| Maciej Katafiasz 2008-02-22, 8:12 am |
| Den Fri, 22 Feb 2008 03:16:07 -0800 skrev Andy Chambers:
> (defmethod refs ((odm odm))
> (with-accessors ((doc doc)) odm
> (?let ((items `(// :|ItemRef|))
> (codelists `(// :|CodeListRef|))
> (groups `(// :|ItemGroupRef|))
> (forms `(// :|FormRef|))
> (events `(// :|StudyEventRef|)))
> (reduce (lambda (l1 l2)
> (union l1 l2))
> (mapcar (lambda (f)
> (funcall f doc)))))))
>
> I've created a macro that makes the ?let form above expand into a labels
> form making items, codelists etc available as functions of one arg. A
> note from the compiler says that it deleted them during macroexpansion,
> presumably because it thinks they're not being used. This means that
> when funcall tries to call them, they don't exist. I can work around
> this but I'm interested in how the compiler decides its ok to delete
> them.
The problem is not with the compiler, but with your code. LABELS creates
local lexical functions, but with the code above, you're FUNCALLing
symbols, which means accessing the (global) dynamic environment. That
doesn't work. You can't access the lexical environment other than by
forms textually enclosed by it. If you want to have function objects to
call later, you want to expand ?LET to a series of LAMBDAs, not LABELs.
Note also that in this case you wouldn't map over '(items codelists
groups forms events) (which is a literal list of symbols), but (list
items codelists groups forms events), as you're interested in the values
they represent.
Cheers,
Maciej
|