what does the value part of &env map automatically passed to all macros contain?

110 views
Skip to first unread message

Sunil S Nandihalli

unread,
Dec 3, 2010, 10:04:25 PM12/3/10
to clo...@googlegroups.com
Hello everybody,
I really like the &env. It has saved a lot of tedious work a couple of times .. but I have only found use for the keys of the map that gets passed like in the following example.

 (defmacro display-local-bindings []
  `(do ~@(map (fn [x#] (list 'println  [`'~x# x#])) (keys &env))))

(let [x 10
        y 20]
(display-local-bindings))

would print 

[x 10]
[y 20]

I don't understand what the val part of the map contains? I have failed at attempts to figuring it out.. Can somebody tell me what the val part contains and how one could use it?

Thanks,
Sunil.

Alex Osborne

unread,
Dec 3, 2010, 10:59:43 PM12/3/10
to clo...@googlegroups.com
Sunil S Nandihalli <sunil.na...@gmail.com> writes:

> I really like the &env. It has saved a lot of tedious work a couple of
> times .. but I have only found use for the keys of the map that gets
> passed like in the following example.

> I don't understand what the val part of the map contains? I have


> failed at attempts to figuring it out.. Can somebody tell me what the
> val part contains and how one could use it?

It contains a LocalBindings object which the compiler uses internally to
keep track of a local binding. Note that unlike the keys, the values of
&env are not a stable API, they're implementation details and may well
change. When he added &env I think Rich said he'd look at giving the
values of &env a proper API as part of the future Clojure in Clojure
compiler.

But you can poke at them like this:

(defmacro foo []
(def lb (first (vals &env))))

(let [a (+ 1 3)]
(foo))

(.sym lb)
;; a

(.idx lb)
;; 1

(.name lb)
;; "a"

(.isArg lb)
;; false

(.canBeCleared lb)
;; true

(.init lb)
;; #<StaticMethodExpr
;; clojure.lang.Compiler$StaticMethodExpr@1a9d267d>

(.args (.init lb))
;; [#<ConstantExpr clojure.lang.Compiler$ConstantExpr@51d2bb9f>
;; #<ConstantExpr clojure.lang.Compiler$ConstantExpr@621bedb0>]


If you're using Emacs + SLIME, the SLIME inspector is quite useful for
exploring unknown values. After evaling the first two forms above, put
the cursor over "lb" and press C-c I (note that's shift + i). You'll
get something like this:

clojure.lang.Compiler$LocalBinding@25de152f
--------------------
Type: class clojure.lang.Compiler$LocalBinding
Value: clojure.lang.Compiler$LocalBinding@25de152f
---
Fields:
sym: a
tag:
init: clojure.lang.Compiler$StaticMethodExpr@1a9d267d
idx: 1
name: a
isArg: false
clearPathRoot: clojure.lang.Compiler$PathNode@1740d415
canBeCleared: true

You can then press enter on any of the field values or class names to
get more detail about them.

Sunil S Nandihalli

unread,
Dec 3, 2010, 11:46:41 PM12/3/10
to clo...@googlegroups.com
Thanks Alex. I asked because I thought it might be part of stable API. Thanks for your tip on slime (I do use slime) also. I will wait for it to become part of stable api.
Sunil.

--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@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+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Sunil S Nandihalli

unread,
Dec 4, 2010, 12:34:10 AM12/4/10
to clo...@googlegroups.com
I feel they could add a flag to indicate if it was obtained via gensym or not.. I would have liked to have it in the past. It can help in writing debug macros .. may be give better debug messages etc.
Sunil

On Sat, Dec 4, 2010 at 9:29 AM, Alex Osborne <a...@meshy.org> wrote:
Reply all
Reply to author
Forward
0 new messages