[racket] Sometimes (syntax-e #<syntax (lambda (x) #f)>) produces a non-list pair

From: Alexander D. Knauth (alexander at knauth.org)
Date: Wed Apr 16 22:33:07 EDT 2014

Basically, I have a macro, called proc-with-stx, that captures an expression and stores it in a syntax object, and I have another macro, called lambda-with-stx, that expands to (proc-with-stx (lambda …)).  
When I use (proc-with-stx (lambda (x) #f), then the syntax-e of the syntax-object is a list, but when I use (lambda-with-stx (x) #f), which should expand to the same thing, the syntax-e of the syntax-object is a non-list pair:

#lang racket

(module+ test
  (require rackunit))

(struct proc+stx (proc stx)
  #:property prop:procedure (struct-field-index proc))

(define-syntax-rule (proc-with-stx expr)
  (proc+stx expr #'expr))

(define-syntax-rule (lambda-with-stx args body ...)
  (proc-with-stx (lambda args body ...)))

(module+ test
  (define f
    (lambda-with-stx (x) #f))
  (define f2                               ; f should expand to f2
    (proc-with-stx (lambda (x) #f)))
  (define f-stx  (proc+stx-stx f))
  (define f2-stx (proc+stx-stx f2))
  ;; tests for f:
  (check-true (procedure? f))
  (check-equal? (f 1) #f)
  (check-pred list? (syntax-e f-stx)) ; this test fails, produces '(#<syntax lambda> #<syntax (x)> . #<syntax (#f)>) instead
  ;; same tests for f2
  (check-true (procedure? f2))
  (check-equal? (f2 1) #f)
  (check-pred list? (syntax-e f2-stx)) ; this test passes, produces '(#<syntax lambda> #<syntax (x)> #<syntax #f>)

Why doesn't (syntax-e f-stx) produce a list like (syntax-e f2stx) does?

Posted on the users mailing list.