squint

borkdude 2024-08-16T09:00:24.798169Z

I had a stupid idea. Some people asked if we could use @ for js-await but this won't work since js-await is a special built-in thing which will make functions async if you use it, unlike deref. But we could use as a shorter notation, inspired by core.async. Although I'm not convinced that a few characters will make the difference.

(-> (js/fetch "") 

Stephan Renatus 2024-08-16T09:07:42.413419Z

I have to admit that just from looking at the two snippets, what I find more confusing is that it’s js-await and not js/await

borkdude 2024-08-16T09:09:37.991809Z

It used to be js/await but for good reasons this has been changed to js-await : • js/foo is used to point at global JS objects/functions. however, await is not an object or function, it is special JS syntax • for special JS syntax, the convention js-foo is used in ClojureScript. E.g. js-delete , js-keys , js-in . Hence js-await

👍 1
Stephan Renatus 2024-08-16T09:10:32.847549Z

thanks for explaining 🙂 I guess it would become second nature if I used this more… need to find a way to do so

Mike 2024-08-16T09:28:32.797269Z

Does using js-await inside of a function automatically async that function? E.g.

(defn ^:async foo []
  (js-await (bar)))
and
(defn foo2 []
  (js-await (bar)))
are identical in functionality?

borkdude 2024-08-16T09:29:09.083579Z

no, you have to mark foo2 as async, or it's going to be a JS error, just like in JS itself

Mike 2024-08-16T09:30:30.382509Z

What do you mean by js-await is a special built-in thing which will make functions async if you use it ?

borkdude 2024-08-16T09:31:05.264609Z

I mean in JS await is a special syntax

borkdude 2024-08-16T09:31:17.385449Z

and in squint js-await just compiles to await

Mike 2024-08-16T09:31:31.308539Z

Ah right, I think I misread there

borkdude 2024-08-16T09:31:46.012909Z

in JS you have to use the async keyword for a function as well, if you're using await or else you're going to have an error

Mike 2024-08-16T09:32:05.275779Z

Yeah for sure

Mike 2024-08-16T09:32:59.110079Z

I thought maybe you were suggested that there was some magic added to the defn macro in squint that checked the body for js-async

borkdude 2024-08-16T09:33:37.232629Z

well, there is some magic but functions aren't magically turned into async, I think that would lead to nasty surprises, better to be explicit

borkdude 2024-08-16T09:34:14.950239Z

e.g. let expressions use IIFEs when compiled to JS and those are automatically async

borkdude 2024-08-16T09:34:27.257659Z

so you can use js-await in let

borkdude 2024-08-16T09:39:24.484109Z

(switch to non-REPL mode for cleaner code)

Chris McCormick 2024-08-17T06:08:02.751089Z

Personally I would avoid overloading @ or <! with new meaning that is similar but not quite the same and come up with some new character sequence like <p or @w or something.

borkdude 2024-08-17T07:36:43.552379Z

<! Isn’t an existing thing in core, just core async so it’s not overloading necessarily, but I won’t anyway

lilactown 2024-08-18T16:51:08.982809Z

what's wrong with extend-protocol atm?

borkdude 2024-08-18T17:02:54.644659Z

I don’t think there Iassosiative etc at the moment to which assoc reacts

lilactown 2024-08-18T17:10:47.311469Z

oh right

2024-08-19T01:14:26.518589Z

That would be awesome! I'm using immutablejs and squint heavily in my web app-startup!

borkdude 2024-08-16T09:58:27.168839Z

I guess if I'd make extend-protocol etc work more reliable in squint, I could make assoc et al work with immutablejs in a "transparent" way

3
borkdude 2024-08-21T20:16:08.106289Z

I haven't totally rejected the idea, but still thinking about pros / cons. One con is that if assoc etc have to check the object for protocol impl, it's a small perf cost

borkdude 2024-09-23T12:32:34.053659Z

I thought more about this. It would make sense for squint that the "contract" of the standard library is that assoc, etc return a ready to be used JS object without having to go through some conversion (as it the case with immutable-js)

borkdude 2024-08-19T18:56:13.357129Z

Got this working locally (and in branch assoc-protocol):

$ ./node_cli.js -e "(require '[\"immutable$default\" :as imm]) (extend-type imm/Map IAssociative (-assoc [m k v] (.set m k v)))  (-> (new imm/Map [[1 2]]) (assoc :foo :bar 1 2 3 4) .toJSON js/console.log)"
{ '1': 2, '3': 4, foo: 'bar' }
Not sure how far we want to push this though. For example = currently always just compiles to JS === and there isn't an -equiv protocol, so comparing ImmutableJS hashmaps still has to be done manually, which kind of defeats the purpose of not dealing with immutableJS literally

borkdude 2024-08-19T18:58:25.188979Z

so perhaps it's better to just be explicit in using immutablejs

2024-08-19T20:00:23.094099Z

hmm. yes, that makes sense.

2024-08-30T18:06:02.444169Z

I use Squint (over ClojureScript) because of the performance benefits. I would be happy to see it going "lightweight" path.

lilactown 2024-08-20T15:53:55.207669Z

I think it might be OK to treat IAssociative and equality as separate. you already have to compare JS objects manually if you can't rely on new reference => new value

borkdude 2024-08-20T15:56:00.637659Z

yeah I was also thinking that

borkdude 2024-08-20T15:56:42.483599Z

perhaps we can introduce an equiv protocol with an explicit equiv function for value equality

borkdude 2024-08-20T15:56:53.976939Z

which you should use in squint rather than using = for value equality

borkdude 2024-08-20T15:57:06.258369Z

not sure how much that would buy you

borkdude 2024-08-20T15:59:58.379929Z

my question in general is: how much does extending core functions to protocols buy you vs writing your small idiomatic clojure wrapper around immutable-js (e.g. imm/assoc, imm/dissoc etc

2024-08-20T16:05:41.005129Z

I see value because it facilitates the possibility of porting your app to full clojurescript and throwing away immutablejs down the road.

borkdude 2024-08-20T16:06:54.060209Z

that's true, but never 100% right

borkdude 2024-08-20T16:07:50.222539Z

you could also reach that goal by doing this:

(ns foo (:require [#?(:squint my-immutable-wrapper :cljs cljs.core) :as imm]))

(imm/assoc ..)

😎 1
borkdude 2024-08-20T16:08:53.923639Z

perhaps = isn't as important in general since in Clojure you mostly rely on something being a subset since more keys are generally not a problem

borkdude 2024-08-20T16:09:04.877799Z

but now I'm rationalizing

pez 2024-08-16T14:06:59.047799Z

https://x.com/pappapez/status/1824447585169420639

😎 1
pez 2024-08-16T14:43:24.323929Z

The qu on the back of the shirt could work nicely as a slack emoji, I think.

borkdude 2024-08-16T14:44:03.471959Z

feel free to upload it! https://github.com/squint-cljs/squint/tree/main/logo

5
pez 2024-08-16T15:03:31.538339Z

Hmmm, maybe it got a bit destroyed… Kan @tonsky make a special icon for this maybe?

borkdude 2024-08-16T15:33:16.990159Z

squint

22