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

define (resend) (long)



I'm afraid that we have a real disagreement here.

    Much has been said about the pros and cons of the "MIT style" local define,
    and it is clear that a consensus is not possible, so a compromise is in
    order.

I disagree.  Much has been said about MIT's INCREMENTAL DEFINE (which
T also has), but not much has been said at all about (static and local)
INTERNAL DEFINE, which is the only one which appears on the report.
This happened mostly for compatibility with S&ICP, not because the
people from MIT were trying to force it on anybody else (after all, we
cheerfully accepted LETREC, which we did not have before).

    Using a different keyword, such as DEFINE-GLOBAL, to make global definitions
    from lexically nested positions is not acceptible to us.  We have tried to
    live with such arrangements for some months now, and have found them
    intolerable.  

DEFINE-GLOBAL does not make sense for either T or MIT-Scheme.  Neither
really has a global environment distinguished from the rest, thus
there is no environment where these definitions could be made.  The
closest we (MIT) can come to this is making the definition occur in
the innermost environment created by means of MAKE-ENVIRONMENT (the
innermost locale in the case of T), but this seems arbitrary in our
case, to say the least, since all environments are created equal.  In
T this is not the case, so this is a viable option.  We would still do
it if everybody else agreed to it, but we'd rather not, since there
are other options (see below).

    The idea is that it should be
    possible, in any "standard" Scheme that supports some kind of macro package,
    to get *either* style of lexical DEFINE by simply loading the appropriate 
    macro package.  

What about Schemes that do not have macros at all?  Does this mean
that they have to choose one of the two styles, and thus have no
possibility of running the "portable" code written using the other?  I
disagree very strongly with having a feature with two possible
inconsistent semantics.  The only option would be to remove its
optional status, and therefore remove it from the report completely.
Thus nobody would be able to use DEFINE at all in portable code.
Changing semantics now, besides being unacceptable to us, would mean
being purposely incompatible with S&ICP, and gratuitously incompatible
with the previous version of the report.

What is it that you do not like about DEFINE-GLOBAL?  The name is too
long?  Use DEFINE! or DEF instead.  The first was suggested at the meeting
in Brandeis.  Is the problem that it is not even in the report, so you
can't use it because it is not portable?  I'm pretty convinced that we
(MIT) could be convinced of accepting it for the sake of consensus
after a little arm twisting (very little needed).

Note that there is a portable way of achieving the effect of
DEFINE-GLOBAL:

(define foo)	; or (define foo '*)
(define bar)	; or (define bar '*)

(let ((<local-state>))
  (set! foo <whatever you want 1>))
  (set! bar <whatever you want 2>)))

We often do this (although we have and use alternatives) to "export"
values to outer environments, but this gives us more control than
DEFINE-GLOBAL, since we can just place the DEFINEs in the environment
where we want the definitions to occur.

If you do not like the assignments, there is the following
alternative:

(with-exports (foo bar)
  (let ((<local-state>))
    (define-export foo <whatever you want 1>)
    (define-export bar <whatever you want 2>)))

which would just be pretty syntax for the previous choice.  Note that
DEFINE-EXPORT (or DEFINE!, or anything you want to call it) is nothing
special, since it trivially turns into SET!.

Note that the (FOO BAR) list could be made optional, meaning "trap"
all DEFINE-EXPORTs.