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

Getting to the bottome of it


    Date: 14 July 1980 12:05-EDT
    From: George J. Carrette <GJC at MIT-MC>
    Subject: suggested compiler feature.
    (compiler-unwind-protect <form> <protected-forms ...>)
    The semantics of this are simple, during alpha conversion <form>
    is the expression which is the *value*, but the <protected-forms> are
    evaluated even if the alpha conversion of <form> causes some error.

My opinion: Can't hurt anyone, and probably useful to some.  Next case, please.

    Also: atomic-macro-of-the-first-kind.
    Which would have the following actions given that <FOO> has such 
    a property:
    A free <FOO> => <expansion of FOO>
    (setq <FOO> X) => (setf (expansion of FOO> X)
    ((lambda (<FOO>) <FORM>) X) => dissables the macro property of <FOO>
    during the expansion of <FORM>. i.e. LAMBDA is a truely transparent.
    If one wants to (BIND ((<FOO> ...)) ...) then some special BIND
    form must be used. This is of course incompatible with the
    existing semantics of special variables, but perhaps special variables
    should be changed.

    One motivation: for these things in maclisp and lmlisp is an
    implementation of closures with lexically scoped instance

Be careful of letting a giant into the house to swat a fly.  I share the
general skeptcism shown by PSZ and ALAN about this feature, particularly
since it looks an awful lot like the discredited idea of READER symbol
macros.  Almost all good from the latter can be accomplished by the
READER character macro idea -- case in point is QUUX's suggestion a
year or two ago to use things like &#FOO to mean things like an instance
of the variable FOO, but with various declarations available for various
values of the character "#".  (e.g., &%FOO might mean "LOCAL" by 
having LAMBDA-list processing look for things like "(&LOCAL FOO)" whereever 
a variable is permitted).

  But more to the point:  Writing things like
    (DEFUN FOO (x) 
        (DECLARE (ACTOR x VAR1 VAR2 ...))
        (LIST VAR1 VAR2))
is a little more tasteful than
    (DEFUN FOO (x) 
but the right way to accomplish the former is not by admitting any kind
of atomic-macros (as PSZ said, "let hear the case for atomic-macros" -- 
I don't think local closures is that case).  RWK wrote a transformation
package to accomplish this kind of conversion in MACLISP, and both
SCHEME and NIL have a more subtle mechanism for lexically-local variables.
In fact, how soon NIL implements the syntax which permits instance
variables to look like lexically locals depends on whether the lack of
this feature is a bottleneck holding back system development, or just
a minor inconvience.

    Another misdirected line of commentary concerns LET;  whether
one likes the name or not, the destructuring features seem to be
popularly useful.  Recently RMS had an interesting idea about extending
the kind of destructuring specification to be a program rather than
a data-pattern, and a "hairy" atomic-macro scheme will spoil either
one.  E.g;  (RMS-LET ((`(FOO ,x ,y) Z)) ...)        is like
            (RMS-LET (((LIST 'FOO X Y) Z)) ...),    which acts like
            ((LAMBDA (X Y) ...) (CADR Z) (CADDR Z))
or, in the current data-pattern style destructuring
            (LET (( (() X Y) Z ))  ... )            which acts the same way.
Since the atomic-macro idea really isn't the "context-free" idea of a
reader macro, it would open a miasma of expansion/evaluation questions
for these several destructuring contexts.

   Another suggested application of atomic-macros has been for
"symbolic constants" -- perhaps partly alluded to in HIC's comment
    (defatomicmacro MAGIC-VARIABLE ...)
Indeed, SYMBOLIC-CONSTANT is a declaration available in NIL, which
just setq's a variable as a global variable in the interpreter (and
marks it on its property list at toplevel), but which is handily converted 
by the compiler into a constant (rather than a special variable reference).
See MC:NIL;INCUSE >  for a description of how to use the NIL compiler,
and the examples under SYMBOLIC-CONSTANT.  The reason that this
works so well, is that the evaluation context of a SYMBOLIC-CONSTANT
is the same as a variable:
    (DEFUN (X PI Y) ...) and (DEFUN (X) (SETQ PI ...) ...)
		==> detectable errors
    (DEFUN FOO () (//$ PI 2))
		==>  (DEFUN FOO () 1.570795) during compilation