[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

sentiments



    Date: Sun, 1 Jun 86 16:21:30 est
    From: Kent Dybvig <dyb%indiana.csnet at CSNET-RELAY.ARPA>
        
    That begin must be a core special form results from the fact that in
    the report, (begin (define ...) ...) must not open up a new scope;
    i.e., (begin x y ...) must not be defined as ((lambda () x y ...)),
    or the more traditional form ((lambda (t) (begin y ...)) x) where t
    does not appear free in (begin y ...).  I think of this as the "usual
    expansion".

I get the feeling you haven't read the report.  According to NEITHER
Will's RRRS, NOR the draft I sent out, is (begin (define ...) ...) a
syntactically valid expression!  Look again at the BNF and at the text.
The usual expansion ((lambda (t) (begin y ...)) x) works perfectly well
since <expression> can't produce anything of the form (define ...),
<definition>s can only occur in <program>'s and <body>'s, and the syntax
of <sequence>s is (begin <expression>+), not (begin <body>).  The RRRS
says that definitions are expressions, which isn't exactly wrong, but it
seemed a little misleading to me, since they aren't legitimate in all
places where expressions are supposed to be.  (Again, only the details
of the description have changed, not the language described!)

Maybe you're misled by the statement in the RRRS that "(lambda (var1 ...)
expr1 expr2 ...) is equivalent to (lambda (var1 ...) (begin expr1 expr2
...))".  This can be seen to be technically true if either (a) you take
this statement to be only about the essential subset or (b) definitions
aren't expressions (so that the statement wouldn't apply in the case of
(begin (define ...) ...)).

The BNF in the draft makes the error of classifying (begin ...) as
primitive instead of derived.  This is an error.  (At one point I too
was confused and thought that begin had to be primitive, but Sussman
straightened me out).  Sorry if this bug confused you.  I will fix it.

    I wouldn't brag about this!  Having already expanded Scheme from
    expressions and functions to statements and procedures, we are now
    adding declarations.  What happened to simplicity?

"Now"?  The fact that definitions weren't valid in copntexts other than
top level and the beginnings of "bodies" was agreed on Brandeis and
hasn't been challenged until now.

Introducing the term "statement" to mean an expression whose value is
thrown away seems harmless to me; I was inspired to do this by the
abstract syntax that Will sent me for the denotational semantics (which
sets Com = Exp).  Using "<statement>* <expression>" instead of
"<expression>+" also gives a rationale for requiring at least one
expression in LAMBDA, BEGIN, etc.  If there's general sentiment that
this is a bad idea, I'll flush it, but I thought it was reasonable.

We all know why we use "procedure" instead of "function".  I don't
understand how this makes the language more complex.

Your question about simplicity is pure propaganda, so I won't answer it
beyond the above remarks.
        
        As has been explained innumerable times, there is no way to avoid this
        and have a language which is at all coherent with T and MIT Scheme.
        Note that in all programming languages of the Algol/Pascal/C variety it
        is an error to assign to an undeclared variable.  That MIT Scheme and T
        (and thus RRRS Scheme) also have this property is not coincidence.

    Algol, Pascal, and C are not (typically) interactive languages, nor
    do they have such nice features as first-class functions that allow
    one to form modules of functions sharing local state/help functions.
    I think that it would be possible in any system to have a notion of
    a "top-level" lexical environment which implicitly contains bindings
    for all things not bound elsewhere.  This could be a per-user or
    per-module thing; it need not be the outermost lexical environment.

I repeat: "there is no way to avoid [requiring that variables be bound
before they're assigned] and have a language which is at all coherent
with T and MIT Scheme."  I never said it would be impossible to
implement.  And interactiveness has nothing to do with it.
        
    ... I don't either, but I think what he means is that only a handful of
    experienced implementors will understand how a full Scheme system is
    implemented.
    ... Dan was referring, I'm sure, to the core of the language, which he
    feels must now not only include lambda, set!, quote, if, identifiers,
    and applications but also begin and define, not to mention the added
    complexity of lambda.

Do I need to mail out a complete evaluator in order to drive the point
home?
        
    I think you misunderstood his point completely here.  He was merely
    wondering of what use internal define is if you have letrec, and noted
    that you can get letrec trivially with lambda and set!, if you like.

No one ever said internal defines were linguistically necessary.  They
are obviously redundant.  They are there because it's very important to
be compatible with something so central to S&ICP.  Like I say, talk to
Sussman and Abelson if you dispute this.

    I agree in principle with this idea.  It makes sense that define at
    top level should be treated specially, and nested definitions such as 
    those given throughout S&ICP are quite handy and encourage modularity
    in a nice way.  Since this treatment would not affect lambda or let,
    it would be easy to understand and easy to implement.

How does its not affecting lambda or let have anything to do with how
easy it is to implement?  Implementing internal defines involves one
trivial loop, and it doesn't matter whether you put this loop in the
code for lambda or define, although it DOES matter if you have to invoke
it two places.

    I would agree
    to using something totally different for definitions or perhaps use
    the define/set! combinations for our interpretation of internal define
    if we all agreed that define were only to be used at top level, with
    the nested syntax.  I would even agree to making top-level, nested
    define a required feature, and to requiring that define not be used
    anywhere else.

I don't understand this paragraph at all.  Note that no one has ever
wanted internal defines to be essential in any context.

    ... We have an exceptionally tight community of people
    working on/with Scheme and it is not good for us to put each other at
    odds by publishing a feature that some of us strongly dislike in its
    current form.

Like I say, talk to Abelson and Sussman.  I think a lot has and can be
done to make internal definitions minimally ugly and intrusive.  It is
not good to confuse many innocent bystanders and put your community at
odds with MIT's by permitting an incompatible meaning for DEFINE.

Jonathan.