Fork me on GitHub
#sci
<
2021-05-31
>
Markus Agwin13:05:21

In attempting to create a Scittle plugin, (sci/copy-var some-macro sci-created-ns) (where some-macro is a symbol created by :refer-macros) results in an "Unable to resolve var" error. Just to be sure: it's not possible to expose macros of an arbitrary cljs-library in a Scittle plugin, right?

borkdude13:05:19

To be sure, just re-implement the macro in terms in CLJS as a normal function

borkdude13:05:39

and then use :sci/macro as metadata on that function to expose it to sci

borkdude13:05:20

(defn my-macro [_form _env x y & zs] `(do ...))
(with-meta my-macro {:sci/macro true})

🙏 3
Markus Agwin08:06:31

I cannot get this to work:

(ns scittle.makro-plugin
  (:require
   [sci.core :as sci]
   [scittle.core :as scittle]))

(defn add-low-fn [_env _form x y & zs] `(str "__" ~x ~y ~zs))
(def add-low-makro (with-meta add-low-fn {:sci/macro true}))

(def rns (sci/create-ns 'makro-plugin.core nil))

(def makro-plugin-namespace
  {'add-low-fn (sci/copy-var add-low-fn rns)
   'add-low-makro (sci/copy-var add-low-makro rns)})

(scittle/register-plugin!
  ::makro-plugin
  {:namespaces {'makro-plugin.core makro-plugin-namespace}})
add-low-makro behaves the same way as add-low-fn . Do I need to add something in order to SCI recognise a macro?

borkdude08:06:17

you should not use copy-var with add-low-makro

borkdude08:06:24

as it only copies the var metadata to the sci var

borkdude08:06:49

@U77MR6ETD So:

scittle.makro-plugin=> (defn add-low-fn [_env _form x y & zs] `(str "__" ~x ~y ~@zs))
#'scittle.makro-plugin/add-low-fn
scittle.makro-plugin=> (sci/eval-string "(add-low-makro 1 2 3 4)" {:bindings {'add-low-makro (with-meta add-low-fn {:sci/macro true})}})
"__1234"

borkdude08:06:17

This also works:

scittle.makro-plugin=> (defn ^:macro  add-low-fn [_env _form x y & zs] `(str "__" ~x ~y ~@zs))
#'scittle.makro-plugin/add-low-fn
scittle.makro-plugin=> (sci/eval-string "(add-low-makro 1 2 3 4)" {:bindings {'add-low-makro (sci/copy-var add-low-fn rns)}})
"__1234"

Markus Agwin09:06:55

Great! For the record, this works now:

(ns scittle.makro-plugin
  (:require
   [sci.core :as sci]
   [scittle.core :as scittle]))

(defn add-low-fn [_env _form x y] `(str "_" ~x ~y))
(defn ^:macro add-low-makro [_env _form x y] (add-low-fn _env _form x y))

(def rns (sci/create-ns 'makro-plugin.core nil))

(def makro-plugin-namespace
  {'add-low-fn (sci/copy-var add-low-fn rns)
   'add-low-makro (sci/copy-var add-low-makro rns)})

(scittle/register-plugin!
  ::makro-plugin
  {:namespaces {'makro-plugin.core makro-plugin-namespace}})

Markus Agwin13:06:42

@U04V15CAJ is env meant to be empty when I print it via

(defn add-low-fn [form env x y] 
`(str "_ form: " ~(str form) " env: " ~(str env) ~x ~y))
? (at least I got the form<->env order right this time)

borkdude13:06:52

it depends where you call it from

borkdude13:06:00

it contains the locals

borkdude13:06:26

these arguments are called &form and &env in normal Clojure macros

Markus Agwin14:06:05

But in this specific Scittle example I cannot improve my code to (for example) have the name of some namespace appear via (:name (:ns env)), right?

Markus Agwin14:06:44

that helps, thank you!