Fork me on GitHub

I hate to ask as I don’t like pitting libraries against each other but would it be better to work with reagent or helix? My JavaScript knowledge is minimal so I’m also learning it a bit at a time so clearly I’m not stuck on doing things the vanilla react way, however I wonder if I should start off with helix so I have a understanding of react and what parts reagent and re-frame clean up for DX.


Hey there! I actually really like both libraries! I would begin with Reagent because there’s going to be more Clojure examples available to you in open source, documentation will be abundant and reagent comes with a state management library built in which you can opt to use (ratoms) and finally it wraps React in such a way that you can think “Clojure” over thinking “React”.


If you’re goal is to understand React (and this is a great goal!) then you should just work with React for a bit and see what’s up. There is going to be no substitute for going right to the source.


I probably should have begun my responses with: what’s your goal?


I also wonder…re-frame alternatives. I read a bit on datascript and posh. I feel I’m taking the harder road here but I’m trying to learn what goes on in the background, getting away from frameworks


@U06FM9QN9 you may find Grokking Fulcro interesting. Irrespective of whether you ever bother to use Fulcro, Tony Kay walks through a lot of the problems Fulcro (and other libraries) need to address to wrap React properly.;list=PLVi9lDx-4C_TBRiHfjnjXaK2J3BIUDPnf


Oh that YT series is really good. The presentation is a bit ad-hoc, but I find that relatable. What is interesting and educational here is how he breaks through the abstractions of React and really plays with it and shows how Fulcro is wired up. I started watching it to learn more about Fulcro but then I realized how little I understood React in the first place 🙂


(I actually use it in production and you can see it in action in the shadow-cljs UI. I'll hopefully make it a proper documented library soon) 😛

🙏 7
cljs 8
😍 2
😎 1
Bryce Tichit09:09:16

Amazing project ! But it's not really clear for me what are the limitations that React wrappers have that your approach does not have


its not react based that is the main limitations you dont have 😛


I make no claims about being better or worse than react

Bryce Tichit09:09:40

Helix is amazing, 100% recommend it. It's really closer to modern React and make great uses of hooks

👍 1

Reagent very well established ofc, but has some oddity wrt input elements. see e.g. which is good to be aware of if using things like material ui, semantic ui etc. Helix wouldn't have any such issues.


well, I may be wrong, but I didn't think think this was an issue generally. the last comment in that thread is The canonical solution is to make sure you're calling setState` with `` during the `onChange` event. That should be enough to preserve the cursor.`


Yes, but IIRC the Material UI input field does not do that as well. And Reagent does it for all inputs itself, but it cannot access the internals of Material UI - that's why it needs you to provide the input explicitly.


ah sorry you're quite right. I'll delete my comment as misleading


@deleted-user I’m a slow learner. That may be a bit much. Lol


Hey People: I had a small question. I have a couple of profiles inside :cljsbuild {:builds [{...}, {...}]} and I am repeating some of the compiler options. Is there a place where I can define the common config and refer them from inside a particular build's config?


@punit-naik more context: is this lein cljsbuild?

Drew Verlee18:09:55

If i'm developing a cljs library, whats the story around getting a running repl from which to eval the logic? If i'm building a browser app, i have been using figwheel and shadow-cljs, are those tool chains still ideal for this even it's a library (its going to be injected)?


regarding shadow-cljs either shadow-cljs browser-repl or shadow-cljs node-repl. creating a :browser build for local testing also works, or one of the testing builds can also help

👍 1

so yes you want either of these tools for local development regardless. the lib is just the uncompiled sources in a .jar so it doesn't matter which tool you use for local development

👍 1

Yeah, it helps to have another app project that points to your lib project in deps.edn like some/lib {:local/root "../some"} with :source ["src" "../some/src"] and then you can develop in the application with the figwheel dep but leave the lib project clean of application-time deps


I often use a Node.js REPL assuming it can run in both node and web


Yeah, calva has a quick and easy node-js target you can launch for a lib with no extra dev deps in the project - I do that these days too


Just curious if anyone has encountered this cljs/clj difference. Seems too obvious to be a bug. cljs

cljs.user=> (update [0 0 0] 3 inc)
[0 0 0 1]

cljs.user=> (update [0 0 0] 4 inc)
#object[Error Error: Index 4 out of bounds  [0,3]]
user=> (update [0 0 0] 3 inc)
Execution error (NullPointerException) at (REPL:1).

user=> (update [0 0 0] 4 inc)
Execution error (NullPointerException) at (REPL:1).


I'd say it looks like a proper bug.


Ah, in that case I’ll file it on github. Or here rather.


(update [0 0 0] 4 inc)
; Execution error (Error) at (<cljs repl>:1).
; Index 4 out of bounds  [0,3]


bug reports don't go in github - they should be filed here

👍 1

hmm I think this is actually a difference in inc


update uses assoc under the hood. using just assoc, the behavior is the same between impls


Clojure 1.10.1
user=> (assoc [] 0 1)
user=> (assoc [0 1 2] 3 3)
[0 1 2 3]
user=> (assoc [0 1 2] 4 4)
Execution error (IndexOutOfBoundsException) at user/eval5 (REPL:1).


cljs.user> (assoc [] 0 1)
cljs.user> (assoc [0 1 2] 3 3)
[0 1 2 3]
cljs.user> (assoc [0 1 2] 4 4)

Execution error (Error) at (<cljs repl>:1).
Index 4 out of bounds  [0,3]


A good find!


the difference:

user=> (inc nil)
Execution error (NullPointerException) at user/eval7 (REPL:1).
cljs.user> (inc nil)


Given that, my guess is that it will be closed with "won't fix". Numerical differences are usually preserved between CLJ and CLJS.


yeah, cljs is more lax from all kinds of angles, often due to the host semantics


I think even considering js vectors as "associative" is wrong. Why would anyone do that? I can't come up with a single good idea why would I want to assoc or update in a vector?


vectors are associative structures in both clojure and clojurescript


And js arrays are actually maps lol


it's part of their core performance characteristics - you should be able to quickly read and update a value by index with a vector. as opposed to a list, which you would have to traverse the list up to the index, which is why they do not implement IAssociative


@U0G75ARHC we're so used to updating things by mapping over them, we forget that we'd want to, but how else would you update a vector by index?


(vec (doto (js/Array 1 2 3) (.splice 0 1 5)))   ; => [5 2 3]


Oh, look. It predictably fails successfully when given out of bound index. Javascript is full of ... things that make Gary Bernhardt happy 🙂

😂 1

Wait am I missing something. It seems strange to me that this works in either implementation.

user=> (assoc [0 1 2] 3 3)
[0 1 2 3]
The vector [0 1 2] should only have indices 0, 1, and 2 . Why am I able to assoc something at index 3? Something special about vectors allows for one more index? For example, I cant do (nth [0 1 2] 3)


Looks like (assoc v (+ 1 (count v)) 9) is supposed to be synonymous with (conj v 9)


So as to allow using assoc'ing on the end of a collection as a conj op


Guessing the same logic is happening somewhere in the guts of clojure.lang.RT


well, (assoc v (count v) 9) I guess, since the count of v would need to be converted to zero-based index


But adding an element to the end of the coll, as with conj, seems to be an intended use case for assoc in that way


Which is nice if you're iteratively associng on the same vec over a range


Ah cool, thanks @U050PJ2EU for pointing me to that. Makes sense

👍 1