[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