Why is with-syntax required in this example?

Asked by leppie on 2008-09-08

Hi

I am wondering why the 1st with-syntax is needed in the follow example.

(import (rnrs))

(define-syntax foo
  (lambda (x)
    (define (bar e)
      (lambda (x)
        (with-syntax ((e e)) ; <--- this one!
          (syntax-case x ()
            [(x) #'e]))))
    (syntax-case x ()
      [(_ e r ...)
        (with-syntax (((r ...) (map (bar #'e) #'(r ...))))
          #'(list r ...))])))

(define x 'hi)

(display (foo x (a) (b)))
(newline)

Removing the with-syntax, the snippet fails with:
&who: e
&message: "identifier out of context"
&syntax: e
&source-information: "c:\\Program Files\\xacc.ide\\with-syn.ss" "(9,18) - (9,21)"
&trace: #<syntax e [(9,18) - (9,21) of c:\Program Files\xacc.ide\with-syn.ss]>
&trace: #<syntax (foo x (a) (b)) [(17,10) - (17,25) of c:\Program Files\xacc.ide\with-syn.ss]>

Any clarification will be helpful. Maybe a bug?

Cheers

leppie

Question information

Language:
English Edit question
Status:
Solved
For:
Ikarus Scheme Edit question
Assignee:
No assignee Edit question
Solved by:
Abdulaziz Ghuloum
Solved:
2008-09-09
Last query:
2008-09-09
Last reply:
2008-09-09
leppie (leppie) said : #1

Ok, I think I see what happens, I am just not sure why :)

The following I can understand:

(define-syntax foo
  (lambda (x)
    (define (bar e)
      (lambda (x)
        (syntax-case x ()
          [(x) e])))
    (syntax-case x ()
      [(_ e r ...)
        (with-syntax (((r ...) (map (bar #'e) #'(r ...))))
          #'(list r ...))])))

Best Abdulaziz Ghuloum (aghuloum) said : #2

When you say (syntax e), there are two possibilities:
1. "e" is a pattern variable, and therefore its value will be substituted in the syntax template, or
2. "e" is not a pattern variable, and the identifier e will be used in the syntax template.

A simple example is as follows:

> (let ([e 12]) #'e) ;;; e is not a pattern variable
#<syntax e>
> (syntax-case 12 () [e #'e]) ;;; e is a pattern variable whose value is 12
12
> (with-syntax ([e 12]) #'e) ;;; same
12
> (let ([e 12]) (with-syntax ([e e]) #'e)) ;;; outer e is a normal variable, inner e is a pattern variable
12

So, with-syntax is a binding form: it binds values to pattern variables that have special meaning within (syntax _) forms.
Does this make sense?

leppie (leppie) said : #3

Thanks, I understand a bit better. I will play with some variations.

Cheers

leppie

leppie (leppie) said : #4

Thanks Abdulaziz Ghuloum, that solved my question.

leppie (leppie) said : #5

Just to clarify my error.

I was confusing a pattern variable with a syntax type.