Hacker News new | past | comments | ask | show | jobs | submit login
Why I Use Elm in 2023 (taylor.town)
151 points by surprisetalk on May 23, 2023 | hide | past | favorite | 158 comments



> Languages like Go and Elm spurn extravagance. They resist overcomplication. They force me to solve real problems instead of fighting compiler errors and stylistic differences.

I hate this mindset. "<my favorite language> is used to solve REAL problems, other languages are not as good for creating VALUE. Any powerful language features, ergonomic syntactical sugar or tooling that does not exist in <my favorite language> is useless". So strange


I think you're just reading it as "Elm/Go good, $yourFavLang bad".

Maybe this makes more sense:

Coming from more expressive languages, one of the good things I could say about Go's developer UX is that you are so helpless to circlejerk over abstractions that there is simply nothing else to do than to write concrete code to solve the problem.

Elm is similar versus the huge type expressive power of Haskell. Elm's type system is so minimal compared to similar languages that you can't spend hours perfecting your higher kinded advanced type abstraction that perfectly annotates and cordons off the problem domain because there isn't enough typing power to do that. You have to go "welp, good enough" and move on.


> nothing else to do than to write concrete code to solve the problem

And by that you mean "invent ad-hoc code generators instead of using built-in language features from the 21st century", right?


Not to diss on Haskell, but to illustrate the difference: There's an entire HaskellX 2022 talk about "language extensions we use, extensions we are cautious about, extensions we never use". There are many ways to solve problems in Haskell; and mostly only one or two ways to do things in Elm. The most choice I can think of is in context of parent-child communication (Config pattern, OutMsg, flat Msg type). Most everything else has a single obvious solution.

Yes, sometimes the simplicity of the language leaves you wanting a bit more power (typeclasses, macros) but the code quality seems (to me) better with the constrained language than with the unconstrained one.


Well, one is a research language with the explicit goal of trying out new language features, so the comparison falls flat imo.

Also, doing only GUIs is quite a bit more restrictive than general purpose programming and not every fancy feature may make sense there.


That's an unfortunate problem that Go has, admittedly; it's far from a perfect language. I'm just glad they resist adding language features for isolated use cases.

One example of code generators is enums, I'd love for Go to add that as a feature, I frequently use them in other languages. Go's equivalent is a list of consts with a shared prefix, e.g. StatusOK, StatusBadRequest etc for HTTP error codes [0], then functions to do anything with them (like getting a status text for the aforementioned HTTP status codes; see [0] and scroll down a bit).

I mean it's not difficult code; nobody has to learn any new syntax or methodologies to understand enums if they already know consts / variables, functions and switch/case statements. It's just inelegant and it feels unsafe - you need a linter [1] to check for exhaustiveness of the aforementioned switch/case, on top of a ton of other linters [2] that IMO should be language features or compiler checks.

My personal gripe is struct tags that are just strings that no tooling or compile-time checks will check, they're left up to a library (or the standard library) to interpret at runtime. In other languages like e.g. Java they introduced annotations to add metadata to properties.

[0] https://go.dev/src/net/http/status.go

[1] https://pkg.go.dev/github.com/nishanths/exhaustive

[2] https://github.com/golangci/awesome-go-linters


In my experience, real-world Go can be just as complicated as real-world Python or C++. The lack of abstractions is making the problem worse, if anything.


Do you think the new go Generics solve this in some part?


It thankfully removes the need for code generators or large swathes of copy / pasted code with all the risks and maintenance overhead that incurs.


Regarding Go, it didn't have generics until recently, partly because some of the community didn't think it was beneficial. They've been nothing but positive in our project as we've been able cut down on substantial amounts of boilerplate in some areas.


Isn't that the grandparent's point though? Features that other languages have are first considered "not beneficial" and are in fact mocked as being useless or extravagant. Then, once said feature is introduced to one's favourite language, the feature is considered useful and it turns out that maybe those other languages had a reason for including them beyond mere extravagance.

edit: gp, not p


Also known as "the Blub paradox". https://wiki.c2.com/?BlubParadox


> partly because some of the community didn't think it was beneficial

And partly because it needed more thought. I'm all for more well thought out features, but there's also value in a language that doesn't move fast and doesn't break things. And I say that while Python is my main work horse, so I understand what breaking things mean.


This post from Russ Cox was really insightful to explain that Go's generics and the delay in implementing them were a technical issue, not a political or opinion based one:

https://news.ycombinator.com/item?id=9622417

> We have spoken to a few true experts in Java generics and each of them has said roughly the same thing: be very careful, it's not as easy as it looks, and you're stuck with all the mistakes you make.

The Go team does their homework, and they do it thoroughly. I respect that more than anything about the language. Compare with Java, that had been stagnant in committees for nearly a decade, or with Javascript, that has been bolting on features left and right; I'm mainly thinking of the half-baked OOP addition.


It’s funny you call out Java, when it is exactly the language famous for taking advantage of being the last mover — even its original intros mentioned it!

Also, languages don’t start in a vacuum, they shouldn’t have to go through the whole process from zero each time — Go absolutely failed by not incorporating it from the first version.


The Go developers, many years before implementing generics, made it clear they were open to the idea. It was more about how it would fit into the language and them agreeing on it.

To their credit, they don't just throw things into the language because it's trendy or "cool" at the moment. Even if people disagree with their decisions, they are well considered and thought about decisions.


I'm gonna take a bit of a "people-pleaser" stance on this and say that there's merit in both mindsets.

Personally, I tend to prefer using and abusing all the sugar and tools that a compiler gives me. I find that I'm not a terribly smart person most of the time, and if a compiler engineer has a figured out a good bit of abstraction to make the code safer or more readable or faster, I'm inclined to use it.

There are plenty of success stories with this approach. Love it or hate it, I think SQL is overall a reasonably pleasant language, and almost completely removed from the underlying hardware. You think relationally with SQL, not really in terms of for loops or memory allocation.

All that being said, I will admit that sometimes I don't want to spend the entire day trying to decipher whatever the hell GHC is trying to tell me with its weird errors. Go makes you do a lot more manually, but at the same time you also don't need to understand the intricacies of a sort of approximation of type theory or linear logic.

IMO, I genuinely think that right now the two best languages in terms of abstraction usability are Clojure and F#. They both allow for lots of great abstract stuff, but they also do allow you to cheat when necessary, and being on the JVM and .NET Framework respectively, there's no shortage of libraries available.


It's something that you can fall into pretty easily imo, but after you dive into a few languages and realize you just weren't aware of the tool chains, librarys and platforms you begin to realize familiarity accounts for most of your enjoyment.

I like golang a lot and use it professionally and there are plenty of errors and issues that can require syntax and code that to people who aren't super proficient in it would think is over-complicated and end up fighting the compiler (channel can be awkwardly implemented and related issues and what not can be.... non-obvious..).

I've been writing a ton of rust recently and until I became proficient I felt it was really complicated and led me to fight with a compiler (borrow checker I suppose) and honestly it took me coming back to it a second time almost a year later to break through it and now i'm as productive in rust as I am in golang... but it was my familiarity, I found tools I wasn't aware of, my SQL query strings & templates are now checked statically and so I feel more productive in rust in some ways.


> <my favorite language> is used to solve REAL problems

That is really not the point being made. The point is rather "the language helps me keep focused on what I do, because many subtleties in other languages don't exist, and those have me overthinking things". Whether what you do is REAL work or a friday night game jam is irrelevant.

Also I wouldn't say that Elm lacks ergonomics or powerful expression features. It does lack browser API features, but I don't believe that's what the author enjoys.


I think there's a case to be made for simpler languages, but not the way the author portrays it here, and not the way eg Go does it.

IMO the biggest problems with almost all popular programming languages are

1) null

2) exception based error handling

such that, when you call foo() where foo is

String foo(){ blabla }

you can get a String, null OR an exception (!!!) and most compilers happily let you treat it as if it only ever returns a String.

I hope some day null is no longer a thing, and that Functional Programming types like Option, Either, Try etc in the native libraries is the new default.

incredibly, there's still no consensus as to which exceptions should be used for what and when, though these days the most common approach is to simply stick only to RuntimeExceptions, which is terrible.

Functional error handling using Option, Either, Try etc are arguably much simpler, safer and more powerful than exceptions.

Simpler because they don't rely on dedicated syntax- they're just regular objects no different to any other object.

Safer because unlike exceptions, they force callers to handle all potential outcomes, but no more. (no risk of ignoring errors and no risk of catching a higher level of error than desired, ubiquitous bugs in exception based error handling)

Powerful because they support map, flatmap, applicative etc, making it easy to eg chain multiple computations together in desired ways, which is unwieldy and bug prone when using exceptions.

It could be that, when learning Java, Python and any other language, we learn that methods return objects... and that's that. No weird dedicated syntax and magic, special treatment for returning anything other than the happy path, and the HUGE complexity that comes with it, eg the dedicated syntax itself and how it behaves, differences between checked and unchecked exceptions, hierarchies of exceptions etc etc.

In addition to that, when lists and booleans implement map, flatMap etc, you can actually reduce syntax of languages even further- there's no need for looping syntax like for, while etc, and no need for if else either. This is probably too extreme for most people, but think about it. There's literally no reason to have this syntax in the language if the types in the library give you the same functionality.

So my dream languages would be something like Kotlin ie with inferred type safety, immutability by default etc but without support for null at all, no exceptions at all, no looping or conditional syntax, and a better, smaller, simpler library.


I like exceptions. You can't get away from them, I know Haskell tried, Rust tried, they still have exceptions (perhaps they call them by a different name though). May as well make that system generally available to programers. They also allow you to have the Erlang/Elixir philosophy of happy path coding, "just let it fail", by using a high level exception handler and then just coding the happy path underneath.


The problem is that virtually all languages abuse exceptions and use them for very much expected control flow and business logic. But exceptions should be just that, exceptional. Eg when you make a db call, the db not responding is not exceptional. Nor is not finding the user you're looking for. Those are 100% within the range of expectable outcomes for a db call.

fun findUser(userId: String) : Either<Error, User>

is MUCH simpler and more powerful than

fun findUser(userId: String) //haha, I can actually throw exceptions that aren't in this signature, or return null (wat)


> I like exceptions. You can't get away from them

I hope you never program any safety critical machinery. I don't mean exceptions cannot be useful, just that there are circumstances where they are useful and circumstances where they are not.


>I like exceptions. You can't get away from them, I know Haskell tried, Rust tried, they still have exceptions (perhaps they call them by a different name though)

Rust has no exceptions in any sense of the word. Exceptions are ways to crash the program in a controlled manner with the ability for these crashes to be caught midway before the program crashes and handled correctly.

In rust you can only crash it explicitly using the panic! Macro. No handling.

The different name you are looking for is "errors". Rust has errors as do all programs. Some programs have exceptions to handle those errors. Rust does not.

If you mean "runtime crashes" then elm is the only language that is popular that uses has no runtime crashes.


> Exceptions are ways to crash the program in a controlled manner with the ability for these crashes to be caught midway before the program crashes and handled correctly.

> In rust you can only crash it explicitly using the panic! Macro. No handling.

You can catch Rust panics with `catch_unwind()` if you compiled your program with `-Cpanic=unwind` (default on most platforms). Under the hood it uses stack unwinding, just like C++ and co's exceptions. But Rust doesn't consider this idiomatic error handling, it's only used in a few special situations (test frameworks, web servers where one buggy session shouldn't take down the process...).


You absolutely can catch and handle a panic in Rust [0]. Panics are just exceptions by a different name. Although, I do agree that the Rust ecosystem tries hard to avoid using panics, which is good.

[0] Example of catching, handling, and "swallowing" a panic in Rust (GTP4 wrote this): https://play.rust-lang.org/?version=stable&mode=debug&editio...


This is very uncommon to do and cannot be compared to exceptions


Catching a panic is _morally_ equivalent to catching a SIGSEGV. It is not meant for normal program error conditions and expected failures (e.g. "No such file").


I.e. only to be used in exceptional cases.


Learned something new. I feel though it's better if most programmers didn't know about this. It looks like cursed knowledge.


It's not exactly cursed knowledge, you just have to have enough judgement to understand where it's appropriate.

Trying to do magic and patch something on a panic and retry is cursed indeed. If it's about cleaning up resources of a thread and logging this somewhere, then there's nothing cursed about this.


I don’t disagree with you that just because rust has a feature similar to exceptions, that it has exceptions, but https://doc.rust-lang.org/std/panic/fn.catch_unwind.html does exist.


As an application gets more complex what starts to matter is general design, software architecture, performance, compile times and language agnostic features.

Obsession with language features or syntax tends to move people towards building castles in the sky and being too obsessed with code rather than the software that actually runs on a physical machine. A lot of fancy features usually come at quite high runtime or compile time costs with not really meaningful benefits in a large software system.

Unless you're writing software explicitly for the sake of staring at code, unopinionated and simple, fast and pragmatic languages that get out of the way are the tool of choice for good reason.


Oh, so somebody liking language features that you find unnecessary is "obsession with language features"?


Obsession is somebody liking that which you find unnecessary.

There, I made it point-free. Isn't it much simpler?


Yes, your comment seems to be devoid of any point


Author here :)

I definitely don't think ergonomics and features from other languages are useless! I just feel a bit overwhelmed and distracted by variety sometimes, especially when working on teams.

For example, about 50% of the JS teams I've worked with collectively agreed not to create new classes. I think I'd prefer working with JS if there were only one way to do things, but it doesn't mean that classes are bad or useless.


I like Elm but there are some things that would make life easier and not add much cognitive overhead, like updating nested records for instance. The current syntax wouldn't even need to change.


It’s even worse as you cannot even update a record if it has a qualified name.

    { Module.record | field = value }
is not allowed. So either, you need to import record unqualified, or you need a let construction.

I somewhat get the restriction on nested updates (though I don’t agree with it), but I absolutely do not understand this.


It's a valid assessment depending on the context. There's a lot of software scaffolding that exists in places that, usually for good intentions, creates complexity in the hope of simplify the problem at hand. Sometimes it works, sometimes it doesn't. When it works, it's great. When it doesn't work, it adds yet another layer of complexity to deal with whatever problem you're trying to actually tackle.

Ultimately it comes down to trying to do a cost/benefit analysis of the complexity at hand and deciding if the additional layers add enough value and how far your problem deviates from the supporting structures. The issue is, it's often quite difficult to know a priori what is helpful and what just adds complexity because goals are often moving targets and you have to try and assess the range of potential goals with the flexibility of all the middle layers you introduce.


I read this as an expression of preference not a condemnation of other languages.

The full context helps

Most languages are too powerful for my palate.

Don’t get me wrong – I love Rust and many other languages! But sometimes they’re just too much for me.

When writing Rust or JS or Haskell or Python or Lisp, I’m overwhelmed by opportunity. Should I make this generic? Should I use classes or structs? Immutable or mutable? Macros? Functional or imperative array manipulation?

I try to please compilers and coworkers and customers, but all are disappointed. Give me a woodshop and I’m lost, but give me a simple chisel and I intuitively know what to do. There’s a certain freedom in restricted toolsets.

Languages like Go and Elm spurn extravagance. They resist overcomplication. They force me to solve real problems instead of fighting compiler errors and stylistic differences.

Furthermore, consistent code makes portable mental-models. Go and Elm codebases tend to be extremely readable.


Speaking as a dude who loves legacy Lisp - I once wrote an interpreter for it in Elm. I was disappointed to find there wasn't enough parenthesis in Elm! Sometimes the bell and whistles get in the way of my creativity and flow


I loved Elm as soon as I had a running app that I could refactor and be (reasonably) sure it would work once the compiler was satisfied.

However, I don't like the way the project is run. It's one Benevolent Dictator that has a particular vision for Elm and he's not really sharing with the community. For context, the latest Elm version (0.19.1) was released in October 2019. It kind of feels like a nice tree house left to the elements because the person grew out of interest, but kept a lock on the door.


Have there been any efforts to fork it?

0.19 also prohibited interaction with non-Elm code which I recall a controversy about. But can't seem to find out if anyone forked 0.18 because of that.


I don't think it's a fork, but prominent Elm developer/author Richard Feldman has been working with and hyping up Roc: https://www.roc-lang.org


It is my understanding that roc aims to "bring Elm to the backend", so it does not at all look like a substitute for Elm.


Ah my mistake. I wonder if Roc plans to have first-class support/integrations for Elm frontends. Or maybe they’ll stay completely agnostic and just mention Elm in docs and examples?


From what I know from skimming the docs and listening to Richard's podcast, their focus currently is on achieving great compiled performance. Plus, from what I can tell, Richard is still a fan of Elm, so I'd guess he thinks there's space for Roc to contribute to the frontend (that last part is pure speculation though).


Meant to say "... there isn't space ..."


He in fact works on Roc full time now! As does one other Roc contributor whose name escapes me. Exciting times.


Interesting! From a surface language level it feels a lot like F#, but with purity and a managed effects system--which is something that I've kinda wished for/had to build patterns for in F# codebases... I'll have to keep an eye on it, thanks! (reading through the FAQ, there are some interesting design decisions! I appreciate the pragmatic focus. Didn't realize that it was non-curried lang until the FAQ)


Not quite a fork, but Gren is a descendent: https://gren-lang.org/news/220530_first_release/


Gren is a fork. Their first commit is the head of Elm 0.19.1 right?


The faq in the book says this about it:

> Gren started as a fork of Elm. This is mostly considered to be an implementation detail, a way to speed up initial development.

> It's not a goal of Gren to replace, or stay compatible in any way with, Elm.

A little vague but I read it as they're planning on diverging strongly and immediately with a clean break. Which doesn't make it not a fork I guess, but isn't what I normally think of when someone says a project is a fork of another.


Yeah I guess "stay compatible with" and "cover the same use cases" are the connotations for a fork and it really doesn't hit those, fair enough.


Fork means "to the originating project's source code and develop it further in the context and governance of a new project" in my understanding.

So Gren is a fork.


It's such an easy restriction to work around that it just doesn't come up a ton on code that's always been written for 0.19. I imagine it was a monstrous hassle if you depended on it with a big 0.18 codebase, but the new JS interop (ports but more importantly custom elements) are very nice to work with tbh.

There's a third inspired-by-elm language Derw (after Gren and Roc that are mentioned elsefork) but I don't know much about it.


Indeed the releases are less frequent and Evan works in batches to avoid breaking changes every year. But he didn't left, he still works on private branches and on security patches when needed. Yesterday he gave this presentation:

https://gotoaarhus.com/2023/sessions/2529/elm-on-the-backend


Why has his work not turned into a public bug fix update in 2.5 years?

This feels a lot like Patrick Rothfuss on his Kingkiller Chronicles. The creator has a fan base he doesn't want to disappoint and who will defend his honor as long as he can give them any evidence he's actually making progress, but all the evidence suggests he's actually lost interest or doesn't know where to go from here.

Not that there's anything wrong with losing interest in a hobby project. The problem with Elm is that it was pitched as more than a hobby project but then held so close to Evan's chest that no one else has been able to take over now that he's not maintaining it.


Too many people are concerned with the language's creator, how much he is working on, how many people love or hate him, what his motives are, what he wrote in a comment four years ago, and what he had for breakfast this morning.

These comments are always the same: "Elm is great, but..." Then they dig up some drama about its creator with a years-old post. If the language is great, then maybe they should use it and stop fretting about the person who made it.


I'm not talking about any specific drama, and I didn't go digging anything up. I'm just talking about what's actually happened to the language: it has been 2.5 years since a single bug was fixed. That suggests that the creator is (contrary to the person I replied to) not working on it any more.

I couldn't care less about the creator or his drama, but I am a bit sad that a language with so much potential has been dropped instead of being handed over to the community.


I am talking about this:

>The creator has a fan base he doesn't want to disappoint and who will defend his honor as long as he can give them any evidence he's actually making progress

So yes, it's fair to say that you do care about the creator and his drama.


You're reading way more emotion into that statement than I meant to write. I meant it strictly literally and apathetically: both creators have fans who will jump in to reassure onlookers that things are actually moving forward.


Knowing who the BDFL is and how a project is run are very important considerations for long term projects. It's not something you can just discard as trivial. Doing an AoC in a language you know nothing about is totally fine, but not in any serious environment.


Seriously...the person who controls everything about the project, irrelevant and immaterial! Sure, like I'll buy that.


The only way to watch this is on a mobile app??


Yeah, partially because of how the project is run I chose to go with elmish for my own project.


As a counterpoint to the inevitable "Is Elm dead?"[0] comments, how many other languages are still rock solid after 3+ years without a new version? Shouldn't we aspire towards using tools that are stable because they are complete?

What is the maintenance burden of the average React app? When I have written an Elm app, I feel confident that I could come back to it in a few years time with no issues.

To me, this stability is a testament to the language's thoughtful design and rejection of the constant churn of contemporary web development. At the risk of sounding like a Game of Thrones fan waiting for Winds of Winter, I look forward to the next version coming out with modest changes and bug fixes whenever it is ready.

[0]: https://iselmdead.info


That website justifies Elm's release cycle by saying that the language evolves slowly and that's a good thing, but you and they are conflating the bug fix release cycle with the feature release cycle.

I don't think people would be saying Elm is dead if there were regular bug fix patches coming out and we were on v0.19.21. The reason why people are declaring Elm dead isn't because new features haven't been added in two and a half years, it's because there hasn't been a bug fix update in two and a half years.

Sure, the language is stable in that it doesn't change, but stable can also mean bug-free, and Elm is certainly not stable enough to justify going that long without a single bug fix.


Yes, you are correct that bug fix release cycle and feature release cycle are different. If I felt that the majority of criticisms and comments were about bugs, I wouldn't have felt compelled to respond in this way. Perhaps I've misjudged that.

I will admit that the bug list is extremely disheartening. I have personally never come across them in the wild, but I don't doubt that when they do come up they are a horrible roadblock and the burgeoning set of community tools to work around this is telling.


There's also a difference between language features, and std library or browser API features.

I'm fine with Elm-the-language as it is, but I would definitely have preferred for a stdlib not to expose a function that are just a TODO.

I still use and enjoy the language, mostly because everything else in browserland is a pit of despair for me, but I could see some quality pull requests being merged once in a while.


There are probably people out there who think that a language should change more rapidly, but I think most people just take a quick glance at when the last release or commit was and judge that it's someone's hobby project that they've long abandoned.

Which is more or less true, given that Evan never let anyone else fully participate.


Yeah, I think that's exactly the attitude I want to push back on.


It's not rock-solid nor complete.

The authors refused to fix a parser error related to negative literals: https://github.com/elm/compiler/issues/1773



"Rock solid" in my day to day experience; obviously there are the issues reported on GitHub but I haven't come across these issues in real-world development. This bug is admittedly very poor, but it is straightforward to workaround.

I don't think the language is complete, but that we should aspire towards completeness over churn.


This is disheartening in theory. In practice it never comes up


Until it comes up.


You thought you ate huh. This is “duck season” “rabbit season” type naysaying. It’s work aroundable if it ever comes up but I can tell you that it has not come up for me working in Elm.


People in the issue gave multiple real cases where it came up for them. If responses like yours are common in the Elm community when bugs are pointed out then that would explain a lot.


Looking at the number of opened bugs and lack of releases, I wouldn't call it rock solid.

https://github.com/elm/compiler/issues


Ouch, not just the number, look at the type of issues. "Compiler error...", "compiler panic...", "elm publish hangs indefinitely..."

They never made it to 1.0, so it's not surprising, but major compiler bugs coupled with no chance of a patch (2.5 years since the last bug fix update) definitely suggests the language shouldn't be used in large projects.


Can you please list which of these compiler bugs are _major_?

There was a commonly encountered compiler bug in 0.19.0 (Map.! crash) and the 0.19.1 version was the result of fixing that. During 4 years of writing Elm full-time (close to 500kloc total) I have encountered only a "rank 2 typevar" typechecking bug _once_ and it was easy enough to work around. The Elm code that large projects need doesn't really trigger compiler bugs and crashes of the kind you'd see in the GitHub Issues.

If GCC has some bug reports open about crashes, but your code doesn't really trigger those in practice, would you call GCC unsuited for large projects?


If the last bug fix update on GCC were 2.5 years ago, I would absolutely steer clear! That I haven't run into them yet doesn't mean I won't, and the larger the project the more likely it'll be a problem at some point.


I agree that the list of issues is disheartening[0], although I would add that some part of this is due to the language designer's approach to issues (let them pile up organically and then sort through them).

[0]: https://news.ycombinator.com/item?id=36044473


If the low hanging bugs can't even be triaged, what hope is there for any future innovation? ie, the countless unsupported browser APIs

It is clear that Elm is understaffed, to say the least.


> It is clear that Elm is understaffed, to say the least.

The core team treat bug reports as insults: https://github.com/elm/compiler/issues/1773


Wow, that's remarkable. I can't fathom having the response of "why are you even doing this" instead of something more productive. It doesn't matter why they're doing it (and valid use cases are provided), negative numbers in a case statement should be supported regardless.

Edit: And finishing reading that thread now, Evan didn't even return once his question of "why" was answered. That's something else. I have no skin in this game, and people can run their projects as they see fit of course. But this behaviour doesn't make for a great community/ecosystem.


That's the appropriate response. You have to understand the problem to produce a solution. I don't read that as a negative response to the bug report. Just asking for more context.

It is bad that the bug has remained for so long.


I still use Elm daily. Even if development on it is essentially paused for the foreseeable future, it is still much better than the alternatives for me.

For example, all Elm apps having the same architecture ("TEA") is one of the biggest wins over alternative apps where every project, even those you make yourself, will do things differently.

Elm Janitor (https://github.com/elm-janitor/apply-patches) is a curation and applicator of community patches to Elm proper. Haven't used it, but it seems like a promising way forward.


The fact that Elm had traction and popular support (books/youtube tutorials/etc) most language or framework projects would kill for and then basically dropped is almost criminal in my mind.


re famous Elm error messages. This one I got when I was learning Elm 4-5 years ago.

  Elm uses a different name for the “not equal” operator:
  
  5|   text "Hello!" != "balbla"
                     ^^
  Switch to (/=) instead.
  
  Note: Our (/=) operator is supposed to look like a real “not equal” sign (≠). I
  hope that history will remember (!=) as a weird and temporary choice.

Wondering if it is just me, or it really is passive-aggressive? It was the first red flag for me.

upd: formatting


its fairly direct. And not wrong.

Passive aggressive might be like this

"there are some languages that feel the need to use !=. They have the 'opinion' that this was a good idea, look at them. They are so cute trying to be a real language with such *interesting* design choices"


The note absolutely is, the use of `/=` is just consistent with Haskell though, which to me makes perfect sense.


I was also using it for these reasons up to about 10 months ago. I've switched to rescript now because it still addresses most of these, while being a lot closer to the mainstream of frontend programming.

Rescript does piggyback on normal JS ecosystem and build systems so comes out worse there. But it's easier to integrate with existing js codebases and npm packages for the same reason, and its output can be used from js in any framework if you plan for it.

I was really missing the elm command/update model for a while but at some point I realized adding that semantics to a react reducer with a custom hook was completely reasonable, and there are a couple existing projects doing exactly that. I wrote my own in an afternoon and have been copying it around to new projects since.

I'm like 90% happy with this transition now. It doesn't always feel quite as safe & magical as elm did, but it's also a lot easier to integrate with other systems.


Interesting, got any repos written in this style?


Not that I can share unfortunately. But here is the implementation I got the idea from. https://github.com/mjal/rescript-use-tea/blob/master/src/Use...

I defined the actions a little differently and followed the rescript-react pattern of having effects return an Option of a cleanup fn but most of the idea is there.

Looking around just now I also found this PoC of someone doing a very similar thing but all inline with react. https://github.com/mishaszu/rescript-model-view-poc/tree/mai...

Really the only jump you need from react to the elm architecture is having the reducer be (State, Action) -> ('State, Effects) instead of simply returning the new state alone. The then you have a useEffect that invokes the side effect fns, passing in dispatch so they can send updates back to the reducer & so reducer stays pure. There are a bunch of different ways to set that up, and honestly a lot of react apps blunder into an accidental and incomplete version of this anyway it's such a natural model.


How has your experience been with runtime errors? One of the things I like about Elm is that for pure Elm code, there's very little surface area where a runtime error can occur.


For pure rescript code it's pretty much as reliable as elm.

The only time I've really seen them is when interacting with js/ts code. The rescript externals system is easier and more flexible than elm ports, but for that reason less safe.

If you don't model the types of incoming data exactly it can cause runtime errors. For some packages it's very difficult to do that with high confidence so I've seen a few leak in. Similarly if you use gentype to map typescript types to rescript, it assumes the types are both correct and sound. Which are not actually guarantees typescript makes I don't think. So I've seen some from that as well.

Rescript doesn't really do a great job at displaying these types of errors either. It's usually pretty obvious where they came from but not always why unless you have good knowledge of the API you're hooking to. So, rare but anomalously frustrating in an otherwise very pleasant language.

I think for this reason it's pretty standard to avoid writing or consuming package-wide bindings to npm modules. It seems like everyone is just writing tuned limited externals only for the parts they actually use, except for a handful of very popular libraries.


The contrarian HN view is below.

432 comments | 3-years ago

https://news.ycombinator.com/item?id=22821447


Elm has lots of great ideas, but if I were making decisions in a company, I wouldn't use it in production for anything big and long-living. Simply too much of a risk in terms of support, and finding developers with experience using it.

Only contacts I've had about Elm positions have been about rewriting existing Elm apps to something else.


It's a shame Elm was abandoned.

Impossible to justify for serious projects at this point.


Would you mind sharing a link / citation for this? Elm releases are intentionally long and the project appears to be ongoing [1].

[1]: https://iselmdead.info/

Edit: moved the position of the citation.


People are constantly asking for a pulse:

https://discourse.elm-lang.org/t/is-elm-browser-still-mainta...

https://discourse.elm-lang.org/t/request-elm-0-19-2-any-upda...

It's pretty sad. I personally believe the ecosystem would be in a much more vibrant state today, if the creator had formally abandoned the language at any point in the past, as there are many who would pick up the torch.

It is telling that several people who could once have been considered 'core team' are now building their own languages:

https://gren-lang.org/

https://www.roc-lang.org/

https://www.derw-lang.com/


I think A) Elm is done, not dead. "If it ain't broke, don't fix it." (The JS folks should take a note.) and B) the natural next step is to make Elm-to-native compilers, which is now happening.

I think a lot of programmers get warped views of PL development from over-exposure to the badlands of Javascript. There are languages (like Prolog) that grow like trees, eh?


Mentioned elsewhere in this thread, but the lack of bug fixes imo makes it definitely seem dead. I'm all for stability and sticking to a core vision/set of principles, and agree with your point about the Javascript ecosystem. But not even having small updates to fix bugs here and there doesn't exactly scream "this project is alive but done".

Personally I do believe that the core team are working on things away from the public eye, and that's fair enough in order to keep focus without having to deal with everyone giving their own opinion or criticism. I just wish there was significantly more transparency in the process, and a few bones thrown to the community in the form of fixes.


I think everyone just means something different by dead.

I personally wouldn't use the word until Evan throws in the towel, but he's clearly still onboard. For example, https://gotoaarhus.com/2023/sessions/2529/elm-on-the-backend (yesterday).

I don't think we handle these kinds of oddball cases very gracefully which is evident in basically every HN discussion about Elm. If a language gains traction, then we demand a certain shape of expectations from it, and we're not very good at walking away with just "well, it ain't for me". It's not enough for us to just say that. It's like we have to linger around and ensure everybody else washes their hands of the tool, too.

I'm pretty sure Elm is past the point where anyone who doesn't like the glacial BDFL approach doesn't use it, and those who choose to use it don't care.


Well, I have no particular insight but I heard something about a compiler-to-native code project that might be taking up core team time, or maybe Evan is just burnt out from all the static. I just wish there were fewer people crapping on the kid and more recognition of what he accomplished, and will hopefully accomplish in the future.


They can proclaim Elm not dead all they want, but if you take a look at the main repo the last commit was over two years ago, and it was to set up an auto reply to PRs that they probably would not get a response.


He works on private branches to avoid speculation and pressure. Example, he gave this presentation yesterday: https://gotoaarhus.com/2023/sessions/2529/elm-on-the-backend


If people can credibly ask whether something is dead, then the project is dead.

Live projects appear to be alive. There is activity, developers to talk to, support to purchase, release notes to read, even if those release notes are just maintenance notes for mature software. If your evidence of life is pointing to a two year old forum comment, I hate to break it to you, it's dead.


Honestly, even just a tweet from the BDFL twice a year saying 'I still care about this' would be something.

It's impossible to evangelise something when the creator has seemingly taken his ball and gone home.

The idea that enterprise should use Elm is laughable.


Is iselmdead dead


The core team refuses to fix straightforward bugs: https://github.com/elm/compiler/issues/1773


Quintessential experience of talking to Elm core team: https://github.com/elm/compiler/issues/1773#issuecomment-418...

What's funny, rtfeldman uses case expression with numbers in his (in OP's blogpost) praised library elm-hex, so it's not the problem of numbers vs variants. Only negative numbers are the problem.


> Elm releases are intentionally long and the project appears to be ongoing [1].

Sounds like a case of the halting problem.


It had so much potential. PureScript is a good alternative with an active community and democratic development process.


The successor to Elm is probably “Elmish” for F#, which is a bit less opinionated. It can interop with any JS code so it’s a safer bet.


That's what we are using right now in production. But the main benefit on this case is that we also can use the same language on the server and devops.


Gren is trying to be a successor too: https://gren-lang.org/


Is elm dead?


Elm isn't dead the same way Yahoo isn't dead. It's around but it isn't gaining new traction, features, mindshare.

I think it's a great language that people should explore for fun and learning. I think it was horribly mismanaged from a public relations perspective and at one point in time had a real shot at becoming a lot larger than where it will stay from now on.


We also use Elm in 2023, just got the first project to production a few months ago and we absolutely love it. Finally a way to tame the complexity of browser-run-code.

We only use it when there is complexity: when there is just a little progressive enhancement needed on a SSR HTML page we happily use vanilla JS or jQuery (we're looking for a good TS-based jQuery-like solution the fits that bill).

What we like about Elm:

* makes us think about tech design issues early on (you cannot just ignore them)

* its a transformative experience: devs become better at writing any language after having solid Elm experience

* its fast to compile compared to TS+React+Redux+Babel+WebPack+...

* no unhandled runtime errors! (yes it is true, no more errors with Elm)

Just like I find Ruby a very nice language that was hidden in Perl, I see Elm as a very nice language that was hidden in Haskell. Thanks Evan for creating it.

And yes I truly believe Elm is not dead but merely finished to a great extend.

Oh, as a bonus, want to have your mind blown, check out this:

https://www.youtube.com/watch?v=nSrucNcwlA8&t=275s

(when I watch that video I cannot unhear "look at all the boiler plate im not writing" in David Heinemeier Hanson's high pitch voice; referring to the original Ruby on Rails demo)


> no unhandled runtime errors! (yes it is true, no more errors with Elm)

I used to work with elm some years ago and my coworkers claimed this as part of their reasoning for choosing elm. Shockingly, we still had runtime errors! Elm helps reduce some type system based runtime errors. But that’s only a subset of exceptions, and it’s not perfect at even catching those. Try this in elm:

div [ attribute "@style" "color: green" ]

It’ll compile just fine. And crash completely at runtime.


Wow, it indeed crashes at startup (a very reasonable place to "crash" when you avoid all safety mechanisms and put an @ in an HTML attribute key).

There are some fully type safe CSS systems in Elm, but they are 3rd party libs.


> And yes I truly believe Elm is not dead but merely finished to a great extend.

No less a CS personage than goddamned Donald Knuth uses the decimal expansions of irrational constants to denote that his programs approach "finished" with smaller and smaller changes. Somehow this is fine when he does it but "the language is basically cooked as far as syntax goes" is an unacceptable answer to the Elm decriers. Dogs bark; the caravan goes on. Mazel Tov on launching your thing in production. I wish you a thousand years of success.


Elm reduces work and makes it a lot easier to work on (refactor) someone else's code. Some people may be threatened by that.

Also: many do not like anything they are not accustomed to.


Lamdera is closed source and you deploy on their system. It has been forgotten already. Rails is thriving, open source and a beast. I think that is the problem with the Elm community. They are too uptight to do open source properly. They need to listen to some Humble from Kendrick Lamar.


I find Lamdera cool from theoretical perspective.

> They are too uptight to do open source properly.

It's not an "open access innovation project", so they did not get that bit of open source "right".

Comparing Lamdera with Rails is near impossible. But one is certainly resulting in less runtime errors!


> But one is certainly resulting in less runtime errors!

In the 5 or so projects which uses Lamdera.


Wait until you want to support an enterprise customer and you need to adapt their requirements in a quick way.

Elm is fine for learning, but that's all for me. Serious products for serious customers require more than "beautiful typings"


I wrote some Vue instead of Elm because I was frustrated. But the more I work with Vue the more I am absolutely terrified of using it for non-internal web apps.

Elm has some super annoying problems, like their disdain for nested structures or components, but I just don't know of anything better...


Imba is the answer


Vendr (1B+), NoRedInk and Humio are huge companies and their entire frontend is in Elm.


> Wait until you want to support an enterprise customer and you need to adapt their requirements in a quick way.

Is that within Evan's ambition? I personally do not mind to use software that does not cater for enterprise in production at our small "enterprise" :)


What's your working experience with Elm?


Aww, I was hoping this was about the email client.


I was an embarrassing distance down the article before I realised they weren't talking about email.

"Wow. I had no idea that email reader I used thirty years ago had such depth!"


You might be interested in Himalaya, a modern email CLI.

[1] https://github.com/soywod/himalaya


Same here, I had not heard of anyone using elm these days.

I have seen similar titles for old software bouncing around, one example is ical, the tck/tk calendar application I use to use. I keep running across ical and my first thought is always "is ical still under development ?". At the time that was a very nice application and had potential.

https://wiki.tcl-lang.org/page/ical


I loved elm(1).

I stopped using elm (email) when I found mutt(1).

Gads, that and procmail(1) were heaven. And when I finally intersected procmail with eliza, I was full of bliss... I was at AT&T (yes, THE AT&T) and it was hyper-satisfying that my co-workers recognized it and the marketing dept usually did not.


I stopped using elm when university upgraded to pine. But muscle memory was so powerful I have been aliasing my mail reader to elm ever since. :-)


If you want to use Elm for your hobby project, go for it. Everyone else, choose something that has a well established development team - the operative word being team. One-man development efforts (no matter their genius/brilliance) are too risky to depend on for serious work that needs to work/be-supported in 5+ years.


What I loved most about Elm was the syntax, types and it's incredible CLI . But I found the architecture and working with foreign data (JSON APIs) just too strict to be productive.


On the other hand, I love Elm's decoder combinators so much that I miss it in every other language.


I like them in principle, but they really get annoying for objects with lots of fields (since the order has to exactly match the constructor), or for objects that need to round-trip (because there's twice as much code to write, and no way to verify that they're equal).


highly recommend the talks "making impossible states impossible" and "make data structures" by richard feldman.

https://www.youtube.com/watch?v=IcgmSRJHu_8

https://www.youtube.com/watch?v=x1FU3e0sT1I

the talks are geared towards elm but I think they offer some great advice applicable to programming in general.


Sometimes I dream about writing my own secret coding language that no one else knows so I can have this personal/private connection to the digital products I build. I would make all my code open source, but no one would understand it.

But that would take a lot of effort, so I just use Elm instead.


I can relate to most points in the article but definitely not #4. I'm a newbie and Elm's ways of declaring types are confusing to me. There are custom types, type aliases, records, extensible records, opaque types, phantom types, wrapper types [1]. However, I still wasn't [2] able to model a list of items with a common base type without having to switch-case through all possible types.

[1]: https://gist.github.com/JoelQ/6b303d9ad450537163b6f8f6cf8a4e... [2]: https://ellie-app.com/mQ52TY6k3zZa1


I don't work much with extensible records myself, but maybe an easier solution is to invert it so the item variants are contained in a field:

    type Item = { name: String, year: Int, kind: Kind }
    type Kind 
        = Cd { artist: String } 
        | Book { author: String } 
        | Shoes { size: Float }
https://ellie-app.com/mSVCN8dQqX8a1

Consider joining the Slack community: https://elmlang.slack.com -- The #beginners channel is a great place to ask these kinds of questions.


Thank you, that's indeed a better way to model it!


I thought this was going to be about the Elm email client. I guess I'm old af

I don't think I'd ever use "elegant" to describe Go

it's a workhorse language that's readable and full of utility.

When I think elegant, I think Clojure. Not that I'd want to use it day to day (I have)


My initial reaction was 'Not even pine? That's hardcore.' Then realised it probably meant the programming language


I thought this was going to be about the Elm email client. I guess I'm old af

You are not alone. I do kernel programming in C. I've seen so many languages come and go since the 90s that I can't keep track of them all. I never used elm the email client (I was more of an emacs rmail person at the time).


Do you know of an up to date Elm course?


Has the Elm community finalised a canonical way to work with Elixir Phoenix?


elm seems to be a very opaque project; caution must be taken before adoption.

the architectural model is good, and there are many projects mimicking it in a more open way.


[flagged]


What is that?

He must have died while typing it.

Oh, come on!

That's what it says.

Look, if he was dying, he wouldn't bother to type "to write a post like this". He'd just say it.

That's what's typed into the form.

Perhaps he was dictating it.

Oh, shut up!

Does it say anything else?

No. Just "to write a post like this."




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: