Let’s consider the syntactic form:
(internal-body
(begin-for-syntax
(void))
(void))
the internal-body is expanded at phase 1 and evaluated at phase
0; the begin-for-syntax is expanded at phase 2 and evaluated at
phase 1. The code in begin-for-syntax is evaluated when the
code in internal-body is expanded.
Let’s compare two syntactic identifiers captured by syntactic bindings established at different expansion phases:
(internal-body
(define A 1)
(begin-for-syntax
(define B 1)
(pretty-print #'A)
(pretty-print #'B)
(printf "same ribs? ~a\n" (eq-ribs? #'A #'B))
(pretty-print (id-rib*/no-top #'A)))
(void))
-| #<syntactic-identifier expr=A mark*=(src)>
-| #<syntactic-identifier expr=B mark*=(src)>
-| same ribs? #t
-| (#<rib name*=(B A) mark**=((src) (src)) label*=(lab.B lab.A)>)
let’s acknowledge that:
internal-body is expanded: at phase 1.
begin-for-syntax is expanded: at phase 2.
<stx> objects representing the syntactic identifiers ‘(syntax
A)’ and ‘(syntax B)’ have the same marks and rib objects.
rib of internal-body has tuples for both ‘A’ and
‘B’.
so the expansion/evaluation phases are not distinguished in the
<stx> objects and the rib objects. Under Vicare: phase 0
has its LEXENV; phase 1 and the other phases have their LEXENV.
Let’s try to resolve the identifiers using the inferior LEXENV from
the begin-for-syntax:
(internal-body
(define A 1)
(begin-for-syntax
(define B 1)
(pretty-print (id->label #'A))
(pretty-print (id->label #'B))
(pretty-print (id->descriptor #'A))
(pretty-print (id->descriptor #'B)))
(void))
-| lab.A
-| lab.B
-| (lexical . (lab.A . #f))
-| (displaced-lexical . #f)
we see that the labels are retrieved correctly from the rib object;
the descriptor of ‘A’ is retrieved from the inferior LEXENV,
while the label of ‘B’ appears unbound.
To retrieve the descriptor of ‘B’ we do:
(internal-body
(begin-for-syntax
(define B 1)
(begin-for-syntax
(pretty-print (id->label #'B))
(pretty-print (id->descriptor #'B))))
(void))
-| lab.B
-| (lexical . (lab.B . #f))
let’s acknowledge that:
begin-for-syntax is expanded at phase
2 and evaluated at phase 1. If we evaluate
current-inferior-lexenv in the body of the external
begin-for-syntax: we retrieve the LEXENV holding descriptors
for phase 1.
begin-for-syntax is expanded at phase
3 and evaluated at phase 2. If we evaluate
current-inferior-lexenv in the body of the internal
begin-for-syntax: we retrieve the LEXENV holding descriptors
for phase 2.
for this reason: from the internal begin-for-syntax we are able
to retrieve the descriptor of ‘B’.