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

Re: := bug



    Date: Wed, 18 Apr 84 10:25:20 EST
    From: Chris Riesbeck <Riesbeck>
    To: T-Bugs

    Here's a simplified version of the code that leads to the warning
    message that Stan [Letovsky] reported [to T-Bugs]:
    
        (define-macro (:= x y)
           `(set ,(macro-expand x (env-syntax-table (repl-env))) ,y))
    
        (define-macro (foo x) `(car ,x))
    
        (define (baz x) (:= (foo x) 1))
    
    The desired effect of course is that (:= (foo x) 1) should expand
    to (set (car x) 1) before compilation.  The reference to (repl-env)
    is one problem, although the compiled code seemed to work in the
    simplest case.

    Is there any legit way to do this in T?

Perhaps the FOO example is not a good one, since I can just tell you to
use integrable procedures:

    (define-integrable foo
      (object (lambda (x) (car x))
              ((setter self)
               (lambda (x y) (set (car x) y)))))

or even

    (define-integrable foo car)

Problems (with the (object ...) version):

    - It's verbose.
    - TC will integrate calls to FOO, but not calls to (SETTER FOO).  This
      deficiency could be fixed, but hasn't been.
    - It doesn't work in cases where FOO really needs to be syntactic, that
      is, can't be formulated as a procedure.

I have been thinking about the SET / macro interaction problem.  Because
syntax descriptors may be moved freely from one syntax table to another
(i.e. syntax can be exported), (REPL-ENV)'s syntax table, or for that
matter any other syntax table that an ordinary macro expander would
have access to, won't necessarily bear any relation at all to the
one lexically in effect when the code (the expander's argument) is
being analyzed.

T 2.8 has an experimental mechanism whereby one can define macros
like := or SET which want to do syntactic analysis on subforms, without
being subject to the syntax table screwups that the above and similar
definitions of := and SET suffer from.  It allows one to define a
macro which is passed an appropriate syntax table by EVAL, TC, or
whoever else is doing the macro expansion.

This facility won't be released in T 2.8, because I'm not completely
happy with the way it turned out.  But the following should illustrate
its major features:

    (define-syntax :=
      (object nil
              ((syntax-descriptor? self) t)
              ((macro-expander? self) t)
              ((expand-macro-form self form table)
               (do ((previous nil lhs)
                    (lhs (cadr form) (macro-expand lhs table)))
                   ((eq? lhs previous)
                    `(set ,lhs ,(caddr form)))))))

Being unreleased, this is subject to change without notice.  When
it seems stable, SET will be modified to do "the right thing."

Note the symmetry with read macros, which are subject to the same
lexical "environment" problems as macros, and which therefore in (T 2.8)
take a read table argument which can be passed on to READ-OBJECT,
in the same way that the syntax-table argument to the EXPAND-MACRO-FORM
method can be passed on to SYNTAX-TABLE-ENTRY or MACRO-EXPAND.

As suggested, I will try to draw up a summary of stop-gap, experimental,
or internal features which might be of general interest; it will
describe this and the above in a little better detail.