[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Martin Gasbichler <gasbichl@xxxxxxxxxxxxxxxxxxxxxxxxxxx> writes:
> Andre van Tonder <andre@xxxxxxxxxxxxxxxxx> writes:
>> I have been wondering about the following technical issue:
>> (let ((x 1))
>> (let-syntax ((m (lambda (form)
>> (let ((x 2))
>> (syntax x)))))
>> There are two possibilities for what this should give, and I am trying
>> to decide which would be the Right Thing. If we regard transformer
>> and runtime varables to live in separate namespaces, the (syntax x)
>> will refer to the outer binding, and we will get the answer 1.
> I don't think this has anything to do with namespaces. The variable
> generated by (syntax x) and the binding introduced by the LET live in
> different phases (or stages). Hence they must not interfere.
The multi-stage programming community also gained some hands-on
experience on how to handle variables that are bound at one level and
used at another one.
If I remember correctly, issues like this are know there as
"cross-stage persistence" and "cross-stage safety". Their pracmatics
usually is that it is specifically allowed (and also condidered usful)
to use variables "at higher levels". Section 2.3 of Taha's thesis will
tell you more ... 
Here is what MetaOCaml has to say about it ...
# let x = 1;;
val x : int = 1
# let m = .< let x = 2 in .<x>. >.;;
val m : ('a, ('b, int) code) code = .<let x_2 = 2 in .<x_2>.>.
# let n = .< .<x>. >. ;;
val n : ('a, ('b, int) code) code = .<.<1>.>.
# .!(.! m);;
- : int = 2
# .!(.! n);;
- : int = 1
( .< e >. is like syntax, .! works like eval)
 Walid Taha, Multi-Stage Programming: Its Theory and Applications
Matthias Neubauer |
Universität Freiburg, Institut für Informatik | tel +49 761 203 8060
Georges-Köhler-Allee 79, 79110 Freiburg i. Br., Germany | fax +49 761 203 8052