Fork me on GitHub
#babashka-sci-dev
<
2022-03-06
>
Crispin08:03:40

can sci take some code, expand all the macros in it, but not "run" it? As in only the evaluations needed to expand the macros are done, and then you have access to the AST before execution...

Crispin08:03:57

or is the macroexpansion not a seperate step, and is tied up with evaluation?

borkdude10:03:51

@retrogradeorbit I guess you could do something like this:

user=> (sci/eval-string "(defmacro dude [x] `[~x ~x]) (clojure.walk/macroexpand-all '(dude 1))")
[1 1]

borkdude10:03:06

What problem are you trying to solve?

Crispin13:03:35

Im hatching a massive hack

Crispin14:03:13

not even sure it will work...

Crispin14:03:16

Ive been experimenting with different ways to generate wasm

Crispin14:03:53

but I don't like them

Crispin14:03:17

last time I used wasm I used C++ and C++ is never enjoyable.

borkdude15:03:05

@retrogradeorbit What problem are you trying to solve?

borkdude15:03:16

(I'll just keep asking the question ;))

borkdude15:03:16

Oh I see now, a C generator

borkdude15:03:28

Sorry, I didn't read the title so I couldn't tell if this was C or JavaScript

borkdude15:03:11

It reminds me of this: https://github.com/dundalek/liz It parses Clojure (using edamame) and generates zig code

👀 1
Crispin15:03:06

Last time I was making wasm I was using C++ and then I got to the point where I wanted to implement something like this

Crispin15:03:55

a moving 3x3 window over a 2D array, outputing a central value based on the pattern

Crispin15:03:13

and this is quite straight forwards with pattern matching

Crispin15:03:18

but C++ doesnt have that

Crispin15:03:26

and it quickly descended into hell

Crispin15:03:58

and my C++ friend when I asked him just said, "nah you're stuffed. write it all out by hand"

Crispin15:03:18

my kingdom for a proper macro system

Crispin15:03:41

If I can generate C, I can implement a pattern matcher as a macro

Crispin15:03:06

I will check out this liz... see how its doing its magic

borkdude15:03:02

why not generate the code once using a macro or whatever templating thing and then inline that code

borkdude15:03:18

seems like a lower hanging fruit than implementing a Clojure -> C transpiler

Crispin15:03:06

yeah so thats an option... but then it gets unwieldy

Crispin15:03:24

as you have half C++ files, half generated snippets.. that get mashed together

Crispin15:03:52

implementing a Clojure -> C transpiler does sound like madness, yes

borkdude15:03:15

this is effectively what liz is, transpiling to C shouldn't be much harder perhaps

Crispin15:03:17

would it even be possible for have core.match emit the C code

Crispin15:03:30

yeah, the aim is to not implement a lisp in C

Crispin15:03:52

just to write C using s-exp

Crispin15:03:02

and then, some macros over the top

borkdude15:03:15

that is effectively what liz is ;)

Crispin15:03:26

Im gonna read some liz source

Crispin15:03:37

you know, its not crazy huge

Crispin15:03:47

its quite small

Crispin15:03:05

you know what, I should try using liz

Crispin15:03:17

see what its like to use liz to generate wasm

borkdude15:03:14

yeah, let me know how that goes :)

borkdude15:03:21

Maybe using Common Lisp for this would also make sense, given that you can get quite close performance to C using it and there may be WASM bindings for it

borkdude15:03:33

but generating C would be most optimal I guess

Crispin15:03:30

one approach is to build up wasm from the ground up. wasm has a format wast that is s-expr. It's spec is very lispy already. You would deal directly in the wasm types and map clj straight to wasm ast. This is somewhat like helins/wasm.cljc does

Crispin15:03:46

the other is to transpile to another supported lang, and then compile that down to wasm

Crispin15:03:24

the first is probably more elegant, but the advantage of the second is the existing toolchains (like emscripten) work magic on the C code

Crispin15:03:24

you've got your advanced optimiser already done, and whats really great is you can bring across your stdlib malloc/free heap allocator into the wasm code to manage the wasm "linear memory"

Crispin15:03:58

ie, you can malloc and free in your wasm code, then access that data from the JS side. Its shared.

Crispin15:03:41

and if you decompile the C generated wasm, you can see the entire libc heap allocator expressed inside the wasm

Crispin15:03:27

so theres all this work that just kind of comes for free with transpiling first

Crispin15:03:43

zig looks good though!

Crispin15:03:07

and if liz supports me writing macros... that can solve my problem

borkdude16:03:11

liz doesn't support macros I think :/

borkdude16:03:46

at one point liz listed SCI as an option to execute macros during transpilation, not sure if Jakub explored that option, but don't see it mentioned anymore