I never enjoyed frontend programming until I came across Elm. Not only that Elm turned out to be a gateway drug to Haskell. Now I write frontend and mobile apps in Haskell using Functional Reactive programming (FRP).
Yeah, we've had a great time writing Elm for a fairly complex single-page Ethereum dApp. It's conceptually a lot simpler than Haskell, which made it easy for the team to pick up. I only wish it had a better system (Tasks) for JavaScript interop instead of ports.
This is so true. I liked and used Elm when I have the right to make final decision. But it's hard to convince others use Elm when coming to integrate with JS.
That's the reason TypeScript won. It intergrate with existing JavaScript seamlessly.
One of the biggest complaints of Elm is the lack of typeclass. I'm not aware of a similar abstraction in OCaml. Does Reason have similar limitations, or are there ways to get around it?
OCaml has parametrized modules, confusingly called functors, a very nice feature along with first class modules that Haskell doesn’t have. It is roughly speaking used wherever one would use a Typeclass in Haskell http://ocamlgraph.lri.fr/index.en.html is one good example.
From an OO perspective, Elm lacks interfaces. Typeclasses are probably the best way to handle the idea of interfaces in the functional programming model.
Since functions are first class, you can bodge this with an object that has functions in it, but since those don't serialize they don't play well with a lot of Elm idioms if you put them in your model.
I thought about this, and kinda came to a conclusion, than I would take a language that has generics, and doesn't have interfaces (i.e. Elm) over a language that has interfaces and doesn't have generics (i.e. Go)
Thanks for replying! This looks very useful with good documentation and a small but dedicated community. I've worked with Purescript and some other frontend functional languages/frameworks and haven't been as productive as I believe functional allows you to be. But this and Miso seem very promising. I'm really excited about potentially using one language and paradigm for web, mobile, and backend.
> Since July 2017, I’ve been leading the frontend rewrite of their flagship product. The codebase was at 16k LoC when I started. Since then, I’ve rewritten the various subsystems at least once (I'm looking at you generic form component). Now we hover around 45k LoC with most of the common SPA structures stabilizing. We are about a third of the way to completion.
I don't know if it's common for rewrites to triple the amount of code while being only 1/3rd complete, but it certainly doesn't feel like "these are the facts I should lead with."
Edit: I read more of the prologue, and it turns out that the initial 16kloc application was not complete.
Correct, the initial 16k LoC was not complete.
In fact ( no metrics ), I deleted large portions of redundant files/code and at one stage we were back at about 11k LoC.
The comment about 16k -> 45k LoC was to give an idea of how much we had added to the product over the last 10 months.
It may be relevant that he applied elm-format to the codebase, apparently for the first time. elm-format puts very little code on each line and puts a lot of meaning into indentation, so that alone could inflate the LoC instantly without changing any semantics.
A bit of a side-track, but I feel like I'm in a weird waiting phase with Pure FP JS.
With Elm, I don't really feel like introducing it to my team before 0.19 hits, because it "feels" like it's around the corner, but it has felt like that for a while.
With Haskell, I'm not entirely happy with GHCJS and the tooling surrounding it. I'm dreaming of the WebGHC[0]/WASM being nicer, if it ever gets done.
I don't exactly know what keeps me off PureScript, perhaps that most frameworks just seem to compile to React, and that the community still hasn't settled on one (at least it seems so from the outside).
Honestly, Miso[1] is the one I feel the most optimistic about atm.
Immutability and purity by default goes a long way to remove a lot of headaches. I could settle for immutability, but it seems ReasonML mixes things a bit.
All the ML inspired languages seem to fall over on compile time. This post is a good example, where it describes design choices driven specifically by compile time, which is not a dimension I usually want interacting with the way I structure my code. I love the rest of the story (full disclosure: I have years of experience with Scala and Swift, which are no better) but until sufficiently advanced compilers arrive these languages are going to continue to be a hard sell for a substantial group of developers.
> where it describes design choices driven specifically by compile time
I'd like to point out two things here:
1. There are common library functions that we put in single files. These are imported by a lot of other files. The fact that these incur a large recompile cost is unfortunate and I think it doesn't have to be this way if dependencies were calculated at a more granular level.
2. The far larger implication to compile time becoming exponential is coupling of concerns. This is solely in the developer's responsibility. For a type system that guarantees correctness of code, there is no way around the fact that all affected modules must recompile. eg, if a fundamental law of physics were to change, the whole universe would have to recompute.
So I think for a 'substantial group of developers', the focus should be on helping people to recognise what is coupling and how to design de-coupled systems.
Beyond separate compilation, incremental compilation can go a far way here in minimizing what has to be recompiled on a change. You can even be incremental at tree level for really aggressive change latency reductions (though batch becomes lower because of memoization overhead, not to mention memory consumption concerns).
The strange bit with Elm is that it limits its type system just enough that compile times should be reasonable: The performance pits that Scala has are skirted altogether by Elm. If Elm isn't faster at compilation time, it's because that's not where the focus has been. I might be missing something though, and I'd be happy if Evan corrected me on this one.
As far as Scala goes, Grzegorz Kossakowski has done work trying to get major performance improvements out of Scala type checking, and his numbers look very promising. Barring some Shapeless-style type level computations, Scala could compile quite fast.
I've only used Elm for a hobby project. Given how much I enjoyed the experience of web app programming for once, it's nice to read how well it scales to a large application.
It definitely scales. There is an 'adjustment period' where I went from a nested to a flat, decoupled architecture. But as most things are one to two levels deep (state), complexity also grows fairly linearly. This is really great from a developer's pov when trying to grapple with how to add new features.
This is also my experience in both elm and (type|Java)script/react/redux apps as well: flat decoupled architectures seem to scale better in terms of development/maintenance in addition to reducing (bad) churn. If styling is properly handled, feature progression is also linear-ish.
Thanks for writing this. It's encouraging to read about others' experiences using Elm in production. After a couple small side projects in Elm, I'm finally using it in a few low-risk areas at work.
Network effects: The sufficiently large pool of competent programmers who already know Javascript makes it easier to hire people. The many people you don't hire often make some of their work available for reuse for free.
If you doubt that it will persist in 5 years, and want you app to be supported in this timespan. Nothing is worse than abandoned technology in the core of your application
It's definitely an issue for larger, coupled projects in 0.18 but don't let it scare you. The trick is to decouple your modules by focusing them on a single responsibility. Then the compile time is a non-issue.
The fact I have to do that shouldn't be necessary. I've been scarred by too many long compile time projects to know eventually entropy takes over despite the best of optimization efforts.
The fixes need to be in the compiler & dev tools itself, or it needs to be a very obscure feature or obviously surfaced build time problem highlighted by the compiler.
Honestly, it took digging through multiple pages to figure out what (this) Elm was about. If you come in with a preconceived notion of what something is supposed to be about, and there is nothing which even gives a short blurb on project goals, it can be a little bewildering. Clearly it wasn't about the email client (that was a bit tongue-in-cheek), but I was curious about what the project actually was for, and had to really hunt to find any information.
It's interesting how everyone thinks they're the first person to make the joke.
Not much different than going "haha, I thought it was about the Elm tree for a while!"
I'm starting to think it's just a way to signal to others that you know of an email client that last had a stable release 12 years ago that most people haven't heard of. Maybe there should be a way to wear this badge of honor in your profile instead of making the same joke, though.
Sure, but I used Elm for email for probably close to 15 years. It, and Pine, were pretty much the only two dedicated email clients for as long as I can remember. I don't have a problem with people repurposing the name, just be somewhat sympathetic that not everyone is going to know about your web framework. Onboarding is a thing.