Hacker News new | ask | show | jobs
by satvikpendem 1218 days ago
Your argument is more about static versus dynamic typing rather than anything Elm specific, as you can get all of that with TypeScript too, but without opting into Elm's entire framework. One reason why, in my opinion, TypeScript won, as I mentioned above, because it lets you do what you need to do without arbitrary restrictions by the compiler authors.
1 comments

My experience has been due to the type system, I agree. (Also the compiler enforced semver.) I've never had the opportunity to use type script, so maybe it does offer similar benefits to Elm in that area.

That's extent my personal experience can push things as far as active production applications go, but it seems to me there's something a bit more in Elm beyond just the type system. Haskell and PureScript both have static typing, but I've had runtime errors in both those languages. Not as often as JS or C or even Rust, but they do happen. In Haskell because the 'error' function exists and so people use it. In PureScript because it has its version of Elm's native modules, permitting arbitrary functions to be implemented in JS. The JS can (and does) produce runtime exceptions.

It seems to me that the promise from TS, Haskell, PureScript, etc. is something like "with this language/type system runtime errors will rarely happen" whereas the promise from Elm is "with this language/type system runtime errors can never happen."

I think that transition from 'rarely' to 'never' has been a big part of the Elm project for a long time. It's been on their homepage for as long as I can remember. At least prior to the big 0.18 native modules controversy.

If the idea is "no runtime exceptions can ever happen" with the implicit addendum "no matter what you do" native modules have to go. They were a vector by which user code could crash the application, breaking the promise. In that sense the restrictions are not arbitrary, but instrumental in upholding a major design goal of the Elm project.

That said, I don't know how much value there is in the "can never crash" promise. It feels like a step in the right direction, but at the same time it seems all the benefits in production code that I've personally experienced and cited in my earlier comment don't fall under the edge cases Elm prevents with its stricter promise. The two or three exceptions I've encountered in PureScript as a result of its version of native modules existing were all in toy programs, so maybe it's just not a big deal in real production apps.

That makes sense but it also strikes me as what I feel Haskell is like; it is so wrapped up in the ivory tower and preventing runtime bugs that it's hard to get actual work done. In TS, I also have not had runtime crashes but I'm able to use the vast array of packages for JS (which usually have TS types too nowadays) and get done what I wanted to. If I had to do the same in Elm but with much fewer packages, I mean sure I could reinvent the wheel but it doesn't bring us business value.
The guy just said earlier that he managed to do a full refactor in very little time and had super few bugs in production. I think that's a prime example how you gain very big productivity boosts using elm.

I've used typescript and elm, the ridiculous amount of time that we spend fixing bugs in typescript dwarf the benefits of having a bigger ecosystem.

Elm was the first time I could release something and say that it was done. I had built an app in elm for 4 months behind closed doors and then went live and everything worked with the only bug being in an interop to JS (2 lines of code, I fixed it in less than an hour). It meant that I could continue developing new features as requests came in without stopping to fix things. In return, also meant I could easily predict how long time takes to make. The benefits you get are massive. The cost you pay is that you do things properly.

After that project, it had been a while since I had used Typescript, and so I wanted to give that a try again, thinking that it's basically elm if you are strict about the typing. I fired up a new react project, added some tests using react-testing-library which passed, typing passed and then I booted the app and it crashed. Later on I needed to plot a graph and imported a library for it. I followed the instructions and no graph showed up. This would never happen in elm, if it compiles it pretty much always works. Typescript offers nowhere near the same experience and I lost so much productivity trying to debug the earlier issues.

> imported a library for it. I followed the instructions and no graph showed up. This would never happen in elm, if it compiles it pretty much always works

except that in elm that library would not even exist, and you have to write the binding yourself, which is why AFTER you write the binding, everything should work.

Actually there was a graph library for elm which I did use and it worked perfectly.

The elm ecosystem is surprisingly rich for having such a small community. The libraries are also much better designed and much safer to use due to the pure nature of elm.