Elm 0.19 was released yesterday. There were a significant number of breaking changes at every level: configuration, tooling, library, language. But those are not what this post is primarily about (edit: and Elm provides an upgrade tool to autofix many of these things). For my team, this release broke our hearts.

Two changes that placed the proverbial "straw that broke the camel's back": Removal of custom operators and native modules. At first I only saw the removal of custom operators, and I posted my reaction to that here. The removal of native modules was not mentioned in the 0.19 release notes so I didn't find out about it until today. I just happened to think of it, and a search turned up this post.

The post on native modules was back in March, so how did I not know about it?

Community

I disconnected from participating in the Elm community a little while back. I didn't say much about it at the time, but I'll share the reasons. I love the Elm platform and use it, but decided that the way the community is managed is too frustrating. The tone is firmly set by the way the Elm Github issues are managed. Many of them are locked to prevent disagreeable feedback, or because they are personal items only for the blessed few contributors, even though they are in public. If you post an issue, you are likely to get smacked on the hand for not doing things "properly". Properly means a rigorous SSCCE for bugs, or participating in the gladiator arena of public forums for ideas/requests/suggestions, or you can forget both of those things if you went the extra, extra miles to be trusted as a contributor. I say gladiator arena, but the Elm community is really very nice in general, especially for helping newcomers. However there are more than a few people who have their rulers out and ready to smack that hand to enforce whatever Evan (the creator of Elm) has said or not said. So chances are high that posting "ideas" or "feedback" on the forum will result in being chided. This, in turn, justifies that there was no "agreement" on your post among the community so it can be ignored. So the "go post on the forum first" rule is an effective way to ignore feedback.

Apparently since Elm forums have moved to (edit: Reddit and) Discourse, threads there can be locked too. When mods know Evan doesn't want to hear your disagreement on a particular issue, they may preemptively lock posts where it might surface. In the end, it feels like the D in BDFL is taken a little too seriously over there. So I appreciated the product but mostly stayed away from the community, and didn't happen to catch the posts telegraphing changes.

To be fair, I did have a bad experience myself, and have fault in that. But I have observed this pattern of unwelcomeness in Elm's old github and google group many times as an onlooker. And it isn't this way in other projects I've worked with.

Control

The removal of custom operators was ostensibly for the good of Elm. However, in the post explaining the reasoning behind their removal, an estimated 5% of users have them. And several of the reasons for using them are in common with other languages (task chaining, parsing). In the end, specific custom operators were blessed by Evan and were allowed to remain as exceptions to the rule. But whatever ordinary Elm users think is a valid custom operator for their use cases is "bad" for Elm. Okay...

Theoretically I can still inject native modules through monkey patching in 0.19. (Javascript, right!) However with dead code elimination, monkey patching could be a bit difficult unless you turn off optimizations. But the real kicker is that native modules are still there. They are just reserved for a few Elm contributors only. The rest of us should not have access to this expert feature. Apparently the 40 total lines of native code that I use will completely break the Elm community. Even though there is no other reasonable way to do what I need. Okay...

Minor but indicative: Evan has posted many times telling users to change the way they talk or think about Elm. (Fair point: he's nice about it and there are valid points. But still... indicative.) Examples: Don't use the word Components. Don't say "native"; say "kernel" instead. Union types should now be called Custom Types. But don't you dare respond to one of his posts -- there is always a closing section instructing you of the only few acceptable replies or to just not reply at all. Okay...

Considering all of the above, a picture is forming for us: we can expect to be overbearingly micromanaged as Elm users. And feedback (well, disagreement) is not welcome or considered even when it is decisive and voluminous, like on native modules. Evan decides he just doesn't like something he sees Elm users doing (even if it has credibility from similar languages, like custom operators), it gets disabled in the next release. My way or the highway. Despite all the amazing things Elm has been to us, that's intense behavior for a toolchain. And not really a situation my team wants to be in.

What now?

The way I see it, we have a few options.

Keep using 0.18

I have not had any major issues with 0.18. We could avoid the broken things that have been pointed out in the changelog (like Arrays). However, this is not a long term strategy. It seems unlikely that 0.18 will ever see another bugfix. Old versions of tools (like Create Elm App) eventually stop being maintained. Meanwhile Computer Science and the web advances on.

Monkey patch 0.19

Because of the dead code elimination, putting the formerly "native" code in through monkey patching has some unknowns. But the deeper issue is that by moving to 0.19 we are still in a place of feeling unstable with the future of our toolchain.

Wait for an Elm fork

Lots of tree names are probably still available (i.e. acacia, poplar, etc). Unfortunately we do not have the resources to maintain a fork. But it seems likely that somebody will draw similar conclusions to us and be in a place where they want to create one. Even then, this path has a lot of unknowns.

Wait for Elm to solidify

Most projects reach a phase where they solidify. Meaning there is some effort to maintain backward compatibility. If Elm decides to do this at some point, we could evaluate where the latest version is. Maybe by then there legitimately won't be a need to have the freedoms which were taken away, so it will be a moot issue. However, probably as long as Encoders and Decoders are the only official way to deal with JSON, we will need native code. 20 lines of native code saves us hundreds of lines of encoders and decoders.

Switch to something else

The only other Model-View-Update platform I'm aware of is Fable-Elmish. It uses F#, which we already use for APIs anyway. The unfortunate bit about that is that F# is not a pure language. So it takes discipline to write pure functions. Whereas Elm has been taking purity too far with some of these recent changes, F# is not quite far enough IMO for the front end. But F# is great for APIs since they are about integrating external systems (e.g. UI, database, email, files, etc). F# would be harder to use there if it had a lot of overhead to perform side effects. Striking the right balance for the use case is important. Anyway, it is still an option on the table.

There could also arise an alternative MVU platform at some point. I believe ClojureScript has a library which works similar to MVU. I don't really want to go back to a component-based system. (Yes, pure function MVU is that good.)

Conclusion

The team has all agreed that sticking with 0.18 is the best choice for us right now. We have some apps coming up that we will create with 0.18, ignoring 0.19. We will experiment with Fable. We will see if another MVU style platform is around. Eventually 0.18 will start to rot and we will need to switch to something else going forward.

We find this situation really disheartening. We love Elm and never wanted to use anything else. But we have begun to feel that our relationship with Elm is unstable. 💔