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

macros expanding into definitions



   Date: Wed, 2 Dec 92 14:03:15 -0500
   From: "Mark Friedman" <markf@martigny.ai.mit.edu>
   Reply-To: markf@martigny.ai.mit.edu

   The initial (and I thought primary) motivation for all this was to
   make internal defines consistent with top-level defines. The above
   rules do not do this. For example, the above disallows:

     (define x 0)
     (define (foo)
       (set! x 1)
       (define x 2))
     (foo)
     x

It is not disallowed, it rewrites into

(define x 0)
(define (foo)
  (let ((x))
    (set! x 1)
    (set! x 2)))
(foo)
x

which does not modify the top-level variable X.


   This does not seem consistent to me with the top-level behavior of:

     (define x 0)
     (set! x 1)
     (define x 2)
     x

   I'm not saying that the semantics of internal define should be such
   that the first set of expressions means the same as the second set
   (and obviously neither would any of the people who have heretofor
   spoken on this subject) but I just don't see that the semantics that
   people have presented for internal defines is particularly consistent
   with top-level defines.

I think they are, but you have to understand top-level defines
differently.  Imagine that top-level is wrapped in a LET that binds
all the variables that are defined, and that the defines are just
assignments.  This is consistent with one of the options that the
report mentions.

But this is exactly what people are asking for internal DEFINE!

In other words, the programs that you have shown are not analogous.

     (define x 0)
     (set! x 1)
     (define x 2)
     x


is not the top-level equivalent of

     (define x 0)
     (define (foo)
       (set! x 1)
       (define x 2))
     (foo)
     x

but of

     (define (foo)
       (define x 0)
       (set! x 1)
       (define x 2)
       x)

     (foo)

which behaves the same way.


The analog of


     (define (foo)
       (set! x 1)
       (define x 2))
     (foo)

is

     (set! x 1)
     (define x 2)

which clearly is not legal at top-level either.

Adding extra code at top-level (to previously define FOO, as you had)
is similar to adding extra code _inside_ the lambda expression, not
outside.

In other words, the nice property of the new proposal is that if you
have a program that works, you can wrap it in

(let ()
  <program>
  )

and it still works the same way modulo assignments without definitions
of the names of the standard procedures (CAR, WRITE, etc.), although
if I remember correctly IEEE states that this is an error.