Fork me on GitHub
#clojurescript
<
2021-09-23
>
v3ga01:09:47

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.

athomasoriginal12:09:09

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”.

athomasoriginal12:09:35

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.

athomasoriginal12:09:53

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

v3ga01:09:12

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

pithyless04:09:57

@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. https://www.youtube.com/watch?v=3dZK5seIaVI&amp;list=PLVi9lDx-4C_TBRiHfjnjXaK2J3BIUDPnf

dgb2306:09:54

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 🙂

thheller05:09:51

(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

thheller16:09:16

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

thheller16:09:41

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
henryw37409:09:21

Reagent very well established ofc, but has some oddity wrt input elements. see e.g. https://github.com/reagent-project/reagent/blob/master/doc/examples/material-ui.md which is good to be aware of if using things like material ui, semantic ui etc. Helix wouldn't have any such issues.

henryw37409:09:21

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 `e.target.value` during the `onChange` event. That should be enough to preserve the cursor.`

p-himik10:09:33

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.

henryw37410:09:17

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

v3ga14:09:55

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

punit-naik14:09:06

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?

borkdude15:09:17

@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)?

thheller21:09:35

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
thheller21:09:11

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
john19:09:40

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

lilactown19:09:33

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

john19:09:36

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

harishtella19:09:04

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]]
clj
user=> (update [0 0 0] 3 inc)
Execution error (NullPointerException) at (REPL:1).
null

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

p-himik19:09:57

I'd say it looks like a proper bug.

harishtella20:09:12

Ah, in that case I’ll file it on github. Or here rather. https://clojure.atlassian.net/jira/software/c/projects/CLJS/issues/

john20:09:04

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

lilactown20:09:35

bug reports don't go in github - they should be filed here https://clojure.atlassian.net/jira/software/c/projects/CLJS/

👍 1
lilactown20:09:49

hmm I think this is actually a difference in inc

lilactown20:09:21

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

lilactown20:09:33

Clojure 1.10.1
user=> (assoc [] 0 1)
[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).
null

lilactown20:09:43

cljs.user> (assoc [] 0 1)
[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]
:repl/exception!

p-himik20:09:09

A good find!

lilactown20:09:40

the difference:

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

p-himik20:09:05

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

john20:09:41

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

ag20:09:20

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?

lilactown20:09:23

vectors are associative structures in both clojure and clojurescript

john20:09:50

And js arrays are actually maps lol

lilactown20:09:15

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

john20:09:58

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

ag20:09:39

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

ag20:09:44

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

😂 1
harishtella21:09:17

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)

john23:09:22

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

john23:09:10

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

john23:09:44

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

john23:09:16

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

john23:09:14

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

john23:09:49

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

harishtella23:09:01

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

👍 1