Fork me on GitHub
#clojure
<
2020-10-11
>
Apple04:10:31

Hello, can you explain this macro code?

(defmacro inspect-caller-locals []
  (->> (keys &env)
       (map (fn [k] [`'~k k]))
       (into {})))

(inspect-caller-locals)
;;=>{}

(let [a 1 b 2] (inspect-caller-locals))
;;=> {a 1, b 2}

seancorfield04:10:27

What do you need explained about it? &env is the environment the macro is evaluated in.

seancorfield04:10:48

That's a variant of the local-map macro is the library that my company released a while back https://github.com/worldsingles/commons/blob/master/src/ws/clojure/extensions.clj#L152

Apple04:10:12

consider local a and 1. in [`'~k k], if first element is 'a how does the second get value 1?

seancorfield04:10:30

That's how macros work. Maybe this is a better question for #beginners ? I'm not sure where to start...

seancorfield04:10:36

(I don't mean to be rude but I want to make sure we're started from the appropriate place)

Apple04:10:21

No problem. 🙂

Apple04:10:43

ah ok. captures.

seancorfield04:10:09

Yeah, &env is magic but it's the captured environment by definition.

seancorfield04:10:03

There's &form as well for the source form of the macro. Per https://clojure.org/reference/macros#_special_variables

Apple04:10:37

thank you

valerauko13:10:53

I'm working on wrapping netty's http2 and I got stuck with this bit: https://netty.io/4.1/xref/io/netty/example/http2/helloworld/server/HelloWorldHttp2HandlerBuilder.html I was trying to use proxy to do the same thing (with my own reified handler of course), but I can't seem to get build to work properly.

(proxy [AbstractHttp2ConnectionHandlerBuilder] []
    (build
     ; ([] (proxy-super build))
     ([decoder encoder initial-settings]
      (let [handler (http2-handler decoder encoder initial-settings)]
        (proxy-super frameListener handler)
        handler))))
If I have the zero-arity version then it fails with java.lang.UnsupportedOperationException: build. Without the zero-arity version it fails with clojure.lang.ArityException: Wrong number of args (1) passed to: my.http2/fn--391/fn--392 (which is, I figure, the 3-arity build defined). I don't know if it's because the builds in the abstract superclass are protected or that if I enter the "super zone" with proxy-super from zero-arity it can't find Clojure's 3-arity one? Is there any way I can express this in Clojure or do I have to write raw Java for it?