Live data from Hacker News

A Farewell to FRP

elm-lang.org

61–70 of 246 posts

Re: A Farewell to FRP

#61
post #52

I moved from React/Redux/Typescript to Elm a few months ago, and I'm now on my second serious project with it, making mobile application with Cordova. I've found it an absolute pleasure to use, and I especially like that you can be pragmatic about it; if there is something that is annoying to do in Elm then you can simply drop into Javascript/Typescript using ports. Coming from languages like Actionscript/Javascript/…

"if it compiles, then it just seems to work" Man, now that is tempting. Also, how easy are the ports? In ClojureScript you can use JavaScript pretty directly, but I often got a bit hung up translating the syntax (it's not that hard, it was just me).

I've never used ClojureScript so I can't speak for that, but the ports are now a lot easier in 0.17 as an outgoing port is simply a function that you can call, instead of messing about with Signals. Effectively, you send stuff to Javascript by calling the port function with a Javascript compatible value, and then you subscribe to messages on the way back in, which end up triggering a message on the update function of whatever component sent it out in the first place.

TL;DR its pretty easy once you've done it a few times

Re: A Farewell to FRP

#62
post #52

I moved from React/Redux/Typescript to Elm a few months ago, and I'm now on my second serious project with it, making mobile application with Cordova. I've found it an absolute pleasure to use, and I especially like that you can be pragmatic about it; if there is something that is annoying to do in Elm then you can simply drop into Javascript/Typescript using ports. Coming from languages like Actionscript/Javascript/…

"if it compiles, then it just seems to work" Man, now that is tempting. Also, how easy are the ports? In ClojureScript you can use JavaScript pretty directly, but I often got a bit hung up translating the syntax (it's not that hard, it was just me).

Ports are essentially event emitters. You can expose them from elm, and in your JS code you attach event handlers to them using .onMessage (I think, been a while).

You can post and receive messages from ports (depending on type). Type checking is done at runtime to make sure nothing breaks.

Cljs interop is easier (can just call a function directly).

Re: A Farewell to FRP

#63

I haven't dabbled in Elm much, but subscriptions look a lot like ordinary JS event handlers: Time.every second Tick vs. Time.on('everySecond', tick) Beyond baking an event emitter into the Time module and having a nice looking API, is there something I'm missing?

They key difference is that when you create an event emitter in JS, you now have a resource to manage. Where does that go in your app? In each component? How does the component know how to turn these off if it is no longer in use? In the root? How does the root know who needs what? So basically, the difference is in resource management. The web socket example makes this clearer. You never have to ask "who owns the co…

> The web socket example makes this clearer. You never have to ask "who owns the connection?" to use the connection.

To be fair you can do this in javascript as well using a messaging pattern similar to elm. Many libraries like postal.js (synchronous) and msngr.js (asynchronous) support a messaging pattern where you can access resources without caring who owns them.

Re: A Farewell to FRP

#64
post #29

Just out of curiosity. I'm trying to decide which client-side framework/language to dive into, and it seems that many people consider Om Next a really nice step forward, away from "giant blob of state". My (uninformed) observation is that Elm does things the way Om (previous) did it: is that correct? Is Elm aiming to incorporate Om Next's advantages?

Elm does things the same way. However, PureScript has lenses so the same thing can be done if you're using the equivelant of Elm in purescript, purescript-pux

Re: A Farewell to FRP

#65
post #50

Earlier quoted context omitted.

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

Yeah, 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 Not to get off-topic though! I am used to work…

Elm incoperates CSS the same way Clojurescript and React incorporates CSS.

Re: A Farewell to FRP

#66
post #34

One thing I'm wondering with elm is how does it deal with state across different components? I.e. where would you put the settings of the current user and how would you access that within one component? (By component I mean the (init,update,view,subscription))

Another approach is to use extensible records, which give you structural typing similarly to Typescript. This means that you can pass the exact same state record/object around to different components, but a particular component might only specify that the state needs to have a `user` property, whereas another might only specify that the state needs to have a `friends` property.

Re: A Farewell to FRP

#67
post #29

Just out of curiosity. I'm trying to decide which client-side framework/language to dive into, and it seems that many people consider Om Next a really nice step forward, away from "giant blob of state". My (uninformed) observation is that Elm does things the way Om (previous) did it: is that correct? Is Elm aiming to incorporate Om Next's advantages?

> My (uninformed) observation is that Elm does things the way Om (previous) did it: is that correct?

It's not, Elm doesn't use cursors and transactional mutations, I'd say the Elm architecture is closer to a pure single-store Redux: user actions are dispatched as Sub Action which are run through an update reducer (Action -> Model -> Model), which is then run through the view (Model -> Html) resulting in the new UI state.

Re: A Farewell to FRP

#68
I got into studying FRP around 3 years ago for my senior project. Aside from a decent, clear explanation, there were hardly any actual implementations of this allegedly good paradigm (something Evan covered in his thesis, and the basis for Elm). It seemed like a paradigm that was full of promise and potential but failed to deliver in any worthwhile way.

(Such was the case for my senior project, studying the viability of Arrowized FRP in Elm. In short, I concluded that it was nothing but hell and nobody should bother.)

I am happy to seem Elm drop FRP, even if I wished it could be the savior of the method. At this point I think it's a troubled concept and should be limited to old theses.

Re: A Farewell to FRP

#69
Has anyone upgraded a non-trivial app from 0.16 to 0.17? Is it pretty simple to rewrite moving from Signals to Subscriptions? Any advice?

Re: A Farewell to FRP

#70
post #60
post #7

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…

Elm 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 li…

There'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.
Post reply on HN