Fork me on GitHub
#clojure-dev
<
2018-05-14
>
andy.fingerhut03:05:24

When one defines a closure like this:

andy.fingerhut03:05:19

(let [x 5, y 7]
  (defn my-point1 [msg]
    (cond (= msg :get-x) x
          (= msg :get-y) y
          :else nil)))

andy.fingerhut03:05:35

Is there anything in Clojure/Java that makes it straightforward to get at the "code" part vs. the "environment" part of the closure, and examine the pieces of the environment? Can it be done without some kind of decompiling analysis of JVM bytecode?

andy.fingerhut03:05:19

This is more for contemplation than any serious need -- It appears that in Henry Baker's paper defining EGAL, he discusses making EGAL true for two different closures if they have identical function objects, and immutable environments with EGAL contents. This enables EGAL to be true when comparing two "poor man's objects implemented using closures".

andy.fingerhut03:05:53

(My quotation marks, not quoting from Baker's paper)

arrdem05:05:45

no, I think Bronsa and I talked about this at one point and he demonstrated doing it by predicting the Java object field names generated for the closed over state and reflecting to it.

arrdem05:05:20

tajvm does give you a way to look at closed overs

arrdem05:05:39

but only statically with form analysis.

bronsa09:05:13

@andy.fingerhut you can use bits of tools.decompiler to find the closed overs (or even more lightweight bytecode decompilation, but way easier if you get back an AST) + reflection for access if you really want to (note that I’m not suggesting it’s a terribly good idea :))

bronsa10:05:01

once you know what the closed overs are:

user=> (def x (let [a 1] (fn [] a)))
#'user/x
user=> (-> x .getClass (.getDeclaredField "a") (doto (.setAccessible true)) (.get x))
1

bronsa12:05:48

yep on the TRDR project too