Is this expected behaviour or should I file a bug? These work in cljs:
$ npx squint -e '(pr-str (assoc-in nil [:a :b] 1))'
$ npx squint -e '(pr-str (update-in nil [:a :b] (fnil inc 0)))'
$ npx squint -e '(pr-str (dissoc nil :a))'
The error:
Error: Illegal argument: assoc-in expects the first argument to be a Map, Array, or Object.> get returns undefined in squint. update-in etc use get
I keep running into this. I found that some returned nil when no matching item was found in a collection, and I had (th/assert-equal ...some result... nil). I changed it to nil? which works but it still feels like a bit of a footgun all these things returning js/undefined when cljs returns nil.
in CLJS undefined and nil are considered equal. So returning undefined should not be a problem. The reason we return undefined is that we can say "this thing wasn't found" without having to use contains?
we could make some return undefined as well
or maybe I should just drop the get -> undefined thing but I don't think you should be running into undefined or null differences, that may just be an issue of your JS testing layer
Yeah it's the testing layer for sure, since Squint is internally consistent. I guess it just depends what experience you want people coming from real cljs to have. Of course Squint is not cljs, but the more like it it behaves the less teething problems people are going to have. 🤷♂️
People using cljs do interop with js of course and so if there are differences in interop that will explode sometimes.
cljs.user=> (undefined? (aget #js {:a 1} :b))
truein squint JS semantics are preserved as much as possible. In JS undefined means "not found"
but I see your point. why do you test for explicit null?
btw clj-kondo has a new rule coming up where (= nil ...) is adviced to be rewritten to (nil? ...)
it wasn't me your honour it was my magic computer brain
lol
maybe you can tell it: when testing for explicit null always use ... - in your style guide
the undefined vs null is a bit like your ref callback improvement
great idea i'll add that to my squint.md
bug/oversight
probably defaulting to an object should be the squint behavior
Will submit a bug, thanks!
thanks!
I'm not sure if this is the same bug:
$ npx squint -e '(prn (update nil :a inc))'
{"a":null}
It doesn't throw an error but it should be {"a": 1} like cljs I think.I see this:
$ ./node_cli.js --repl -e '(update nil :a inc)'
#js {:a ##NaN}which makes sense maybe since incrementing undefined isn't defined?
ClojureScript 1.11.132
cljs.user=> (inc js/undefined)
##NaNcljs.user=> (inc nil)
1I guess get returns nil in CLJS and undefined in squint. I could change that, but I kinda like that behavior
so you know that the key wasn't there
you could use (fnil inc 0)
Added the example
I don't understand why the nil turns into undefined, but I can use fnil as you suggested.
get returns undefined in squint. update-in etc use get
so nil doesn't turn into undefined, there was never a nil
Oh ok
Interesting, I didn't realize get returns undefined.
in squint it does, as I explained above
Thanks for that fix! 🙏
Oh never mind I see you fixed it.
I do'nt know what that does 🙈 will look it up.
I'll add it to the TODO list.
r/with-let is on my list already.
The r/cursor and r/reaction are untested and probably buggy.
create-ref basically creates an atom-kind of thing that receives the dom node, instead of the callback
it can be both in reagent
not urgent, just something I randomly tested
Oh ok interesting.
I can't actually find any examples of this
perhaps ChatGPT was hallucinating
Lol
in React you do have something like createRef, but you're already covering reagent's :ref thing!
The only instance on GitHub: https://github.com/search?q=%22create-ref%22+language%3AClojure&type=repositories&l=Clojure
Because the repo is called _create_-_reframe_-app 😹
lollll
you forgot to look in the code instead of repos: https://github.com/search?q=%22create-ref%22+language%3AClojure&type=code
but since it's not supported in reagent, it's ok
Haha whoops. Looks like it's supported by rum and uix.
I guess we could easily support this if we wanted to. create-ref would just return an atom and instead of calling the callback you'd reset the atom.
Ah ok interesting. At the moment I'm just aiming for the small bits of the Reagent API in widespread usage.
Not opposed to it though.
yeah, I'd hold off for now
despite this being slop coded, do you know how it actually works?
it seems to re-use DOM elements when it can
No it is honestly a bit of a black box to me. I mean I did read the code, but particularly fully-render-hiccup I haven't fully grokked.
lol
Actually it's not that complex. There's a lot of special casing which was due to me giving broken things to the LLM.
There is a lot of strange stuff in there I would have done differently myself, but then I probably wouldn't have done it if I had to do it completely myself.
Things like this I find questionable.
(defonce ^:dynamic *xml-ns* "")
And this:
(def ^:private event-name-map
{:on-double-click "ondblclick"})
Why is this marked ^private lol?lol
where do you see this?
https://github.com/chr15m/eucalypt/blob/main/src/eucalypt.cljs#L79-L80
It's as if it's written by somebody with no brain...
in reagent onClick is also accepted btw, so maybe support this too
But a lot of time to mutate the code until the tests pass.
Will add to TODO.
I guess at some point it's best to stop using an LLM and cleaning up the slop and actually understand it? not sure
it works well so far though
Yes for sure it needs an actual brain to look through it and clean up.
This is why I'm a bit reluctant to release it.
I've never been afraid to release slop code written by myself, but that's just me ;)
It's almost not so much "look at this thing I made" but "look at this thing I found".
Ha ha ok that will be my inspiration. If it's good enough for borkdude it's good enough. borkdude
Discovered vs. invented again (!) --- that clock example is really something. 👏 🙂
I am horrifimazed by this entire journey
great description
Why I think this is ok though. The code of eucalypt isn't that big and it works and has tests. I'm sure I could figure out in details why it works and find out how to improve it.
Famous last words. Narrator's voice: he would never find out, but used it for years ever after.
its like using a buggy version of a replicator on star trek. you order something and all the components are definitely there and it sort of even tastes right but its up to you to determine if it ACTUALLY has the right ingredients etc.
and many times to do so requires the same effort as doing it by hand in the first place
but I definitely get the fun side
if this lib is useful enough, I think it may be worth it to rewrite it by hand and heavily curate the code. it's like 500 lines or so?
yeah if nothing else it skipped to proof of concept effort
exactly I love the idea of a tiny reagent/react replacement that I could use to write web components in lieu of lit for instance
replicant is even more desirable but I understand the cost of adding immutablejs sort of defeats the purpose
(ns my-app
(:require ["lit" :as lit]))
#html ^lit/html [:div "Hello"]Perhaps replicant could also be implemented using deepEquals from es-toolkit, like eucalypt is doing. CLJS ends up doing deep equals often anyway
interesting about deep equals. I meant using eucalyptas in place of lit so there is some notion of reactive rendering etc which I appreciate from lit. That said I think there work with signals is very interesting and I hope it rolls out soon as part of all browsers.
and honestly your example there with just calling .render yourself is probably 90% of the time the best practice for web components.
in general THANK YOU for squint. I feel like this sort of thing not being possible via regular google closure cljs has been an albatross around my neck for years. eg not being able to write cljs web comps that you can share with non cljs developers without them asking “why is this file size larger than the rest of my entire project?”
That's really great to hear, thank you
I would very much welcome PRs to clean up Eucalypt, if I don't get to it first!
@chris358 is r/create-ref also supposed to work?
(not quite sure how this works normally in reagent)