Thanks, using syntax->list solved the problem. On Apr 17, 2014, at 12:22 AM, Carl Eastlund <carl.eastl...@gmail.com> wrote:
> Syntax objects are a rather complex data type, especially where pairs and > lists are involved. Essentially, a syntax object containing a list can be > broken up with extra syntax nodes at all, some, or none of its intermediate > conses, depending on how it is constructed. For example, if you just write > #'(1 2 3), there will be one syntax node at the top level and none anywhere > else. If you write #'(1 . (2 . (3 . ()))) instead, you get syntax nodes at > each step along the way. The syntax objects differ, even though '(1 2 3) and > '(1 . (2 . (3 . ()))) produce the same value. > > So what happened in your program? Well, when you define f2 using > proc-with-stx, the define-syntax-rule from proc-with-stx substitutes (lambda > (x) #f) in for expr, and your syntax object is therefore [essentially] > #'(lambda (x) #f). It's a straightforward list, one syntax node at the top > level. > > When you define f using lambda-with-stx, however, the define-syntax-rule for > lambda-with-stx has to substitute (x) for args and #f for body ... in (lambda > args body ...). I'm guessing the result comes out something like (lambda . > ((x) . (#f . ()))); the process may just automatically put a syntax node at > each cons. Then proc-with-stx substitutes that for expr, and you get > [essentially] #'(lambda . ((x) . (#f . ()))). > > Basically, you can't rely on where syntax-e will split up a list into syntax > objects unless you constructed it yourself. If you want predictable results, > use syntax->list or syntax->datum. > > Carl Eastlund > > > On Wed, Apr 16, 2014 at 10:33 PM, Alexander D. Knauth <alexan...@knauth.org> > wrote: > 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? > > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > >
____________________ Racket Users list: http://lists.racket-lang.org/users