On Thu, Jun 25, 2009 at 10:54 PM, Jurjen<jurjen.hait...@gmail.com> wrote:
>
> Essentially my new version of defn is a basic wrapper around defn:
> (defmacro mkfn [nm args func]
>  (list 'defn nm {:source (str "(mkfn " nm " " args " " func ")")}
> args func))
>
> so when you do (mkfn test1 [a b] (+ a b)) you get out a function test1
> with a metadata :source tag (meta (var test1))
> {:ns #<Namespace user>, :name test1, :file "NO_SOURCE_PATH", :line
> 439, :arglists ([a b]), :tag "sometag", :source "(mkfn test1 [a b] (+
> a b))"}
>
> I tried to override the print-dup for clojure.lang.Fn to check for
> the :source meta-data tag, but I keep getting NullPointerExceptions.
> Anyone got any ideas? Am I missing something obvious?

It may not be obvious, but your mkfn macro is setting the
metadata of the Var that contains the fn, not the fn itself.
This is why to see the meta you had to say
(meta (var test1)) intead of just (meta test1).

This also means that if you do (pr-str test1), pr-str has no
way to get to the metadata.  When this expression is
evaluated, the symbol 'test1' is resolved to the Var, then
the Var is deref'ed to the fn, and finally that fn is passed
to pr-str.  There's no pointer from the fn back to the Var,
which makes sense if you think about anonymous fns, multiple
Vars pointing to the same fn, multiple threads having
different fns for the same Var, etc.

I can only think of two options for you.  By far the easiest
would be to print the Var rather than the fn:

    (binding [*print-meta* true] (pr-str (var map)))
or
    (binding [*print-meta* true] (pr-str #'map))

The other option would be to attach your metadata to the fn
itself.  This is a bit tricky because fns cannot be
duplicated in the way that would be necessary to immutably
"change" their metadata.  And although you can attach
metadata to a fn instance (a.k.a. closure) when it is
created, there's no syntax for this.  However, it is
possible to do with careful use of 'proxy'.

...but even once you've captured the code used to define
a fn, I'm not sure how much good it's going to do you.  That
metadata won't include anything about the lexical
environment in which the fn was defined, the values of any
closed-over locals, etc.

--Chouser

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to