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 "
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
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
thanks for explaining 🙂 I guess it would become second nature if I used this more… need to find a way to do so
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?no, you have to mark foo2 as async, or it's going to be a JS error, just like in JS itself
What do you mean by js-await is a special built-in thing which will make functions async if you use it ?
I mean in JS await is a special syntax
and in squint js-await just compiles to await
Ah right, I think I misread there
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
Yeah for sure
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
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
e.g. let expressions use IIFEs when compiled to JS and those are automatically async
so you can use js-await in let
(switch to non-REPL mode for cleaner code)
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.
<! Isn’t an existing thing in core, just core async so it’s not overloading necessarily, but I won’t anyway
Hmm, nice, immutable-js maps work fine with squint https://squint-cljs.github.io/squint/?src=KHJlcXVpcmUgJ1siaHR0cHM6Ly9lc20uc2gvaW1tdXRhYmxlIiA6YXMgaW1tXSkKCihsZXQgW20gKG5ldyBpbW0vTWFwIFtbMSAyXV0pCiAgICAgIG0gKGltbS9zZXRJbiBtIFs6Zm9vIDpiYXJdIDpiYXopXQogICgtPiBtIDpmb28gOmJhcikp
what's wrong with extend-protocol atm?
I don’t think there Iassosiative etc at the moment to which assoc reacts
oh right
That would be awesome! I'm using immutablejs and squint heavily in my web app-startup!
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
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
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)
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 literallyso perhaps it's better to just be explicit in using immutablejs
hmm. yes, that makes sense.
I use Squint (over ClojureScript) because of the performance benefits. I would be happy to see it going "lightweight" path.
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
yeah I was also thinking that
perhaps we can introduce an equiv protocol with an explicit equiv function for value equality
which you should use in squint rather than using = for value equality
not sure how much that would buy you
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
I see value because it facilitates the possibility of porting your app to full clojurescript and throwing away immutablejs down the road.
that's true, but never 100% right
you could also reach that goal by doing this:
(ns foo (:require [#?(:squint my-immutable-wrapper :cljs cljs.core) :as imm]))
(imm/assoc ..)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
but now I'm rationalizing
The qu on the back of the shirt could work nicely as a slack emoji, I think.
feel free to upload it! https://github.com/squint-cljs/squint/tree/main/logo
Hmmm, maybe it got a bit destroyed… Kan @tonsky make a special icon for this maybe?
squint