9 ms·
Lessons on Writing JavaScript and React from ClojureScript
- christophilus 5y agoFellow South Carolinian and former Charlestonian. I nearly applied to Reify for the same reasons. Clojure is one of my favorite languages. However, I suspect I’d dislike it in a large product / team setting. Having moved from C# to Rails to JavaScript and now to TypeScript, I think I’d miss static types too much. I’d be very interested in a follow up blogpost after you’ve been at Reify for a year or two.
- rjerue 5y ago> I’d be very interested in a follow up blogpost after you’ve been at Reify for a year or two. Me too!
- mikojan 5y ago1. Redux docs encourage you to use @redux/toolkit which drastically reduces boilerplate. And even if you do opt into using vanilla redux: Typescript for some time now has supported string literal types which render enums obsolete almost. 2. Mutability is not at all a problem. Those types of bugs are obvious. On the other hand, mutability allows for a type of fine-grained control you will absolutely need. It is Javascript after all. 3. Redux _does_ allow "users to create complicated compounded subscriptions in a performant way using materialized views" which is a rather convoluted way of saying "memoize derived values." You are looking for the createSelector-API you had been shunning in the opening statement. 4. What in the name of god almighty is this: function Component({ children }) { const { data, loading, error } = useGetMyData(); return ( <div> {(function () { if (loading) { return ( <div>loading...</div> ); } if (error) { console.error("Uh oh!"); return ( <div style={{ color: "red" }}>{error.message}</div> ); } return ( <> <div>Data:</div> <div style={{ color: "green" }}>{data}</div> </> ); })()} {children} </div> ); } We are encouraged to pour yet another layer of abstraction on top of Javascript pulling in clones of the very libraries we had already been using. Only now, our knowledge about performance testing and tuning in ReactJS/Javascript is basically useless. At this point, why not do away with all "boilerplate" and just use Elm?
- swordbeta 5y agoWhat is wrong with the component?
- SahAssar 5y agoHaving JS variables inside JSX inside JS IIFE:s inside JSX inside JS feels bad to me. Current mainstream frontend development does not care about my feelings though.
- prezjordan 5y agoI assumed (4) was the author's frustration that if-statements aren't expressions, and nesting ternaries is rough.
- axguscbklp 5y agoYeah, I do not understand where the author is coming from. One could easily write a helper function in JavaScript that does the same thing that the author's Clojure "cond" does. There is no need to use an IIFE if one does not want to.
- madia_leva 5y agoHmmmm... I wonder how you would avoid the expressions from being evaluated without wrapping then in a function (sorry if it's a lame question, I haven't done any JS in years). Not that there is anything wrong with lambdas, but it's quite a los of boilerplate for something as simole as a cond.
- rjerue 5y agoBingo, IIFEs are and affront to god and nature. Ones in JSX arguably even more so. However, it's really the only way you can colocate all your display code to one part of a function.
- beirut_bootleg 5y agoI can't decide if that IIFE is the sign of a non-React dev trying to jam in concepts from other languages, or just done in bad faith to force a point.
- agentbellnorm 5y agoI just wish more people would adopt clojure and clojurescript. The world would be a better place.
- cyberscientist 5y agoMy company decided to stop using clojure as there were not that many developers in the market or willing to learn it. I also think people rather invest time in Scala because there are more jobs available for it.
- rchaves 5y ago> ClojureScript has unlocked whole new levels of productivity I keep seeing this claim over and over again about Clojure and Clojurescript. I don't get it, at all. I tried it, multiple times, I don't get where the productivity boost could come from. I though maybe the so-called REPL-driven development (as if clojure is the only language ever with a REPL), I watched videos about REPL-driven development, developed a project that way, cool... not more productive than say TDD or hot-reloading > I enjoy it because there is little cognitive load in terms of understanding what the program is doing. Is there? I mentioned I was not more productive in clojure, in fact I was actually much slower in clojure. It's not lack of FP knowledge, because in fact I love how productive I am with Elm, so maybe it's the lisp style, or maybe my inexperience with the language, I can't memorize all thousands of functions to manipulate lists and hashs in clojure (get-in, map-vals, conj, dissoc, select-keys, sorted-map-by, do you know what all those do?) which do a lot, I felt clojure was dense, the opposite of little cognitive load After that, his following arguments about reagent vs useContext and Re-Frame vs redux is not about some real advantage of clojurescript over javascript, but rather conscious decisions that js community did to be explicit over implicit, it was an explicit trade-off, doesn't convince me that much as positive point for cljs I want to like Clojure and Clojurescript, I really do, I would like to brag about writing lisp like the rest of you too, please convince me, claiming productivity because of "repl" or "less symbols" is not working, I need deeper reasoning
- yen223 5y agoYeah, I would like to see more examples of startups picking up Clojurescript (or any of these non-mainstream languages), and running circles around their competitors as a result.
- frankiesardo 5y agoPrecursor.app for a while was a great example. Now I would look at Roam Research for what a Clojure powered startup can do.
- qsort 5y agoI don't get it either. I do backend mostly, but my main differentiator isn't even functional vs. imperative, it's typed vs. untyped. As much as this take is going to make half of HN throw up, I'll take Java over Clojure any day, and Java doesn't even have a good type system to begin with. I could see myself being very productive with lisps for small, plumbing-type stuff that you would use Python or Perl for, but in that area the foremost priority is libraries and the ecosystem, and Python isn't going to lose to any lisp in that department, even though I'm not a fan of the core language.
- testycloj 5y agoI feel the best thing about clojure is test.check. The fuzzy generators are a delight to work with. Everything else is just bonus: functional, immutable, benevolent use of brackets, edn, https://clojuredocs.org/ https://clojuredocs.org/, interop, uberjar, spec, clojurescript, https://github.com/clojure https://github.com/clojure, lein, deps, native-binaries, repl, etc.
- da39a3ee 5y agoI'm certainly attracted to getting more experience of FP / a lisp in production (as opposed to a lisp in my text editor). However, > Previously working with TypeScript has made me miss types and appreciate the runtime checks of spec. This seems like a huge deal. Javascript has got to the point where it has nice static typing via typescript, and various new type-check-time language constructs associated with the typing, and enums, and really nice tooling for it all. Coming from Python I've been really enjoying typescript, since the tooling works slightly better (and doesn't suffer from Django's typing dead-ends). So, I am not all sure that I would be prepared to throw away static typing in exchange for lisp.
- mping 5y agoI would love if clojure had a solid gradual typing story just as ta has. There is core.typed library but I haven't tried nor is it widely employed. However I think its a valid trade-off, and with sufficient experience you learn to navigate the issues just like in JavaScript.
- lobstrosity420 5y agoJSX is easily the worst part about writing React apps to me. It tends to get convoluted and hard to read really fast. Seeing someone trying to represent it with LISP syntax I now realize it could be 100x worse. Don't get me wrong, Elixir sold me on a lot of the stuff the functional paradigm brings to the table and Closure peeked my interest in having some of that in front end land, but please lose the LISP XML tree, it is a crime against God and nature.
- deleted 5y ago[deleted]
- raspasov 5y agoCongrats on the new job! Clojure(Script) is great. I remember how excited I was when I first "understood" Clojure. One small note: "There are also @ symbols for expressing async behavior." @ is just a reader macro, aka shortcut, for (defer ...) in Clojure(Script). https://clojuredocs.org/clojure.core/deref https://clojuredocs.org/clojure.core/deref
- tiborsaas 5y agoRefactored the ugly JSX code to be neat JSX. function Component({ children }) { const { data, loading, error } = useGetMyData(); return ( <> {loading && <div>Loading...</div>} {error && <div className="red">{error.message}</div>} {!loading && !error && <> <div>Data:</div> <div className="green">{data}</div> {children} </>} </> ); } > However, HTML is too declarative of an S-expression to be efficient in constructing the DOM. This is statement is also stinking. HTML is meant to describe the DOM and does a great job at it.
- rjerue 5y agoThe example is meant to be largely trivial. What if there were 50 cases I wanted to render. On another note, I'd suggest ternaries with explicit null returns. Just need to get burned by it once to have it engrained! https://kentcdodds.com/blog/use-ternaries-rather-than-and-and-in-jsx https://kentcdodds.com/blog/use-ternaries-rather-than-and-an...
- tiborsaas 5y agoMy point was that the author could have presented a much better JSX code for better comparison. I assume it's not intentionally made worse to make the Clojure version look simpler and better, but it felt like a TV shop commercial with the black and white "lame people" :) What ifs are what ifs ;) Fair point on the ternaries, I use that too when it makes sense.
- rjerue 5y agoWow, idk if I should be honored or ashamed. Lots of great discussion/things for me to think about! Thank you for that . I made a HN account just for this, want to make a few things clear. - I'm new to Clojure, but did a lot for my formative work in Scala, and employed a pretty functional model using JS. - While I really enjoy Clojure, I'll admit that JS is still my muse; it's the language that I dream in. React is the mental model I use to think of UIs. A perhaps naive summary may be that I'd give is what partly motivated me to write this is that JS and React are star crossed lovers. JS is by no means perfect, and I'd love to see it grow. - I've been following elm for a while. It was after I met Jesse Tomchak from https://player.fm/series/javascript-to-elm https://player.fm/series/javascript-to-elm at a conference a few years back that I started reading about it. When I tried it, the tooling wasn't quite where I wanted it yet and I'm a guilty of being a tooling primadonna. - When I say I used JS, I really mean I used TS too! Speaking of being a tooling primadonna, VSCode's TS interop was a thing of beauty. Yes, it's 100% easier up front to look at a TS type and see what's going on compared to spec. I miss types. I think Clojure needs more in spec and for a large part, it continues to be neglected by the Clojure team. Spec vs. Types could be a whole essay/talk on itself. - This isn't a call to action to use ClojureScript or Clojure. It's my critique of what I was using for years (and still will continue to use). Use what tools you feel most confident in to solve the problem in front of you.