[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
define -- a modest proposal
In Algol 60 a <program> is a <block> or a <compound expression>, so
Algol 60 has the property you want, that regions are always fully
parenthesized (by BEGIN ... END). I always rationalized Scheme's lack
of "outermost parentheses" by the fact that there would be no point in
having them if you would always have to write them -- they would be
redundant. I imagine that those parentheses are there, just outside the
edge of my files, providing a region for my files' top level bindings to
live in. (The T compiler actually puts the parentheses there, treating
a file boundary as a sort of a macro.)
In MIT Scheme, the syntaxer (a program which translates s-expressions
into Scode, shared by the interpreter and the compiler) "puts" the
parantheses there by building an Scode object called an open-block
around the "top level".
The main unpleasantness I see is the syntactic oddity that a <program>
is a sequence of intermixed <expression>s and <definition>s (it's very
important that <definition>s aren't <expression>s!), whereas a <body> is
a sequence of <definition>s followed by a sequence of <expression>s. I
think I suggested fixing this a while ago (whether to people at MIT or
to RRRS-Authors I don't remember), so that <program>s and <body>s could
have the same syntax and semantics (if internal definitions were
supported at all, that is), but this suggestion was not well received.
This change would make Scheme like Algol 68, which also allows one to
intersperse statements and declarations within a "series" (the region
("range") of a declaration includes previous statements and declarations
in its "series"). The other way to resolve the inconsistency is to be
like Algol 60 and require that all the definitions in a program go at
the top, before any statements (expressions), but somehow I don't think
people would buy that.
I object to mixing internal definitions and expressions. I also
object to mixing top level definitions and expressions although I
admit to being guilty of laziness and occasionally doing the latter.
I never (as far as I can remember) mix them internally, and try to
avoid mixing top level ones also. I would not mind (and might even
applaud) a decision forcing top-level definitions to come first, which
would make the intenal and external cases more symmetric.
[Perhaps we should separate DEFINE into two procedures:
(make-local-variable 'foo)
(set! foo value)
A reasonable idea. In MIT Scheme, (make-local-variable 'foo) is written
(define foo). (Or do you really mean a procedure?) If people like this
feature (which causes the variable to become bound but unassigned, like
in LETREC) I'd be happy to see it go into the report. It is bothersome
that one has to specify an initial value, and this seems as good a way
as any to avoid having to do so.
It is completely unacceptable if it is a procedure (which was my
understanding given the wording and the QUOTE). This would imply
runtime definition (INCREMENTAL DEFINE), rather than static definition
(INTERNAL DEFINE). It also has the problem that if it is a procedure,
it needs the environment where the definition must occur as an
argument. Procedures cannot pick it up at run time.
If it is a special form, the QUOTE is not needed (nor the environment,
which is available at evaluation time), and it could be made static
(as I would expect everyone to want), but then it is exactly internal
DEFINE, so why change names?
I agree that (define foo) is reasonable, although only needed at top
level. I use it often in MIT-Scheme. In particular I use it as an
idiom indicating that the this variable is going to be assigned. I
specify an initial value only when it will not change. It is not
needed elsewhere (in MIT Scheme) because
(let ((foo))
...)
gives me a local binding for FOO which I can then assign.
Note: no one at Indiana replied to Hanson's message, even though it
isn't conclusive. (I don't even think it's true; there could be
multiple "global" environments, and SET!'s could be associated with them
lexically.) Did they assume that SET! would be changed?
JAR, I can't believe YOU have the bad taste to consider this (using
SET! to bind) seriously. One of the features that I dislike the most
from MacLisp and Franz (which is a poor clone of MacLisp), is that
SETQ is used to bind variables. I always use DEFCONST and DEFVAR
before assigning anything. Making this the standard (eliminating
DEFINE) would guarantee that I would never write in the standard
dialect. I'm sure that other people at MIT find this proposal as
distasteful as I do. I don't object to a system (like MacScheme, for
example) where SET! "works", but under no circumstances will I
accept a situation where it is the only way to do it. On such
systems, top-level DEFINE would be a NO-OP, which is fine with me, as
long as it is available.