This post originated from an RSS feed registered with Ruby Buzz
by Jay Fields.
Original Post: Clojure: &env and &form
Feed Title: Jay Fields Thoughts
Feed URL: http://feeds.feedburner.com/jayfields/mjKQ
Feed Description: Blog about Ruby, Agile, Testing and other topics related to software development.
However, if any bindings exist, &env gives you the names of the bindings as the keys of a map.
user=> (let [band "zeppelin" city "london"] (show-env)) {city #<LocalBinding clojure.lang.Compiler$LocalBinding@78ff9053>, band #<LocalBinding clojure.lang.Compiler$LocalBinding@525c7734>}
Okay, now we're getting somewhere. What's a Compiler$LocalBinding? I'm not exactly sure, and I've never bothered to look into it. I've been told that the 'values' from &env may change in the future, so I wouldn't rely on them anyway. Since I can't rely on them, I haven't found the need to look into what they are.
Since the symbols don't have a namespace there didn't seem to be much fun I could do with them; however, you can use the symbols in your macro to print the values, as the following example shows.
'show-form' is a symbol, as expected. Which brings us back to a previous example, shown again below.
user=> (defmacro show-form [a b] (println (map class &form))) #'user/show-form user=> (show-form a 100) (clojure.lang.Symbol clojure.lang.Symbol java.lang.Integer)
Okay, 'a' is also a symbol, unsurprising, but perhaps it's interesting since 'a' doesn't exist anywhere except in our invocation. You can probably do some interesting things here, like allow people to specify enum values and append the enum yourself.
Would you want to use &form instead of just using the arguments (stored in l)? Probably not. This isn't an exercise in what you should do, but it does demonstrate what you could do.