My analogy there is Agile. Years ago no company would do agile and probably because no other company was doing it. Then Thoughtworks etc. started doing it, and slowly the proof that it can work spread around. I think this could happen with Elm.
But like agile I think there is some counter-intuitive ideas, sort of 'go slow to go fast' type of things that you need to get your head around.
I struggled and still struggle but I want to give Elm a fair go. My peeves were:
1. Can't component-ize like React.
2. Lots of 'boilerplate' to wire things up.
3. No promise like API for async, you need to do stuff via pub/sub and ports.
However the counter points seem to be that.
1. You don't need components - design a good model data structure and work out from there. There is a good video talk about this at an Elm conf.
2. By making us us wait and use ports for a lot of things in the meantime (and not just adding everything to the language or letting anyone use vanilla JS in their packages) the modules that you do use are "pure" and are almost guaranteed not to crash. And the API's of Elm are well thought out because there is no rush to fill in all of the web platform.
This sort of thinking sounds like the "100 year language" way of thinking that PG writes about. What sort of language will we be using in 100 years? Hopefully something well thought out, not full of baggage because it was rushed.
Yes you can, whether should, is a different question. You can have a ton of mini TEA components.
> 2. Lots of 'boilerplate' to wire things up.
Very true. Generating code helps with that.
> 3. No promise like API for async, you need to do stuff via pub/sub and ports.
What are you using async for? API requests? Then those are async.
I think parent-child communication isn't necessarily the right way to tackle problems.
Otherwise, I'll link to the oft-linked "Child-Parent Communication in Elm: OutMsg vs Translator vs NoMap Patterns" [1].
[1] https://medium.com/@_rchaves_/child-parent-communication-in-...
But can you make parent-child communication with these mini TEA components like in React or Vue? It seems to me that we can't.
2. I think the boilerplate is good in making things explicit.
But in react is is natural to say "oh I need a spinner, let's make a functional react component for that". And you can always keep some local state in React and avoid the message passing relay-race you'd have in Elm with the same approach. So Elm benefits from a different approach.
I think Boilerplate is the lack of a more succinct way of expressing your intent. So, boilerplate is never good in making things explicit, it's just the (current) shortest way possible to accurately expose your intent.
For example, in TypeScript, if I delve into making datastructures `algebra-ish`, I always have the boilerplate of defining a `tag` field in my objects, and lengthy switch-constructs to match on the tag field. It's not good in making things explicit, it's actually just the only way (at the moment).
Um... yea it does. Elm makes functional composition very easy which which means it's very easy to compose "components" (which are just functions anyway).
> - Only pure functions in Elm, so doing API calls and generating random numbers are unnecessary hard.
I would say that Elm makes doing API calls and generating random #s appropriately hard. Elm strives to corral side effects into one part of the Elm architecture: "commands". By doing this, you're keeping all code that contains side effects at the fringes of the walled garden you're growing.
I think this explicitness/discipline is needed in more codebases.
> - It's complicated to implement routing and to build a Single Page Application.
I agree, it's no Ember, which comes with all the bells and whistles of a full router system, including page transitions, transition errors, data fetching, etc. Richard Feldman has an elm SPA example on github that shows how to create routes, pages, etc. The official Elm Guide also has sections on routing, etc.
> So in the end, Elm is an interesting beast, but I think it's too academical and not really practical for serious projects.
Too "academical"? Tell it to these devs: https://blogg.bekk.no/using-elm-at-vy-e028b11179eb.
It's actually not that easy to write composable components in Elm, and attempting to do this has always been officially discouraged.
For the example described in the below article, I think channelPanel and chatPanel can be looked as components.
https://korban.net/posts/elm/2018-11-17-elm-ui-introduction/
IMO, this is one of Elm's biggest strengths. The Elm HTML syntax is a million times easier to reason about and build hierarchies in, than HTML. The syntax is cleaner and easier to read.
(For the uninitiated - each HTML tag in Elm is a function that takes two arguments - a list of attributes, and a list of functions that return HTML.)
This is completely the opposite in my experience. There is a massively strong hierarchy of leadership, core development and active users. All willing to help at all times. There are quirks, sure - but it is by far the most accepting language community I've been a part of. The Discourse has been a fountain of information: have never had an unanswered query before, and don't see many of them around at all.
Pure functions are definitely a selling point. Random number generation needs to be in an isolated part of your app unless it's a toy. Because it deals with IO much like reading from disk, it should have a "hard"-ness to it.
Good luck!
FWIW, I wrote this without having previous Elm experience—the compiler's error messages are so good that it was mostly trial and error until it worked.
To your point: I think using language primitives for defining views instead of HTML templating is an advantage for Elm because you can write them using only the Elm language itself, without having to learn yet another syntax. Combined with the excellent compiler error messages, it makes writing views easier and less error prone than writing HTML templates.
showUsers : [User] -> Html msg
showUsers users = div [id "my-component"] [ul [] (map showUser users)]
showUser : User -> Html msg
showUser user = li [] [
span [class "firstName"] [text user.firstName],
br [] [],
span [class "lastName"] [text user.lastName],
]What's even the "good luck!" part for? Good luck knowing about List.map?
How far do you think he got in Elm?
(def users
[{:firstname "john", :lastname "snow"} {:firstname "Peter",
:lastname "drucker"}])
(defn my-view
[]
[:ul
(for [{:keys [firstname lastname]} users]
[:li firstname " " lastname])])And issues: at least they are known and logged, and people discuss work-arounds, that's something.
Only pure functions: yeah, that's the point of a functional language, isn't it?
Variable shadowing: many languages don't have this, IMO it's a feature. You can always simply prefix local variables with "l_" or "a_".
Pain to build HTML in Elm? Don't get this. It looks slightly different, that's all. As soon as you start adding your templating code, it gets messy when you use HTML.
Yes but it gives you a nice guarantee that you will get a (handled) error at parse time, every time. In JS etc. you may never notice until you maybe render that one prop 4 levels deep under a certain UI combination and its a demo for your client.
Frankly, with something like serde in Rust, it's such a pain to deviate from the 1:1 case that you tend to stick to the 1:1 datastructure despite how suboptimal it is, maybe manually transforming it after parse time if you can be bothered. I don't find that to be any superior to Elm's simple combinators.
My experience with Elm's codecs is that there's a small learning curve if the concept is new to you. And then after some real world experience you wonder how it was ever alien at all. I wish I had it in every other language I've worked with.
http://hackage.haskell.org/package/aeson-1.4.5.0/docs/Data-A...
That's a very surprising oversight from a language that claims to be functional.
The problem is it lacks these advanced features for users that already know advanced FP, AND it has features that are too advanced for people that are beginners in pure FP. Elm suffers from trying to please everyone but pleasing no one in the end.
Of course it does. Exactly like React.
> It's complicated to implement routing and to build a Single Page Application.
not really. It's part of the core libraries in 0.19. Probably simpler than the "react-router" alternative I suppose.
> It's a pain to parse JSON
Probably for a beginner. But once you learn it once, it's trivial to handle most JSON cases.
> Elm avoids HTML
The opposite, the libraries are almost 1-to-1 mapping to HTML elements, so it's as close as it gets.
> I think it's too academical and not really practical for serious projects.
Most definitely not the case.
If you want to respond, try to have a more empathetic approach to addressing a newer users concerns than “of course it does ... not really ... the opposite ... most definitely not the case”.
If new users cannot understand how to do things correctly in the language, that’s a problem. Note that new users does not mean they are new programmers, simply new to your language or way of doing things.
> has given the Elm community a bad reputation
The Elm community is actually very welcoming. Not sure where you read about that reputation. I was also struggling a lot when I started, and the slack channel is extremely helpful. So you can go there, ask those questions and see if the above are true or not.
Not sure how to address them in a more constructive way.
You can state your exact same opinion without it coming across as dismissive just by stopping that one thing.
+ The language syntax is very nice and refreshing.
+ It's a joy to work with the compiler.
+ If it's compiling, it's working! No runtime exceptions.
+ Static typing!
+ Functional programming!
- The language doesn't have component composition (like in React or Vue) and you end up having huge chunks of spaghetti code (but to be fair, it kind of works because of the compiler).
- It's complicated to implement routing and to build a Single Page Application.
- Only pure functions in Elm, so doing API calls and generating random numbers are unnecessary hard.
- It's a pain to parse JSON.
- There is no variable shadowing, so naming your stuff is harder than it should be.
- Vue embraces HTML, Elm avoids HTML, and it's really a pain to build HTML view in Elm. <div><a href="hello">world</a></div> becomes div [] [ a [ href "hello" ] [ text 'world" ] ]
- There is a lack of leadership and community building in this project. We don't know what's going on and where the project is going. It's like a black box. No roadmap. All issues on Github, all posts on Elm Discourse get no response.
So in the end, Elm is an interesting beast, but I think it's too academical and not really practical for serious projects.