Hey, I'm giving a https://2024.heartofclojure.eu/talks/squint-a-taste-of-clojure-for-javascript-devs/ at Heart of Clojure and a stretch goal I've been thinking about to drive home the experience of REPL driven development is to have the generated JavaScript send live values of function argument inputs as bindings when the function is invoked, similar to https://github.com/AbhinavOmprakash/snitch defn*, to a running REPL.
I'm thinking given the following clojure
(defn foo [input]
input)
(foo "hello")
would generate JS that sends an HTTP request to the REPL process with an eval op binding input to "hello".
Any ideas on how doable this is or alternative ways forward?Kick ass in Belgium, Felix! We will be missing you at the Clojure Lunch in Stockholm tomorrow, but the deed you will be doing is a worthwhile deed, so thereโs that.
Thank you, Peter! Send my hello's to the peeps ๐
@felix.kauppi.alm you're also living in Stockholm?
I saw Oslo flash by in a comment that was then deleted. ๐ Since Iโve already brought up the Stockholm Clojure Lunches hereโฆ I went to Oslo this spring to try to figure out their success with Clojure lunches and meetups. So thatโs why we met there, @borkdude. And so far weโve been able to clone the success pretty well. Even if I may not be the best judge there.
niiiiice!
Yes I'm also in Stockholm. Met Peter at the Clojure Lunch meetup he resurrected just a couple of months ago
Hey @felix.kauppi.alm, first of all: really cool that you're giving a talk on squint, I'm planning to visit it at HoC for sure!
Now let's see if I can understand your question...
Cool! I'm looking forward to saying hi in person ๐
so do you mean that you would generate something like:
(def input "hello")
such that you could evaluate input?Exactly
First I'd try if this works at all in squint:
(defn foo [x]
(def x x)
x)
I'm not even sure that this will work, since "vars" are emitted as "var" and I don't think it will hoist it to the top level currentlySomething like this would work:
(def x)
(defn foo [x]
(set! x x)
x))
probablyhmm, that won't work either. it just modifies the function's argument ;-) https://squint-cljs.github.io/squint/?src=KGRlZiB4KQooZGVmbiBmb28gW3hdCiAgKHNldCEgeCB4KQogIHgpCgooZm9vIDEpCng%3D
ah this does work, only in the REPL-output:
Hmm yes that works when all is run in the REPL. But the generated JS isn't sending anything to the repl process on run
with "the repl" do you mean nREPL? and not sure what you mean with "isn't sending" ?
I'm creating an example that I hope will make it clearer. Two secs
or rather making a GH repo public so you can gauge the setup
ah yes even better, thanks
will take a look later today-ish
No stress, I appreciate it ๐
https://github.com/kauppilainen/react-cljs/ exposes a vite plugin that runs Squint on all .cljs files in your project. Working test project https://github.com/kauppilainen/react-cljs-test.
https://github.com/kauppilainen/react-cljs-test/blob/main/src/counter.cljs#L7-L16
in the above example, how do I start it?
npm run cljs-repl?
Correct
and in parallel I also run watch?
npm run dev and npm run cljs-repl are the only ones you need running in parallel
$ npm run dev
npm ERR! Missing script: "dev"Is this in https://github.com/kauppilainen/react-cljs-test?
no I thought you linked to react-cljs
Sorry, that's just to the npm package. The example React project using the that npm packages is react-cljs-test
ok, I have the REPL working
now what do I do?
Check out counter.cljs. There's an example in the comment block of how I'm thinking about how the communication could be done
nREPL isn't http you know
not sure what the example is supposed to mean
if you want to eval (def n 1) that can be done by ... doing that in nREPL? :)
I think I might be misunderstanding you
This also works for me:
That all works as expected ๐ Now in customInc, I'm imagining that when the Squint generated JS is run in the React project by clicking the count button, the n input should be sent to the REPL
A lot like https://github.com/AbhinavOmprakash/snitch defn* macro
I see
one of the problems is that the nREPL only runs in Node.js right, so it's not connected in any way to the web browser
Correct
which is something that could be solved (I have it working for #scittle) but takes time
what I did there is implement an nREPL server which runs in an external process, listens for messages and forwards those to the browser via a websocket
since a browser can only connect via http or websockets
so it's very similar to your idea
I see. Cool that you've done something similar for scittle!
I probably won't have time to get that working in time for the talk but I'll be sure to give it a mention. For me that's where the REPL workflow really starts to shine in comparison to the Javascript equivalent save file->see changes loop
yeah
I probably won't get to this before the talk either but I'm pretty sure it will exist at some point :)
Thanks for taking the time to give this a look! I'll read the scittle solution for this at some point. Interesting stuff ๐
the Proof of Concept is scittle, let's say
here's the docs: https://github.com/babashka/scittle/tree/main/doc/nrepl
Clerk viewer functions are also built using SCI and you can now even develop those using an nREPL server which uses the same approach
Good luck with your talk! If you have any questions, etc. let me know
Thank you! I will ๐
@felix.kauppi.alm I'm going to be touching briefly on Squint in my workshop and I will point people to your talk, which is later in the day, for more depth and details.
@chris358 Cool! Please do ๐ Looking forward to seeing you at the conference.
Likewise!