Are those downsides still valid today?

I like ELM and want to use it in real project. As a seasoned and practical developer(around 20yrs), I love to look for negative points before introducing new technolgy into my work, since these points give me more angles to look at the technology. Then I found this post saying Elm is not ready yet.

Since I’m new to ELM and cannot thoroughly evaluate these points, I come here for opinion from ELM veterans.

BTW, I don’t believe there are any hard drawback in ELM. I think points in that post may more or less due to personal programming philosophy which is not go align with that of ELM which I love(Pure FP, Clearly controled external interact, etc). But still, I want hear feedback on that for a thorough understanding before I put ELM in my real product.

5 Likes

Elm is designed beautifully for its intended usecases. If you have a project, where the use fits elms strengths, and the project constraints aren’t in conflict with what elm supports. Use it! It’s unreal how good elm is at what it’s trying to do.

Requires a build process
Requires client side rendering
Requires learning elm (is your team willing to?)
Doesn’t allow shortcuts or hacks.
No real serverside support.

You could find work arounds for the above constraints, but elm thrives BECAUSE of its constraints. Everything is predictable in an elm codebase. It’s incredible to be able to open any elm project and understand what’s going on.

I’d recommend elm for web apps, and generally advise against using elm for content sites. Elm-pages and elm spa has done good work making content sites more friendly, but elm is naturally incredible at building web apps.

Check you can do everything you want in elm before getting started. Websockets, media, manipulating the dom elm controls, css variables defined on style attributes, and a few other gotchas can be painful. But if you’re building a web app that deals with large or complex data structures, elm is very nice to work with. The syntax is something I miss daily working with js.

Frankly I’d start with the hardest part of your project. You’ll see where elm thrives. The compiler will help keep your logic straight as it becomes more complex, and the slack channel generally has a bunch of helpful people fielding questions.

I fell in love with elm after having the hardest time building something in js as a side project for 2 months and getting a working prototype working in elm in 2 days.

It’s a very cool language which you’ll certainly love learning. You’ll find its strengths and weaknesses as you go, and you can choose how much or little elm to use for your project.

Welcome to the elm community!

6 Likes

Debugging looks awful and is largely unhelpful

Still the case, though if you do it right, it’s just as in every other language

Js

x = 1; y = 0;

fun1(x); //changes both x and y
Console.log("x", x);
fun2(y,x); //changes both x and y
Console.log("y", y);

Elm

{-| This example showcases how you would simulate mutable data.
This is NOT the default way how you would program in elm.
-}
{x = 1,y = 2}
|> (\model -> 
    { model
    | x = fun1 model.x |> Debug.log "x"
    }
  )
|> (\model -> fun2 model.x model.y)
|>(\model ->
  let
    --This is a nice way to quickly print something
    _ = Debug.log "y" model.y
  in
  model
  )

You cannot install Elm packages from anywhere other than the official package repository.

You can clone a package and then add the path to your elm.json file. But this was always the case.

Most of the tutorials / examples online are out of date due to v0.19

Nope. Personally I like to point people towards Beginning Elm for a good introduction to Elm. And from there you will find lots of other tutorials.

The docs are incomplete

Sadly yes. There is still an example at the end of the official Guide that’s just a “Todo”. Here is a blog post discussing the missing example.

Elm core development lives in a walled garden that you can’t touch, even if you wanted to

True. Here is a post by evan about it:

Pull requests being open for 2+ years

Still true. Here’s an official response. TLTR: It’s intended.

Runtime errors can happen

True. But not the way described in the blog post. If you use Elm each day, expect to get maybe one runtime error every year or so. Most of them are bugs and looking into the corresponding issue will give a fast fix for it. That said i would not know any of them of by heart.

Missing key features

At the time of writing, Elm has no implementation for server side rendering, web sockets or localStorage.

You can do a lot of things using Ports. There are some things that are definitely NOT to complicated for using Ports. But it those cases you should look into web components. If you find something that can’t be done using Ports or web components, it would be worth writing a blog post about it. It would definitely be interesting to read.

Lacks the ecosystem of its siblings

True. I’d say Elm as fewer packages then React (The community is also smaller) but the quality of the packages and specially the documentations is higher. That said you can use React and Elm together.

Also, as a side note: Elm Awesome is not the right places to find packages. Instead, use Elm Catalog

7 Likes

Are those downsides still valid today?

The short answer is yes, all the points that are mentioned in that article still hold to this day. Nothing has changed.

The long answer requires you to dig deeper into the language and see for yourself if it is worth for your goals. One thing that is very important to keep in mind is that Elm as a project is entirely rigid: if you find a point of friction it likely has no solution. Elm works very well but in only one way, and you either love it or you’re in for some pain in the long run.

1 Like

Largely solved now by elm-pages - its great, check it out.

3 Likes

I don’t share that sentiment: Just look at what Debug.log model looks like when using the Elm debug helper extension (on chromium browsers, on Firefox it unfortunately is not as nice)


Image source: Nicer Debug.log console output - #14 by kraklin

If someone is open to using a browser extension like redux devtools or react devtools, one could also use the Elm Debug Helper extension by @kraklin (on Firefox and Chromium browsers).

Even if that is not an option, you can still use it directly as an npm package or by adding it directly to your HTML in all other browsers.

<script src="https://unpkg.com/elm-debug-transformer@latest/dist/elm-console-debug.js"></script>
<script>ElmConsoleDebug.register()</script>

There is also a lot of information on an alternate approach in this discourse post, following into the (archived) github repo, you will find e.g. this meta-issue for a ton of great information that I have on my reading list for a long time…


About the Elm time-traveling debugger

I think following statement from the medium post is misleading:

There is an Elm debugger (imagine Redux devtools) but that doesn’t work for our app so we can’t use it — using certain message types (think of Redux actions if you’re from React-land) cause the debugger to throw up.

I have never seen events that caused the debugger to “throw up”. In my experience it renders deeply nested message structures with a lot of arguments just fine.

I assume that the writer has hacked their Elm runtime using undocumented APIs to run “native” (or “kernel” since August 2018 brought us elm 0.19) code in a dirty way. Most likely to use a browser API that is not available in Elm with an effect manager, and did a poor job at it. If his dirty hack had been a little better, he would also have been able to get useful output in the debugger.

There is also a direct question to the writer of the medium post about his debugger issues one day after he created it, and he has not replied yet so I would not give it too much thought.

But looking into this recent writeup about effect managers might still be worthwhile, which also references Platform.sendToApp and the following official Elm documentation:

An extremely tiny portion of library authors should ever write effect managers. Fundamentally, Elm needs maybe 10 of them total.

Using unsupported APIs like WebRTC or WebSockets with ports or custom elements works just fine for me (and many others), see e.g. the official guide or beginning elm.
At my main project at work we use a binary WebSocket protocol and WebRTC for conferencing and screen sharing.
It definitely requires more thought and synchronization than directly writing JS, and that might be a reason not to do it, but I would not consider it a blocker.


Going back to the debugger, a coworker wrote this about a week ago:

Folks, I noticed that it’s possible to re-establish a [failed WebRTC] connection using the Elm debugger, moving through messages, that’s cool :smile:

This is possible because when stepping through the list of messages in the debugger, not only the neat elm model changes are visible, but also the dirty side effects are executed. (And because we use a media server that accepts the same SDP offer/answer again from the browser, but that’s beside the point).


Using the debugger with many subscriptions

I understand that the time traveling debugger might seem to not be very usable when you have many subscriptions (e.g. 60fps for an animation or game), but when paired with one of these approaches, I think one can still use the debugger to find bugs or trace the behavior.

  1. Manually open the debugger and use the slider to go back in time - subscriptions and other messages are paused until manually pressing play.
  2. Add a button to stop subscriptions (many games will anyway need a “pause” button)
  3. Add a port to stop subscriptions, so you can use app.ports.pause.send(true); in the browser console and then pass false to enable it again.
  4. Change the update function to disable the subscriptions if an unexpected state has happened (I like this one best during development)

I wrote a small example in https://ellie-app.com/cm6CzRLJKk4a1 that shows them (and the simple output of the elm debug helper).

4 Likes

Hello! :sunny: That project was a lot of fun to work on. There was a couple of outcomes from it:

  1. @robin.heggelund added some of the performance-optimizations to the official debugger that I also used. @evancz gave that great advice on performance in the announcement-post you linked to.

  2. I explored a bunch of new features:

    • tracing message source (“initialization”, “subscription”, “update” or “view”?`)
    • expanding bug-reports with additional information
    • caching message-history in the browser, and how to think about read/write/compression-performance.
    • partial message-replay (the code is changed, so restore as much of the previous state as possible)
  3. I found myself mostly interested in the “automatic message-replay” feature of my debugger (as described by @rtfeldman here). I developed a module directly for that. It’s incredibly simple to do. Most of my time with this was spent using the module in one of my projects, where I tried to figure out what the developer-experience was like (The application was a PWA with authentication and FLAC audio-files playback. I have a lot to say about that, but probably shouldn’t here - In conclusion, it wasn’t as great as I had hoped for.

Ultimately, I’m not working on any of this anymore. If anyone is going to, I would love to contribute anything I can.

1 Like

Have you tried including functions in messages?

No I have not, @malaire.
I just now tried a simple

type Msg = Increment (Int -> Int -> Int)

in https://ellie-app.com/cmpb2mJZj2za1 and the output Increment <internals> does not look too bad to me. It does not print my partially applied function, but it also does not show an error or garbled text or something like this.

It looks like passing around a Json.Value.

image

Or am I missing something and it does get a lot worse for more complex messages?

The problem is that comparing functions causes runtime exception if functions are different. I havn’t tested when exactly this happens with debugger, but I’ve read that it can cause problems.

I’m wondering, is the debugger problem this one:

Not so much when the message gets more complicated, but when your model gets too big?

I’ll create one and a PR for this fix, as its a simple fix, and the code is in that discourse thread already.

I don’t find the time travelling debugger so useful. I used to use it more, so perhaps it serves its purpose as a learning tool? Or I have learned to know when it can be useful, and just Debug.log the rest of the time.

1 Like

Among your guys informative and wonderful replies please pardon me for inserting my useless thanks here ;-). I’ve read them all and come back now and than for new and inspiration on learning ELM!

3 Likes

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