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

Over on Slack, someone posted in #jobs a that “We have developed a version of our app in Elm and want to change the framework to React to take the app to the next level.” This prompted a really long and interesting discussion of reasons that people have been forced (typically by management, rather than technology) to rewrite Elm code as something non-Elm. I’m opening this thread here to provide a place to capture those stories in a more permanent medium than Slack. (I’m not going to start by transcribing everyone’s comments from Slack – that wouldn’t feel right – but hoping we’ll catch the same stories and more over here.)

7 Likes

(To be clear, the goal here is to identify organizational motivations/pathologies that cause organizations to decide to move off of Elm, not to pick on Elm.)

2 Likes

(Oh yeah, and to provide a cathartic outlet for the victims.)

2 Likes

Once I developed a dashboard in elm-spa / elm-ui. It was very fast, in 3 days I done it. The technology choice was free, but then the manager said that the sales department sold it as a react app and he forgot to tell me, and I needed to redo, it took me 7 days plus 1 extra day some time later to fix some bugs. There is also the time to create new features and to maintain that another employee will have in the future, with Elm it could be much easier. That’s my experience with it.

14 Likes

At my previous job, we got together a cross-functional team to design, build and deliver a project. The team was me as the front end engineer, a full stack engineer, a data-scientist/project lead, and a part time GIS expert. I was a reasonably seasoned Elm developer and the fullstack engineer was quite keen to learn, the other two had no opinion so we built the front end in Elm. This was both super fun and quite productive.

The project wasn’t huge, but there were 2 interesting technical challenges:

  1. Mapping and heavy duty geospatial visualization. gampleman/elm-mapbox was born of this. On the backend we used Postgress with PostGIS (these are really amazing BTW)
  2. i18n. We used a i18n service to do the translations, then used a build time script to generate Elm modules, so we had a different script for each locale. As the project needed only 2 locales, this was pretty manageable. The backend then dynamically served the correct bundle to each client.

After the first phase of the project, the project was put on hold for a bit, and all the other team members eventually left the company. The project went on with a v2, survived a ton of churn, scope changes, politics (literally in this case) and delays. Nonetheless, we shipped a successful version.

At this point, we had hired some new people. At this point the company had 2 senior front-end engineers, 1 graduate developer, 0 full stack and 1 senior backend engineers. We focused for about 6 months on a different React based project. Nonetheless, the other front-end engineer refused to learn Elm. He simply didn’t believe that it had any career potential for him and wanted to focus on other stuff. While the graduate developer might have been interested, he was simply too busy trying to get his head around all the stuff in the React ecosystem.

So when I handed in my notice (with a 1 month notice period), my manager told me that I will spend my notice period rewriting this project into React. As you may imagine, this was not really what I was hoping to spend my time doing.

On the plus side, Elm -> React+Redux is a pretty straightforward porting job, as many of the concepts are very similar. The main thing I was missing was probably Elm-UI, as there doesn’t seem to be a great alternative.

On the negative side, the asset size ballooned. Performance was not great either. The code, despite being a clean rewrite wasn’t any better, rather some of the nice guarantees of the Elm code were completely lost in translation.

For me this was a pretty disappointing experience and I wonder if we need something like “How to use Elm at Work”: “How to make sure they stick to Elm after I leave?”.

18 Likes

I experienced a couple Elm projects that eventually were rewritten in other languages.

Even though it is a minority, as we have several projects now in Elm, I was puzzled about why this happened.

I guess there were multiple factors but the common denominator was about individuals that battled on a daily basis against Elm instead of feeling empowered. They learned the syntax but struggled with concepts like purity and immutability.

Complains were trivial. I remember things like “Why have to be so difficult to get the time?” or “Why are we using Elm while it is still in version 0.x?”. Or something like “I want to become very good at React”.

In my experience these individuals also tended to have strong personalities used to convince people around them. Also for some coincidence, all of them left the company shortly after. This is an anecdotal, but interesting coincidence to me.

Some other time Elm clicked perfectly. For example we had an Intern that was able to learn Elm and write better code than most of us. He ended up crafting a nice piece of code that, unfortunately, is among the projects that was eventually converted to typescript after he left.

What makes some people to love Elm and others to struggle?

14 Likes

I’m working in team that does back office apps for my company. We tried Elm and wrote few apps but now we advice against using it.

It boils down to the fact that Elm is a middle ground between typescript and advanced functional language and we don’t get much benefit from this.

On the one hand it is really difficult to create composable and reusable library of widgets. Anything interactive leads to a lot of boilerplate and weird patterns. And to be honest, Typescript type system is enough for widget library. We still don’t get runtime errors. Reported errors are mostly about rendering and here Elm also does not help.

On the other hand, Elm type system is limited and we can’t express our domain through it. Our apps deal with complex information and we’d like to have more tools at our disposal than records and tagged sums. We’d like to enforce laws and relations between data, even if we need to pay with steeper learning curve.

Few months ago, when we decided that pure Elm is not a viable solution (due to it’s focus on purity and lack of FFI, which we understand) we decided to test three approaches:

  1. Elm + WebComponents
  2. Reason for logic and React-Typescript components through genType
  3. Reason with ReasonReact for components

We ruled out first variant, because it brings us very little. If we start using a lot of web components we’re losing Elm guarantees. WebComponents are transparent for Elm and “string typed”.

But we also have team focused on marketing pages and they are very pleased with Elm + WebComponents approach. Domain logic is not very complicated there and shelf time is shorter.

3 Likes

On the other hand, Elm type system is limited and we can’t express our domain through it. Our apps deal with complex information and we’d like to have more tools at our disposal than records and tagged sums. We’d like to enforce laws and relations between data, even if we need to pay with steeper learning curve.

  1. I am curios what kind of things Elm cannot express about your domain. Is it things like dependent types?
  2. What tools does TS give you that Elm does not in modelling data?

I am asking this because I have always, with no exception, found it much simpler and practical to model complex models in Elm rather than TS. So much so that I often start to model something in Elm only to get clarity on how to properly do it in TS, and this often requires a bunch of helper types/libraries to do right.

To tie it back to the thread’s topic, if it happens that the project I work on moves away from Elm, I could not see how data modelling is the reason for that. I am curious to learn how that happened to you.

12 Likes

Management. I spied an interesting twitter clip of Steve Jobs talking about how companies reward Sales/Marketing at the expense of Product people till the company is guided by people who have no idea what makes a successful product let alone how to built a product.

This "Institutional Product Rot” leads to poor decisions. A Summary is on twitter [0] but I found the original full length interview , “Steve Jobs Lost 1995 Interview” [1]

[0] “Jobs explaining Management/Sales & Markeing who don’t understand how to build Products” https://twitter.com/mikeabbink/status/1315876303455870978

[1] "Steve Jobs Lost 1995 Interview” https://www.youtube.com/watch?v=thxg1-iLRT8

2 Likes

This is a very interesting discussion.

I have used Elm in my previous and now at my current company. When I joined the company, out of 8 devs only me who was really into Elm. There were a couple of devs who didn’t mind doing Elm, but there were who would never do it. Through 4 years of elm experience in two different companies, here are the main reasons why people would migrate from Elm:

  1. Most people can grasp functional programming concepts, but what they are struggling is the application of those concepts to the UI. For example, TEA architecture is simple, but when you have to make a component library using this architecture, then they just can’t figure out how to do it. I have seen so many weirds patterns, which just makes codebase unmaintainable and pain to work with.

  2. Elm allows using of imperative programming concepts such as let statements. Devs from imperative programming background they really love let clauses. This antipattern is so annoying. It allows for creating huge functions. I have seen a function of 1000s of lines. Eventually, I ended up writing elm-review rule for not allowing let clauses at all.

  3. Not following good programming practices, like reusability, modularity, testing and so on. People are just happy that after one day of struggling with the simple task to implement a button it actually works. They won’t spend another 3 days to abstract that button, write tests, maybe even put in the library. Unless someone will force them. This makes codebase even worse.

  4. The more dev is experienced the more likely he will use known, easy and quick plug&play solution. Elm is the opposite from this perspective.

So in conclusion. There are not many people who would try to learn Elm in the first place. Those who are willing, they either:

  1. Afraid to push Elm through the chain of command.
  2. Those who adopt, they fail due to lack of knowledge.
  3. The main Elm dev leaves the company, and there is no one to take it over.

You can reduce migration away from Elm, by writing tons of documentation, setting right tooling, using CI, introducing Elm gradually to your peers, after a while, they will start to see how easily you are managing thousands of lines of front end code. Then they start to trust Elm as a good solution, and won’t abandon after you leave the company.

7 Likes

let is of course, not imperative in elm, it is an expression that evaluates to a value. Do you mean that the antipattern created had to do with many untyped functions inside let?

For example, TEA architecture is simple, but when you have to make a component library using this architecture, then they just can’t figure out how to do it. I have seen so many weirds patterns, which just makes codebase unmaintainable and pain to work with.

I think this is one of the most underestimated challenges in elm.
I have watched many talks and read about how one should change his “component” mindset to something else, to collections of functions. And many times, with the help of good examples I thought I grasped it. But after years of elm, I am still unsure how to make something of good quality that serves the purpose of a component library. Even if it isn’t true, React still feels ideal for building a set of UI tools. With elm maybe there is no one pattern, which is alright, but one has to deal with this when selling elm to any team that is looking for “component” patterns.
I have found this very difficult to do.

2 Likes

Do you mean that the antipattern created had to do with many untyped functions inside

Untyped functions add some weight to the problem but is not the main issue.

let clause allows an imperative way to structure an application. In Java let’s say you define variables and then use them. Here we doing very similar. Although let clauses are expressions and you can define functions which accepts some arguments, most often you don’t do it. Instead, you are using parameters which comes from upper-level function.

Then, the next function you will put inside the let clause as well, cause it depends on the value of that previous function, and so on. Leave out function signatures, and your code literally will look like imperative statements.

These functions are very hard to test, reuse, refactor, read and maintain.

1 Like

By “express” I meant “express in specific style”. Of course it’s still a complete language and I should not use word “cannot” - you of course can, but you need to sacrifice style.

But to be specific - I find Elm lacking with handling polymorphism. For example we’d like to have structures with functions that operate on them, but elements of these structures should be polymorphic.

Typeclasses and/or Modules also provide tools for late polymorphism, where you can define some type behaviour later.

We also model a lot of flows in our apps (think about document flow in organisation) and GADTs are very useful for this.

I didn’t compare TS and Elm in this regard. We use TS for our UI and if somebody wants to still work with javascript libs or idioms, TS is unmatched here. TS tries to be subset of javascript and obey by its laws and best practices. Elm and TS are different tools with different goals.

1 Like

I am curious about this, if Elm did not fit your needs here, what did you use instead that did?

Also, what is the domain we are talking about here?

Our recommendation in the team is Reason right now. We also used and allow Purescript for new projects.

Our domain is mostly legal/compliance flows. Think about legal entities and documents in multiple versions and multiple version of schemas and our app transforms it between them - one employee publishes document that should be compliant with one regulation, then another changes it to make it compliant with another schema and make it pending for review in different department …

I get that Purescript is Haskell so has a more powerful type system than Elm. Its been a while since I used OCaml (20 years), what does Reason have modelling wise over Elm? Is the extensible union types? Or the module system perhaps?

1 Like

GADTs and polymorphic variants open a lot of possibilities for us. Also module system is more powerful (really, modules are different thing in OCaml and name is rather poor).

We use GADTs to express flows as data structures and interpreters for them.

Module system helps with parsers and writing isomorphisms for schemas (functions that convert between complex data structures) - we can extend more basic types with implementations so bigger isos/parsers compose better.

Polymorphic variants are mote like a nice tool here and there - they change nothing in big way, but are quite useful for pseudo row types. This is more like stylistic choice and to be honest, we find Elm extensible records good fit for the same use cases.

Also, please note that our recommendations are taking into consideration multiple factors. We chose Reason not only because of “more powerful” type system but also due to genType, interoperability, community and tooling. It is just a result of specific needs.

2 Likes

I posted in that slack thread. I’ll post here too.

A while back, I joined a company who’s plan was that everything new was going to be Elm, and my team was beginning an important new Elm project for the company. The company had three teams of 6 developers, and each team had 3 frontend devs. Eventually, by time 50% of the front end code was in Elm, the company made the decision that Elm was cancelled, and nothing new would be made in Elm. It was around that time that I quit, which coincided with a lot of other people quitting (for various reasons not related to Elm).

During my time there, I took an Elm project from nothing to completion in about 7 months. And I am very happy to say it is still maintained and in production! Thousands of people are still using it every day. Even though the company gave up on Elm, it seems Elm did not give up on the company :tada: .

Here are some details about the company dropping Elm.

A lot of our Elm developers didnt want to be Elm developers in the first place.

I joined the company to write Elm. A few others were really excited about Elm. But many didnt even know what Elm was when they were told their projects were to be written in Elm. Developers reacted in different ways. One quit, thinking that Elm was a big waste of time in his career. Lots of developers tried it out with at least some hating it, but most being ambivalent. I think “Its nice, but I am faster in React” was a common conclusion among those who were indifferent. The breakdown was roughly 35% Elm-lovers, 50% neutral, 15% Elm-haters.

Lesson Learned

These kinds of technical decisions need to be made “ground-up”. The odds that any random programmer is going to be excited about Elm after learning about it are low (which is the case for any technology) and programmers are more affected by these technical decisions than anyone else- even customers. So programmers are the stakeholder that is the most relevant to these decisions. If you want to become an “Elm company” you first need a lot of developers and teams who are interested in Elm. If you dont have that first step out of the way then you really just cant become an “Elm Company” without making a huge gamble that many people wont share your enthusiasm and thereafter dislike their job. Elm is not so amazingly good that you can just count on everyone loving it when they get exposed to it.

I was not allowed to help Elm newcomers

Since we had a lot of people who didnt know Elm very well, and I often felt like “the Elm guy”. I spent a lot of time reviewing PRs and coming over to people’s desks to help them out. At some point, management made a judgement that teams were not closely integrated enough. They felt that there was too much communication between frontend people on different teams, and not enough communication between frontend and backend people on the same team. Therefore, people like me were supposed to stop helping frontend people on different teams as I was.

The consequence of this, I think, was there there were some teams that had no Elm expertise, only mild Elm enthusiasm, and no in-house Elm support; and they were nonetheless supposed to be writing projects in Elm. Not very promising conditions.

Lesson Learned

Within companies, there develop natural communication networks. Some coworkers communicate with each other every day, others never communicate. My company reasoned “we need communication to follow the existing teams, therefore, we will mandate that that exact communication pattern”, but it really doesnt work like that. I think how people self-organize is a little bit more like an immutable law of the universe and less like a thing that can be dictated into existence. In practice, people communicate with who they need to communicate with; issues with shyness or confrontation aside. Management is also not omniscient; they dont fully understand the communication patterns inside their company. Therefore, management should be a little bit “laissez-faire” about teams: observe who communicates with who, and then draw team-boundaries around those natural communication clusters.

Elm arguments got really really tiresome

The road of project development is bumpy, and Elm was a younger language back then with more open questions about how this or that problem should be solved. In our company, there were always at least a few people who really didnt like Elm, and whenever we hit a snag, there was always someone to say something like “In React this is just…”, spawning a new discussion about whether Elm was fundamentally good or bad. I love these discussions and arguments recreationally in my own time, but on the job its a real drag. Development stops when fundamental arguments about technology are opened up. It got worse and worse over time. Difficulties with upgrading to the then-upcoming 0.19 release added fuel on that fire. Our CTO “switched sides” and lost his love for Elm, and kind of became an agitator himself in these arguments. I remember feeling like “I wish I could have spent this time solving the problem, rather than defending Elm in an argument. I could have just solved the problem, regardless to if they are ultimately right that its easier in React”.

Lesson Learned

You really should keep your eye on the prize at work: getting projects done. Your company has to pick which technology to use, and you have some choice in what kinds of companies you want to work at, but outside of that, if you just wanted to get projects done, why would you be wondering which technology to pick?

I have adopted a few morals about how to get past tech disagreements. One is “code is worth a thousand words”. If you have a tech disagreement, one or both sides of the disagreement should go off for a day and write up the best demonstration of their opinion so everyone can see it shine. Another is “let people be wrong”; just letting an opinion play out naturally is often the most cost-efficient way of getting better opinions. Putting an opinion into practice creates the best evidence that that opinion is good and the quality of this evidence is often so good that it is worth the risk of having to refactor or re-do the code later. If you trust your coworkers, you should expect them to learn from good quality evidence in a positive direction.

34 Likes

Would you say that there were genuine technical problems in Elm that made developing this project difficult? Or would you say that any problems you hit were solvable in Elm quite easily?

Wow, thanks Chad for this write up. I think your summary is very accurate.
(Clarification: I used to work with Chad, at that company. Matter of fact, I was the one who hired him.)

Chad outlined things so greatly that I don’t even have much to add to the points he mentioned so well, but I can give a bit of my perspective on the matter:

The two years I was there for were marked by huge changes. Organizationally, staff-wise, technology and product-wise, and also strategically. I have never seen more people come and go in such a short period of time as at that company then.

Trying to create some stability for the frontend team in an environment when everything changed daily, we took the opportunity to write lots of Elm code in our newly created microfrontend architecture. To me the most important thing was teaching people Elm, which had varying levels of acceptance.

There were no solid arguments against Elm. They all pretty much boiled down to “I prefer React because I already know it” in various disguises and that is ok. Not everyone will agree on this. However, there was nothing technical in the Elm projects that would’ve forced anyone to not use Elm. In fact Elm was great for stability, asset size and (if people had learned enough) development speed.

However, like Chad said, high acceptance for Elm and helping others learn would have been hugely important. It sounds strange when you read “I was not allowed to help others” but there were forces in that companies that were very political and I would there was quite some back-stabbing behavior going on. In hindsight I should’ve been more outspoken against those forces, but at the time I was honestly not 100% clear on the depth of those actions.

Anyway, I agree with Chad that everything stands and falls with having people that are interested in Elm. Unfortunately, the people who are not often have reasons that tends to convice management more (React is stable, backed by Facebook, enterprise, yadadad) :slight_smile:

8 Likes