Sat 16 Jul 2005 09:18:08 PM UTC, original submission:
In some cases letrec doesn't seem to be working with define-macro.
I haven't been able to find out why sometimes it works and sometimes it doesn't.
Here is a simple example that does not work (using the latest Kawa from CVS):
(define-macro (a-test #!key (args ()))
(letrec ((double (lambda (x) (* x 2))))
`(+ ,@(map double args))))
When I try it:
#|kawa:84|# (a-test)
0
#|kawa:85|# (a-test args: ())
0
#|kawa:86|# (a-test args: (1 2 3))
java.lang.NullPointerException
at atInteractiveLevel$37.lambda1$V(<stdin>:81)
at atInteractiveLevel$37.applyN(<stdin>)
at gnu.expr.ModuleMethod.applyN(ModuleMethod.java:207)
at kawa.lang.Macro.expand(Macro.java:162)
at kawa.lang.Macro.scanForm(Macro.java:193)
at kawa.lang.Translator.scanForm(Translator.java:913)
at gnu.kawa.lispexpr.LispLanguage.parse(LispLanguage.java:59)
at kawa.Shell.run(Shell.java:203)
at kawa.Shell.run(Shell.java:172)
at kawa.Shell.run(Shell.java:159)
at kawa.repl.main(repl.java:673)
<stdin>:86:1: evaluating syntax transformer 'a-test' threw
java.lang.NullPointerException
This behavior seems to be quite random: some define-macro very similar to this one do work, but when I remove an unused (not called anywhere) lambda in the letrec they stop working! Sometimes even removing part of an unused lambda makes it fail. For example:
(define-macro (define-generator name #!key (fields ()) (generators ()))
(letrec ((create-field
(lambda (field)
(if (pair? field)
`(,(first field) init-value: ,(second field))
`(,field init-value: ()))))
(->slot-ref
(lambda (x)
(cond ((null? x) ())
((pair? x)
(cons (->slot-ref (car x)) (->slot-ref (cdr x))))
((symbol? x)
(if (member x fields)
`(slot-ref (this) ',x)
x))
(else x))))
(create-generator
(lambda (generator)
(let ((gname (car generator))
(gbody (cdr generator)))
`((,(string->symbol (string-append "gen-"
(symbol->string gname))))
;(->string-append ,@(map ->slot-ref gbody)))))))
(->string-append ,@gbody))))))
`(define-simple-class ,name ()
,@(map create-field fields)
,@(map create-generator generators))))
The I can do:
(define-generator some-test fields: (a b c))
and it works, but if I remove the unused ->slot-ref lambda then it fails!
|