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

Interaction between syntax-tables and environments



    Date: Mon, 23 Dec 85 16:45:06 EST
    From: Jim Meehan <csi!meehan%UUCP at YALE.ARPA>

    (DEFINE-SYNTAX (KAR X) `(CAR ,X))

    (LET ((CAR CDR)) (KAR '(1 2 3))) => (2 3)

    The person who defined KAR probably wanted the expanded code to use the
    standard CAR, but because macros manipulate S-expressions and not values,
    there's nothing to prevent the environment from thwarting his intentions.
    Of course, you could write

    (DEFINE-SYNTAX (KAR X)
      `((*VALUE *STANDARD-ENV* 'CAR) ,X))

    but then you lose in efficiency, open-compilability, etc.  

You don't lose if the compiler is reasonable.  I think this is almost
the right thing.  I think future versions of the compiler will be able
to compile this correctly.

Of course, it just begs the question, since the user could have done
(LET ((*VALUE LIST)) (KAR 3)), or bound *STANDARD-ENV*.  Ultimately I
think a new special form will have to be added to the language (absolute
reference CAN be made to special forms); that's why *VALUE has a * in
its name, just in case we decided to add a VALUE special form.  (MIT
Scheme has such a special form; it's called ACCESS, but takes its
arguments in the opposite order.)

							       One way around
    this is to extend the rules for evaluation to permit the CAR of a form
    to be a procedure (as opposed to a symbol that is bound to a procedure).
    (A similar thing is currently implemented for special forms.)  If this
    were implemented, we could write

    (DEFINE-SYNTAX (KAR X) `(,CAR ,X))

You don't need to extend the syntax of combinations, you just need to extend
the syntax of QUOTE:

(DEFINE-SYNTAX (KAR X) `(',CAR ,X))

    or, being very careful,

    (DEFINE-SYNTAX (KAR X)
      `(,(*VALUE *STANDARD-ENV* 'CAR) ,X))

There's no reason to do this; the macro expander knows perfectly what
its own environment is (weel... on second thought... but let's not get
into that); there's no problem with ITS binding of CAR.

    and avoid the problem.  This introduces other problems (e.g., external
    representation, compiler), but it might be workable.

This could be made to work for system-supplied procedures, but making
it work for general user procedures would be very difficult; in the
general case the system would have to invoke FTP or the international
telephone or mail systems.

One idea I'm considering is something resembling Internet "domain
naming," which is basically a programming convention which allows one to
name any object on any machine.  If I can work the kinks out and if
someone bothers to implement it, it may become part of some future
release of T, and ultimately T may even be able to invoke FTP
automatically.

Your points are correct; I hope that this further illustrates to people
just how intractible macros are.  Don't use them if you can avoid it!
The above is a terrible example; you could have written

(define-integrable (kar x) (car x))

or

(define-integrable kar car)

without sacrificing a nanosecond of efficiency (this is one of the great
features of T compilers).  There are occasional cases where macros are
desirable (I generally only use them for top-level forms), but this is
not one.