6 ms·
This looks very cool. In ClojureScript, we have the re-frame pattern/framework, which is built on Reagent, which is a ClojureScript wrapper of React. re-frame
by timroy 10y ago
This looks very cool.
In ClojureScript, we have the re-frame pattern/framework, which is built on Reagent, which is a ClojureScript wrapper of React.
re-frame is all about subscriptions, using a "big atom" to hold application state client-side. Seeing Elm implement the same subscription pattern makes it look pretty tempting.
My understanding is that ClojureScript and Elm have some similarities - functional, pleasant to work with - with one significant difference being that Elm is typed.
- jiyinyiyong 10y agoMight be off topic but I was interested in the "a big atom". Reagent is using a big atom and some small atoms to simulate component state -- which breaks hot code swapping. And I tried a way to abstract out component states into a single atom to fix it by building my own React like library. Now it's "two big atoms" on my side.
- timroy 10y agoYeah, after the app grew a bit, I had state scattered here and there. re-frame solves this with a big atom, and avoids expensive rendering every time the big atom updates with subscriptions. Subscriptions hold reactions, which only update if the underlying value changes. The re-frame readme is epic and worth reading just for its own sake: https://github.com/Day8/re-frame https://github.com/Day8/re-frame Not to get off-topic though! I am used to working with dynamic languages, but I really should work with a typed language. Elm looks like it offers many of the benefits of ClojureScript, but with typing as well. Also, ClojureScript lets you write HTML and CSS in your code, but a quick web search indicates Elm may have gone further with incorporating CSS (?).
- Skinney 10y agoElm incoperates CSS the same way Clojurescript and React incorporates CSS.
- timroy 10y agoThanks, good to know.
- pseudonom- 10y agoCan you talk a little more about your thoughts on one big atom? I've been looking at Redux and they also seem to follow this approach. The re-frame readme quotes the Elm Architecture as justification, but that same document goes on to describe nesting https://gist.github.com/evancz/2b2ba366cae1887fe621#nesting https://gist.github.com/evancz/2b2ba366cae1887fe621#nesting. I come from a Haskell perspective and having one big blob of state sounds to me like it makes your type signatures less informative and increases the scope for error.
- timroy 10y agoSo, the one big atom solved two problems for me. First, in Reagent/FRP, I was updating a view based on the value of an atom. This meant I had different default values in different atoms. The big atom let me unify where I stored values, and reuse values, without a performance hit. Second, the big atom made storing application state trivial: you can just throw the map/record in Redis or something. However, the big atom is just a big map, and keys can be paired with any value, so it is not enforcing types. From a Haskell perspective (where I understand the program almost falls out of the types you define!), this probably does increase the scope for error. This can be mitigated with Schema (which I never used effectively), logging changes to the console, and being able to see your default map easily (like, there's a map in one file which I load upfront, so I can see what values are there). I'd welcome hearing from anyone with a more advanced or precise use of re-frame state.
- hkjgkjy 10y agoElm is typed, Clojurescript is homoiconic. 2 great features. Wondering if you could make a lisp where `lambda` or `fn` required type annotations, such as (defn add [int -> int -> int] ;; type annotation [x y] ;; arguments list (+ x y)) Then it would be homoiconic - something that has saved me hundreds of lines of code (and the less code, the less bugs as a rule of thumb). Then every function down to the very basic lisp functions would have types. Dunno how doable this is - but it doesnt matter. Someone implemented it in Common Lisp in the 80s I'm sure.
- masklinn 10y agoThere's Typed Racket and Clojure's Core.Typed. In Common Lisp you can `declaim`/`declare` attributes to functions and values, and many implementations allow `declaim`-ing types. It's also common for them to propagate and check type assertions at compile-time e.g. (defun foo (bar) (if (numberp bar) (car bar) x)) should error out in SBCL because BAR is a number but CAR takes values.
- hencq 10y agoThere's Typed Racket [1] and for Clojure there's core.typed [2]which do pretty much that. For Clojure there's also Schema [3], which is a bit lighter weight (it's not a full type system), but still gets you some of the benefits like validation and documentation. [1] https://docs.racket-lang.org/ts-guide/ https://docs.racket-lang.org/ts-guide/ [2] https://github.com/clojure/core.typed https://github.com/clojure/core.typed [3] https://github.com/plumatic/schema https://github.com/plumatic/schema
- hkjgkjy 10y agoNeither fit the bill though - because not every function ever written in the language is annotated. To be nice to use, it should be an all-or-nothing affair. I say this as a huge clojure fan - my clojure programs with dynamic types work great. I rely on predicates (functions ending in -?) in I/O, otherwise I'm sure things work.
- 10y ago
- Morgawr 10y agoI personally use ClojureScript with type annotations from Plumatic (former Prismatic) Schema and it works really well. Obviously it's not the same as an actual typed language, but it gives me a good-enough starting point to leverage some typing information and perform some rudimentary (runtime) type checking. I also feel it's really nice as some kind of "inline documentation" to be able to see the type of your parameters (obviously this is a given benefit for statically/explicitly typed languages).
- timroy 10y agoI have heard only good things about Schema, and I probably should have invested the time to understand and use it more intensively.
- Reefersleep 10y agoJust dive into it. After wanting to be a bit more descriptive and assertive about the input and output of certain functions in some code I was writing, I must have spent all of half an hour reading documentation and successfully adding Schema to my code. Might be a bit of a rose-tinted memory here in respect to the pastimate :) But it certainly is both easy to understand and use.