Reasons that people were forced to move from Elm to something else?

For our use case, as we were thinking about it at the time, the “happy path” of an http request went like this:

  • make X request using token
  • request succeeds

The “unhappy path” seemed to be this:

  • make X request using token
  • X request fails
  • remember that we wanted to do an X request somehow and then do a Token request for a new token
  • Token request succeeds, save the new token in the Model
  • redo X request
  • X request succeeds

So our focus was on figuring out how to code this unhappy path scenario. But actually now I think thats not so fruitful. What is more fruitful is making sure you dont end up in the unhappy path to begin with.

What I have learned to do in Elm over the years, is that if these long and deep code paths, its way better to make sure you have that data you need at the very start, than it is to be in the middle of a deep code path and worry about if you have your data part way through.

So, learning that lesson, to avoid the unhappy path in the case of an api token, one should have some independent system which is continuously refreshing your api token in the background of your app. That way, whenever you do need to make a request, you can be fairly confident that the api token is indeed valid. Maybe if you know the token expires every hour, have an automated system request a new token every 45 minutes.

3 Likes

I had a similar situation but didn’t have some known period after which I knew the token would expire. So I had to handle expiry in the code. I ended up writing an Autoreauth module into which you could pass an HttpRequest or a SelectionSet (for GraphQL requests) and it would handle the reauthentication automatically. It converted the request to a Task then used Task.onError to trap the token expiry error, fetch a new token, then re-execute the original request. So we didn’t have to remember anywhere that we wanted to do some particular request. The result of that Autoreauth module was a tuple containing the result of the supplied HTTP/GraphQL request, and a Maybe containing the new token (if one had to be fetched). Then we just had to handle updating the model with the new token after every request.

4 Likes

Personally, I think this is misguided. I’ve been writing React on and off since around version 0.13 and the idea of what a “component” is has changed over and over. There are class components with state, pure functional components, and now hooks. Not to mention the at least 4+ 3rd party state libraries I can think of off hand. React makes claims of simplicity, but it really isn’t. Sure some people can pick it up fast, but others struggle to grasp it.

To your later points though, what React has that Elm doesn’t is hundreds of brief and many long tutorials about how to write React. Elm is a smaller community so there are fewer tutorials, fewer blog posts on patters.

10 Likes

That’s a fair reply. Maybe I should have mentioned that I started writing react right about when class components were fading out. In fact I’ve never written anything but functions. From my experience, what a component refers to today in React is fairly simple, but I see how that might not be true for those writing React for a long while.

In our project, we began with a backend in Elixir. We had planned to build the front end in Elm and use GraphQL to tie it all together, but our primary developer demonstrated that we would wind up re-inventing fewer wheels by going with Elixir LiveView instead.

So ultimately I think there is a value available in writing code for a single language that covers the entire stack, and where possible abstracts away the details that separate client and server.

I know that Lamdera was trying to offer something like this based upon Elm on both front and backend, and that sounds like the right kind of direction to explore from where I sit, but I wasn’t a big fan of what appeared to be a closed-source offering from them… eg, you’d be forced to host on their servers, could not inspect or alter server platform, etc.

2 Likes

LiveView is one of the only technologies I think might be able to win out over Elm for me for some projects. I think which one I would choose would depend a lot on the specifics and the complexity of the front-end behavior, but LiveView seems incredibly cool.

FYI: elm-mdc does the same. But we stopped using Int, IDs in the form of a String makes changing the UI easier, and can also be used as the HTML id attribute of the component.

1 Like

I recently tried to introduce Elm to a group of programmers who where back-enders and knew no JS at all. However, they thought React would be a better thing in their CV so we ended up with React.

The irony is that they leave most of the frontend stuff to me.

The experience is awful. You can not predict what is going to happen or in what form.

But to answer the OP. It was their CV.

8 Likes

I wonder why to limit this just to this sort of state. Why not to make all the element dimensions and and positions in window as well as position of scrollbars explicit? Perhaps even every pixel so anti-aliasing used for font rendering is explicit state. Of course this sounds ridiculous. The point is that views are not about describing the state of DOM. They are about describing some simpler abstract representation of DOM. In some cases where there are indeed problems - mostly media objects. But it’s not possible to make everything simply explicit - the whole advantage of abstract representation would be lost and you would find yourself writing your own rendering engine. Elm cares about values in inputs as much as it cares about position of scrollbar - not at all unless you hook into the event.

1 Like

Because the element dimensions and positions in the window are not state - they’re a function of css and html.
The same goes for font rendering anti-aliasing. It’s not state. The anti-aliasing is computed from the position.
It might be cached, but not actual state. So maybe there’s some opportunity to memoize it, but that doesn’t need a stateful API.

But yes, scrollbars are state and maybe it’d be nice if it were explicit. Do you really know how your container scrolls when you add some items to a list? E.g. if the user scrolled to the very bottom, does adding items keep the scrollbar at the bottom or does it keep its scroll position in pixels? Or in percent?
Wouldn’t it be easier to sync scrollbars for something like git-like views with two scrollable editors? Or when you’d have a markdown editor like the one I type in right now with a live preview?


I actually really like @eike’s thought and agree strongly with it. What is often overlooked is that the virtual dom does not only exist for performance: It is a layer hiding an impure API. And this hiding only has to be done, because we’re stuck with DOM in the browser and have no way to access all of the state behind it due to abstraction over browsers.
Personally, I’d love to see a functional UI framework without a virtual dom and with actual explicit state, just how you’d implement it in a functional language if you did that from scratch. And I’m actively trying to develop this.
Of course, doing something like this in elm would be horrible, as it’s not built to handle threading explicit state around that much, so it might need some language-level experimentation to find the best abstractions.

EDIT: Oh - and if it turns out that an abstraction over this state is indeed absolutely needed - then it’s possible to build a layer on top of this functional API which works like a virtual DOM. But that can just be a library on top.

2 Likes

Because the element dimensions and positions in the window are not state - they’re a function of css and html.

const $el = document.getElementById("test")
$el.offsetLeft // left offset is a state of DOM node
$el.offsetWidth // size too
$el.clientWidth // actually more size
window.getComputedStyle($el, null).getPropertyValue('font-family') // even the font face is

All of these are states to any program inspecting the DOM. All are observable by user (elements changing positions based on window size, input values changing…). All of these are also part of state of DOM but not necessarily of VDOM. I don’t know about any vdom implementation that would attempt to implicitly hook into DOM mutations. I think all implementations esentially work the other way - change in vdom is propagated to DOM but mutations of DOM aren’t reflected in VDOM. This can cause some problems (loosing state of audio/video elements etc) but I don’t think claiming that there is some state which is not reverentially transparent on the side of elm is not true because there is no such thing.

Personally, I’d love to see a functional UI framework without a virtual dom and with actual explicit state, just how you’d implement it in a functional language

Things to check:

1 Like

I think we’re derailing the thread a little. I’ll DM you on slack!

2 Likes

The mark that this misses for me is typings (and therefor help) same goes for F# which enables you to write F# in backend and in frontend. But as you can call C# from F#, you can end up with null etc.

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.