squint 2024-09-14

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.

๐Ÿค˜ 1

Thank you, Peter! Send my hello's to the peeps ๐Ÿ™‚

1

@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!

1

Yes I'm also in Stockholm. Met Peter at the Clojure Lunch meetup he resurrected just a couple of months ago

2

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 currently

Something like this would work:

(def x)
(defn foo [x]
  (set! x x)
   x))
probably

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.

๐Ÿค˜ 1

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"

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

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

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

โญ 1

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!