Fork me on GitHub
#sci
<
2022-10-10
>
Lone Ranger18:10:02

Can anyone point to some code that has #C015LCR9MHD AND #C03S1KBA2 / #C03S1L9DN compatible macros? Is there an easy trick to it? For instance, writing macros for #C015LCR9MHD requires writing a ^:sci/macro function, whereas for normal clj/cljs it requires a normal macro written in clj. There's no #?(:sci ...) .cljc reader conditional (as far as I am aware (yet)). So curious if there is a best practice here to ship a library that is sci/#CLX41ASCS / #C03S1KBA2 / #C03S1L9DN compatible?

borkdude18:10:25

@goomba It depends what you want to achieve. In bb and clojure there are no differences between macros

borkdude18:10:46

But since there is no guarantee that a macro exists as a compiled thing in JS once you compiled your CLJS you often have to copy the macro code to a .cljs file if you want to configure it to work with SCI as pre-compiled macros. There is AFAIK no way around this.

borkdude18:10:29

But nbb, which is made with SCI, can run macros from source as well

borkdude18:10:51

So this is the config for promesa, which is a macro-heavy library: https://github.com/babashka/sci.configs/blob/main/src/sci/configs/funcool/promesa.cljs This configured is re-used in #scittle and #nbb and some other projects

Lone Ranger18:10:55

Interesting. Now something like this: https://github.com/babashka/sci.configs/blob/main/src/sci/configs/funcool/promesa.cljs#L143 I'm assuming that will be treated like a regular function in a non sci context?

Lone Ranger18:10:22

ok that makes that easy

Lone Ranger18:10:26

just write all macros like that

borkdude18:10:45

except in JVM clojure

borkdude18:10:55

there they behave like proper macros

borkdude18:10:04

but this is a .cljs file so it's just different there

peterdee20:10:37

I am a little unclear how macros work in sci with cljs. (def do-twice ^:sci/macro (fn [_&form _&env x] (list 'do x x))) That seems okay, but: (sci/eval-string "(do-twice (f))" {:bindings {'do-twice do-twice 'f #(println "hello")}}) I can see how that would work with one use of do-twice in the eval string, but what if there is more than one?

borkdude20:10:17

Do you mean with more than one:

(do-twice (f))
(do-twice (f))
?

peterdee20:10:56

Yes, perhaps with different arguments.

borkdude20:10:12

Why would that be a problem?

peterdee20:10:58

I must be missing something. The :bindings map seems to be referring to a single use of macro.

borkdude20:10:18

No, the bindings map is just a map of symbol to function

borkdude20:10:27

And this function (macro) can be called as many times as you want

peterdee20:10:09

I think maybe it is the 'f in the map that is is throwing me off.

borkdude20:10:36

ok, yeah, f is just a function reference

borkdude20:10:58

Similar to this:

(def f #(println :hello))
(f) (f) (f)

borkdude20:10:20

But now as {'f #(println :hello)}

peterdee20:10:34

Got it. Thanks!