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

semantics of ?=



We had quite some discussion on IRC channel #dylan about what the 
intensional name capture by ?= should accomplish.

My idea is: ?=name in a macro expansion behaves exactly the same _as_if_ 
the users code had \name in that position.

To make it more concrete:

define macro it-capturer
   { it-capturer() } => { it }
end;


define macro it-binder
   { it-binder(?:expression, ?:body) }
   => { let it = ? expression; ?body }
end;


// this will never work:

begin
   let it = 5;
   format-out("captured: %d\n", it-capturer());
end;

because the name spelled as "it" inside the expansion of \it-capturer is 
a hygienic name, that has a using, but not a defining occurrence.

hand-expanding yields:

begin
   let it = 5;
   format-out("captured: %d\n", it#1#it-capturer);
end;

here it#1#it-capturer is a hygienic name that was invented for the first 
expansion of \it-capturer and is spelled "it" there.

This will work:

define macro it-capturer2
   { it-capturer2() } => { ?=it }
end;

begin
   let it = 5;
   format-out("captured: %d\n", it-capturer2());
end;

because it expands to the name \it:

begin
   let it = 5;
   format-out("captured: %d\n", it);
end;

OK, lets get a bit more involved.

begin
   let it = 5;
   format-out("captured: %d\n", it-binder(42, it-capturer2()));
end;

Will work, and print "captured: 5".

Easy when hand-expanding:

begin
   let it = 5;
   format-out("captured: %d\n", begin let it#1#it-binder = 42; it end);
end;

The same expansion arises when writing

begin
   let it = 5;
   format-out("captured: %d\n", it-binder(42, it));
end;

Now, lets define a new it-binder2:

define macro it-binder2
   { it-binder2(?:expression, ?:body) }
   => { let ?=it = ? expression; ?body }
end;

This time the defining occurrence of the \it is as if the user had 
written it there.

begin
   let it = 5;
   format-out("captured: %d\n", it-binder2(42, it));
end;

We get "captured: 42".

This is the manual expansion:

begin
   let it = 5;
   format-out("captured: %d\n", begin let it = 42; it end);
end;

The same, using it-capturer2:

begin
   let it = 5;
   format-out("captured: %d\n", it-binder2(42, it-capturer2()));
end;

------------------------------------------------------------

Now, Bruce hoped to be able to refer to a macro-mentioned hygienic name 
by using ?=.

Something like this:

begin
   let it = 5;
   format-out("captured: %d\n", it-binder(42, it-capturer2()));
end;

My opinion is that this should _never_ result in "captured: 42".

The reason is that there are two categories of names, hygienic and 
unhygienic ones. The former come from macro expansions (unless used 
with ?=) and the latter from users source code and macro expansions 
with ?=.

We currently do not have a capture notion "whatever is spelled 
identically". One could invent such a syntax (e.g. ?~ as Andreas 
suggested) but it would be very hard to assign a reasonable semantics to 
it. I am thinking of "let ?~it = ..." here. Would a hygienic "it" 
capture this beast? Or an unhygienic one?

So I would still advise Bruce to stick to the name passing macro 
definitions, even if they become bloated in the presence of the seven 
variables of the iteration protocol.

Now I'll stop and let others build on this (and point out my mistakes :-)


We brought the discussion here, so FO folks can also chime in. We would 
welcome that very much.


	Gabor