expand-once with a datum argument uses (datum->syntax #f datum) on its
argument, i.e. the resulting syntax-object has no lexical context. That
means in this context if-let is unknown, therefore the expansion must fail.
I think passing in syntax with proper context is the right choice.
To [1]: DrRacket 5.3.4 fails too, other versions not tested. Have you
enabled to run the test submod?
I don't know if its needed, as its use is limited to only very simple
macros or otherwise writing down the expansion becomes pretty complex. But
something to test if macros expansions raise certain errors would be neat.
Tobias
PS: I you really want to expand a datum, set the namespace as in the
sample code for expand
On Mon, 26 Aug 2013 16:45:19 +0200, Greg Hendershott
<[email protected]> wrote:
I recently got a pull request where someone defined a
`check-expansion` form to use with rackunit. Simplified excerpt:
#lang racket/base
(require syntax/parse/define)
(define-simple-macro (if-let [binding:id value:expr] then:expr else:expr)
(let ([binding value])
(if binding then else)))
(module+ test
(require rackunit)
(define (check-expansion input expected-output)
(check-equal? (syntax->datum (expand-once input)) expected-output))
(check-expansion '(if-let [x #t] 0 1) '(let [(x #t)] (if x 0 1))))
Although DrRacket doesn't warn that the the test fails, it fails with
`raco test`:
raco test conditionals.rkt
raco test: (submod "conditionals.rkt" test)
if-let: unbound identifier;
also, no #%app syntax transformer is bound
at: if-let
in: (if-let (x #t) 0 1)
context...:
/Users/greg/src/scheme/collects/rackjure/rackjure/conditionals.rkt:11:2:
check-expansion
/Users/greg/src/scheme/collects/rackjure/rackjure/conditionals.rkt:
[running body]
/Applications/Racket_v5.3.5/collects/compiler/commands/test.rkt:29:10:
for-loop
f8
/Applications/Racket_v5.3.5/collects/compiler/commands/test.rkt:
[running body]
/Applications/Racket_v5.3.5/collects/raco/raco.rkt: [running body]
/Applications/Racket_v5.3.5/collects/raco/main.rkt: [running body]
Without giving it much time or deep thought, I came up with this
version which succeeds in both DrRacket and raco test:
(module+ test
(require rackunit)
(define (check-expansion input expected-output)
(check-equal? (syntax->datum (expand-once input))
(syntax->datum expected-output)))
(check-expansion #'(if-let [x #t] 0 1) #'(let [(x #t)] (if x 0 1))))
In light of that:
[1] Why don't DrRacket and `raco test` both succeed for the first
version?
[2] Is my new version correct?
[3] Could/should rackunit provide something like `check-expansion`?
____________________
Racket Users list:
http://lists.racket-lang.org/users
--
---------------------------------------------------------
Tobias Hammer
DLR / Robotics and Mechatronics Center (RMC)
Muenchner Str. 20, D-82234 Wessling
Tel.: 08153/28-1487
Mail: [email protected]
____________________
Racket Users list:
http://lists.racket-lang.org/users