rcf icon indicating copy to clipboard operation
rcf copied to clipboard

Userland macros receives RCF env as &env instead of standard clojure &env value

Open ggeoffrey opened this issue 2 years ago • 6 comments
trafficstars

Reported by @didibus

A minimal repro is welcome

ggeoffrey avatar Jan 29 '23 09:01 ggeoffrey

Minimal repro:


(defmacro my-test-macro [a]
  (prn &env)
  `[~a])

;; No RCF
(let [a 1]
  (my-test-macro a))
;; => {a #object[clojure.lang.Compiler$LocalBinding 0x58d44b9f "clojure.lang.Compiler$LocalBinding@58d44b9f"]}
;; => [1]

;; From inside RCF
(tests
  (let [a 1]
    (my-test-macro a)) := [1])
;; => {a {:op :binding, :name a, :init {:op :const, :env {:locals {}, :namespaces {}, :ns hyperfiddle.rcf-test}, :form 1}, :form a, :local :let, :children [:init]}}
;; => ✅

ggeoffrey avatar Jan 29 '23 10:01 ggeoffrey

It is not clear to me if one can construct a valid instances of LocalBinding. If it is possible then maybe RCF could reconstruct the clojure &env from its own environment.

I tried to produce an instance of LocalBinding, but got an IllegalAccessError failed to access class clojure.lang.Compiler$Expr which has package level visibility.

ggeoffrey avatar Jan 29 '23 10:01 ggeoffrey

  • can we monkey-patch the Expr class visibility from userland
  • can we reify something duck typed that matches most userland calls?
  • what is cljs impact

dustingetz avatar Jan 29 '23 17:01 dustingetz

I'm using &env to get all current locals, their primitive type, and their attached metadata.

In my macro, I do the following:

(map (fn[[_k v]] (meta (.-sym v))) &env)

To get all local symbols from &env.

I also do this:

(try
    (when-some [java-class (.getJavaClass expr-ast)]
      {:class java-class
       :primitive? (.isPrimitive java-class)})
    (catch Exception _e))

On each LocalBinding returned from &env to get the type of the local and it is a primitive or not.

I believe this is the type for what &env returns: https://www.javadoc.io/doc/org.clojure/clojure/1.11.1/clojure/lang/Compiler.LocalBinding.html

didibus avatar Jan 30 '23 02:01 didibus

So I saw that riddley macro-expander I think seems to create LocalBindings as it macro-expands: https://github.com/ztellman/riddley/blob/master/src/riddley/compiler.clj#L55 and https://github.com/ztellman/riddley/blob/master/src/riddley/Util.java#L8 which you could also do in Clojure I guess.

It does seem you have to somewhat update the Compiler about it, or the creation of the LocalBinding will throw an IllegalAccessError or something of that sort.

Might be a lead?

didibus avatar Feb 01 '23 23:02 didibus