How come no one (seemingly) uses Elm, despite all the love? I've noticed a lot of quick, drive-by posts in Elm related threads about how great the language is. This thread ("This is a great little webstack!") and today's other front-page elm thread[1] both do this.
With such high praise, I would expect the language to be more popular. What's with the disconnect? My hypotheses:
1) There are no unhappy users because unhappy users just don't use it.
2) HN goes easy on technological curiosities, saving harsh criticism for large projects that deserve it
3) While there may be a widespread lovefest for Elm, there is too much momentum behind current technologies.
Any other thoughts as to what the disconnect is? Moreover, how do we get to a world where the webstack we all use is "a great little webstack"?
Elm is very new in the grand scheme of things and it was considered experimental for quite a while. The recent changes show that its developers are still willing to make big changes. But I do believe it's stabilizing quickly and I wouldn't be surprised to start seeing it used a lot more, though still mostly in smaller hobbyist projects simply because even if it stabilizes it's still so new that you can't expect larger companies to risk anything on it.
Elm is a lot more experimental than Elixir, for instance. Elixir is still built on the classic Erlang BEAM virtual machine. And its syntax is fairly similar to that of Ruby, which is an immensely popular language among web developers. Elm looks like Haskell, though, which very few developers are competent with. It was originally based on FRP, which has long been considered highly speculative and theoretical. But I think by shedding FRP it's growing into a very practical language, and while it has a Haskell-lite syntax, it's considerably easier to use than Haskell.
I'm looking at Elm for a product that I'm working on at the moment. The language is great and I've wanted an excuse to do actual work in an ML-like language for a long time.
The difficulty I'm having at the moment is just trying to find examples of non-toy application architectures. An application with multiple top-level screens, for example.
For a bit of context, the product I'm working on is a customer-facing kiosk. It'll be driven by a C# ASP.NET back-end. We have several different products using common back-end code but exposing different sets of features to the customer. We're moving from an old architecture that was your standard WinForms UI to something using HTML5 as the UI layer (definitely a big mindset change!).
Right now I'm trying to figure out what the front-end Elm code structure would look like. Is it going to be one huge monolithic Elm project that covers all our cases? Can it be broken up? Does the front-end have to know in advance what screens will be available? (the back-end uses the typical 'load features as plugin DLLs') etc. These are all questions I'm facing right now.
This is especially exacerbated by the recent change from 0.16 to 0.17. The changes themselves seem extremely positive (I jumped in at 0.17, so I'm only going off an impression here) but much of the example material that I've found which might be useful is still using stuff from 0.16 and I'm having trouble wrapping my head around it right now.
So from a commercial dev perspective, Elm, like anything else so new, is massively risky. I'm pushing on for the moment (would love any pointers if anyone has them!). I'm aware of the huge element of "not knowing what I don't know" that I've taken on right now. I'm hoping the payoff will be worth it :)
I'm also looking for more structured examples but so far haven't found much. These are some apps that go a little beyond the "hello world" kind. Some of them are being updated to elm 0.17.
http://package.elm-lang.org's source code is online and implemented in Elm. Not a large application, but it demonstrates a way to break up components like the header, sidebar, and a main content area across files. It's maintained by Elm's creator and stays up to date with Elm upgrades.
Elm is still way too immature. You either end up rewriting a lot of code that might otherwise already exist as a library or you simply cannot use features because they don't exist. If you hang out on the slack channel you'll get an idea of what the language can and cannot do right now. It's also worth remembering that it's a technology that doesn't have the weight of a big company behind it so pace of progress is relatively slow.
I would probably agree with your first 2 hypotheses. However I don't really see any momentum against Elm. Just the opposite in fact. There are other projects that have the same kind of goals such as Purescript or GHCJS but Elm is the one with the momentum.
Thanks for the idea to look in on the Slack channel; I had no idea there was one.
>However I don't really see any momentum against Elm. Just the opposite in fact.
I just edited my comment to reflect that by "momentum against Elm" I meant to suggest that Elm is fighting against momentum that is currently behind technologies like JS, angular, react, etc. in the web programming community.
Elm is the coolest, best programming language ever made for practical purpose and adoption by the mass...that cannot be used for practical purpose and the mass because the FFI for libraries is a private API (the "public" FFI only let's you interop within your own application/world, making it hard to wrap libraries or build libraries that do interop).
So it's basically a language we desperately want to use, but can't.
I hear this criticism about ports a lot. Out of curiosity, how could we make it better? Do you have any examples of what you consider to be the ideal FFI? I haven't used ports a ton, but I have used them for interop between Elm and the Google Maps Javascript API, and I didn't think it was that bad.
The problem isn't that it doesn't work. It's that what you do with ports only work in the context of your application. The JavaScript part has to be defined somewhere else, the Elm code assumes the JavaScript part will be there. You can't redistribute that easily.
How to make it better? that's easy. IT ALREADY EXISTS and is part of Elm. It's just a private API. But it totally does work. It's how the native wrappers are written.
Ports use publisher/subscriber. If I want to, let say, wrap moment.js, which is just a bunch of synchronous functions, how would I do it? Dispatch side effects to "compute dates" and listen to the "response" in my update method? That would be silly.
The port system works beautifully to interface with the outside world. It is very poor to bring the outside world in.
> How to make it better? that's easy. IT ALREADY EXISTS and is part of Elm. It's just a private API. But it totally does work. It's how the native wrappers are written.
The Native interop changed with core >= 4.0, so that relatively straightforward way of accessing native js no longer works, and the new Native is (deliberately, I believe) undocumented.
In a pre-1.0 language, this should be entirely expected. It's bleeding edge a bit, but I've yet to find someone who used it to build something non-trivial and wasn't sold on it. There's definitely some survivor bias there, obviously.
For the record, I looked at Elm over 2 years ago and completely dismissed it. I regret that strongly now as I am extreeeeemely happy developing with it and I can build stuff in far shorter timelines with zero runtime errors than I could in react even (which was a high-watermark before Elm for me in that respect)
The JS community has been pretty good about taking ideas from Elm. Redux is an insanely popular JS library that is basically a replica of the Elm architecture (though, having used both extensively, redux doesn't come close to the beautiful simplicity of Elm).
As far as why people don't just use Elm, I think it's the same reason functional language are less popular in general: fewer familiar engineers and steep learning curve.
Yeah, I had mentally tagged Elm as "interesting language that future browser languages/frameworks might claim as an inspiration".
But, I thought the same about Coffeescript. And then Rails gave it massive traction. I wonder if the same might happen to Elm, should Phoenix adopt it as their browser language of choice. That might also offset concerns about Elm's fledgling status and key man risk.
I wonder if the same might happen to Elm, should Phoenix adopt it as their browser language of choice.
There's definitely a connection there -- for what it's worth, the keynote at 2016's Erlang Factory conference was a shared talk between Chris McCord (creator of Phoenix) and Evan Czaplicki (creator of Elm),
"Making the Web Functional" [0]
Having used them both quite a bit I really cannot say that Redux is much at all like the Elm Architecture. It separates views and state machines. This works well for managing state in an application-wide sense but complicates state which is more local to your components.
Coming from Haskell, I kind of dismissed it on the basis of missing a construct like interfaces/protocols/traits/type-classes, and started checking out purescript instead which is closer to Haskell. Eventually stopped using purescript due to some unbearable compile times (in purescript's defence it was early on in it's development, and it's still pre 1.0).
All that said, I'd probably check out elm now only because I've heard good things about it's developer experience.
Like any new language (including Elixir), it's rare in the wild. Elm is also an ML and looks "weird". Give it a few years.
Elixir is getting bigger with Dockyard and Pinterest using it among others, though it has the benefits of running on proven technology, having an "easy" syntax, and Phoenix.
This is a great point, and I think it is because the language is still really new. The language syntax and patterns have just firmed up with the 0.17 release. I think it just needs some time for additional adoption.
I've been playing with it over the last couple of days. Having dabbled in Haskell in the 90s it all feels familiar and clean. Really quick to get up and running and the compiler / messages definitely give a lot of guidance.
I'm not deep enough into it to really assess yet, but I suspect the difficulty is how you integrate it with existing JS code. It feels like maybe it's an all-Elm or nothing world, which makes it hard for organisations to take it for a test run when they have an existing codebase to play nice with.
My exploration is an ongoing activity to figure out which framework / methodology is best to continue building our existing product on. We're currently using Angular (1) and some react components. I did some prototyping with Redux (including investigating Sagas) and familiarised myself with RxJS and MobX. I found the boilerplate in Redux distracting some I'm still looking to see what else is out there – would love to hear how others are assessing these tools.
You can easily "sprinkle a little elm component in" for what it's worth to try it out in production. I know NoRedInk pulled it into a heavy React-based project. You basically set up intercommunication between components via ports. It's a fantastic solution once you grok it.
And the other way around? What if you had a big existing submodule in JS that you wanted to make use of within an Elm app? Is that doable?
One of the things that's really attractive about React is that there are already a lot of components you can drop in to handle behaviours for you. If I could somehow utilise those within Elm, it would lower the entry barrier for me.
:) Ok, I'm going to take your word for it! Hopefully I should get to that stage tomorrow and it will all become clear.
It's not that I even have a clear picture of what I need to achieve but with each of these different tools I'm trying to poke at them to see where they fall down. So far, Elm feels the nicest, but it's the smaller ecosystem / lack of libraries that's the most obvious shortcoming so I'm trying to understand what the options are for interoperability on that front.
Go to the Elm home page. View source. Things have swung too far to the JS side. I'm not going to force my users to have to use that. The beauty/accesibility/advantages of the web architecture is being lost to things like this.
That's pretty unfair given the fact that it's 0.17. Before this release, server side rendering was possible but super weird. This release includes most (all?) of the big changes necessary to make the server side rendering story great. This is already basically done but not yet release ready.
Please don't reject something based on its current (admittedly not 1.0!) state based on assumptions about its future! Evan and co. are in fact extremely smart and by no means does anyone consider Elm "done." I'd suggest playing with the language itself. That's the important part - not the state of the current runtime.
I walked away from Elm still being very enthusiastic about it and watching its progress.
I started coming to Elm hackathons in 2014, did a few helloworlds of increasing complexity, eventually tried to write a portion of my app in Elm; there were ups and downs and then one of my (very few) customers asked me to create an API call to something that was happening in the browser. This code was written in Coffeescript, and I had to clean it from DOM dependencies (it builds a complex SVG and then just inserts it into the DOM, so that was relatively easy) and integrate with Express. Auth, cookies, all the usual stuff and the prototype was ready. And then I realized that if I had this code already rewritten in Elm, I'd have been busted. I could easily imagine someone else wanting to have the portion I was writing in Elm as an API call (it was another complex SVG) and for that, I would have no known course of action.
Elm is not just a language, it's a language + frontend UI framework. It is theoretically possible to run Elm code under Node, but the relative level of craziness is similar to "writing a C++ compiler in Angular", please let me exaggerate a bit :-)
After this adventure, I realized that having the ability to share code between server and client is too indispensable for me to trade for lack of runtime errors.
Native interface - I use a lot of js code already written by somebody else. I have a very extensive data manipulation library developed in Coffeescript for my application. It's proven, tested, documented and presents a solid foundation for whatever I decide to write using the data I have. I want to use this code freely. In Elm native interface is frowned upon and the official way is to use ports, which is quite cumbersome, especially for procedural libraries.
As an OSS project, Elm is too centralized for my taste. I'm fine writing helloworlds, toys, learning projects, etc in the language that is being designed and developed by a single person not accepting contributions from the public, besides probably a very small curated list (not sure about that part). But for the business, it's just too much risk yet.
I moved to Purescript. I haven't yet started writing for the browser yet :-) but so far Node and Google Apps Script were doing pretty well. In a sense as a language Purescript is both more demanding (it's much closer to Haskell than Elm) and more forgiving, more javascripty in a good sense of this word, just a part of the toolchain, not pretending to be an ultimate answer to everything. The native interface is best in class.
Frankly, for the category theory idiot like me, Purescript is easier than Elm, while Elm is considered much simpler exactly due to many compromises with "The Math". Almost every decent beginner-friendly Haskell book will work for Purescript, you don't need to break your head over "Elm doesn't have monads, but it does have Effects and Maybe and what not, which are technically monads, but we don't call them monads, etc...". Maybe for others it's different. I can recognize design decisions Evan made and why he made them and I'd like to see how it goes. But I'll watch from the sidewalk for now.
Elm keeps sounding like a great language, but the fact that it locks my code into a web browser, with no headless way to run it, is a deal-breaker indeed.
server-side is coming, but Evan wanted to be very smart about it. I.e. don't just default to "run in node all will be well". There is a concurrency layer that's being introduced (see Process) and I'm hopeful it will eventually run on Erlang's VM (seems likely atm but time will tell)
This is because in Elm a runtime error is a compiler bug. If you want no runtime errors, interoperating blindly with JavaScript is a great way to fail :-\
Another great thing about the community is a goal of a single great library for every use case, rather than a lot of half-baked competing libraries. So expect there to be a single great modal library. Etc.
As a corollary to what shados was saying, now that 0.17 is out the elm-lang organization will make a library to cover every single part of the web platform [0], at which point you will never need to.
I'm no Elm expert, but as far as I understand, the "native library" APIs, the kind that are used to actually wrap browser APIs and interface with javascript in a way that can be published and made reusable, is "private". I mean, you can look at the source and make your own, but you're playing in undocumented, unstable territory.
The only "official" interop channel is the "port" system, which only lets you do a publisher/subscriber type thing with your application at runtime, and cannot be used in a library.
So you basically cannot make a "blessed" library that uses native browser APIs.
Josh from DailyDrip here. My first realization that this was here was that we started getting a ton of traffic. :) We just ran the first Remote Elm Meetup today so my attention was elsewhere: https://www.bigmarker.com/remote-meetup/1-Elm-Remote-Meetup-... (yes, I know our company name is misspelled in the url :-\ )
I'd love to chat with anyone that wants to know what we're doing and why we do it :)
Obviously thrilled, thanks. All we want to do is keep making awesome content, and every customer helps us on that path. Let me know if you have any issues, ok? Obviously I've tested the crap out of it, and we have a decent number of customers, but this is our biggest traffic day by 4x already.
I ended up learning Erlang after hearing about Elixir and not being a fan of the Rubyish syntax and immutability comporomise, which has been a very rewarding experience. Haskell even more so. And Purescript has some nice Elm inspired libraries [2].
there is no "immutability compromise" in Elixir. Static Single Assignment != Immutability. Elixir is entirely immutable - it has to be as it just runs on the Erlang VM!
I think a legitimate complaint along these lines would be "pinning is confusing and error prone for beginners" and I think it's fair. Christopher Meiklejohn mentioned this on Twitter yesterday, and it's a point that's caught me plenty and I write more Elixir code than most people by far.
> the structure [1, 2, 3] still exists in memory, but now the variable x is bound to the value 2
I wasn't talking about data, I was talking about variables. Yeah you just called it "re-binded". I called it "changed" or "mutated".
You have a function, and you see x=1 first and print its value. You'd see "1". Then you can have x=2 maybe a few lines or pages below, print it, you get "2". Variable x has changed its value. I even illustrated with a short example.
> All data is still immutable, the BEAM itself requires so. All data is still immutable, the BEAM itself requires so
Agreed. I don't think I ever talked about data being mutable. Having used BEAM VM for the last 5 years, yes, I noticed data is immutable ;-)
It's not mutated or changed it points to a totally different memory location. It's called immutable data not immutable identifiers. Immutable data is what eliminates a large number of potential bugs. Having a ton of intermediate variable names
could actually be a source of bugs plus you have to care if someone reuses the name above the point in code you used it. By allowing rebinding you only care about the code below the place your introduced a variable.
> It's called immutable data not immutable identifiers.
immutable/mutable data and immutable/mutable identifiers are two different things. One is not called the other, they are separate things really.
> It's not mutated or changed it points to a totally different memory location
So you said it yourself. It points to a different memory location. So how is x not mutated then? "Mutated" is a synonym for "change", or so I thought apparently.
I don't see how one can look at a variable being reassigned and say "nope, variable didn't change", where it clearly has a new value in the line below.
> Immutable data is what eliminates a large number of potential bugs.
Agreed. Was using Erlang for many years and tried Haskell before. Immutable data is pretty nice most of the time.
> care if someone reuses the name above the point in code you used it.
Wait, is it the opposite of what you were trying to say? Wouldn't you want to care if you are now randomly re-using or changing variables someone else assigned. I thought immutability was a good thing.
> By allowing rebinding you only care about the code below the place your introduced a variable.
Unfortunately in my code base, the code above the place where variables are introduced is just as mission critical as the code after the place. Maybe I am using a strange coding style or paradigm ;-)
This summarizes my thoughts on "compromise" exactly. It may be a good thing to some people but it was still a compromise to change it for potential benefit in exchange for some potential loss of strict identifier immutability.
I prefer the way Erlang does it. But I get why Elixir did what they did as well.
> You're calling renaming something mutation. It isn't.
I think you are confused though ;-) There is no renaming -- x=1, then x=2. Nothing was renamed. x wasn't renamed, it is still variable x. 1 and 2 wasn't renamed, it is still 1 and 2 (could have been a map, or list for example). So what do you think was renamed there?
> You're referring to static single assignment.
No, I am referring to immutable variables. Variables are not changing, they are immutable in Erlang. In Elxir variables change, they can be assigned different values later in a function. If that is not a change i.e. a mutation I don't know what is.
We love this stack, and dailydrip and elixirsips have helped us get a lot of the knowledge we have. Josh does an awesome job at explaining the technology in a step by step fashion that is both concise and easy to understand.
They're both very functional, but it's an interesting matchup given that Elm is very strongly typed and (according to my understanding) Elixir is totally dynamic. For those who are developing with both, I'd be interested in hearing if there's a reason why types would be more useful on the client than the server or whether there's another motivation for those particular choices.
Also, Elixir community... there seems to be a paucity of awareness of Dialyzer and Typespecs. Perhaps they could be more prominent? They're included in the reference docs, but not really so much in a way that indicates what they are or how one would use them when writing their own software in Elixir.
There are many, many classes of problems that can be discovered before they're discovered at runtime. It's made a little harder in Elixir-land due to limited Map support in Dialyzer and Map usage being extremely common in Elixir code, but still spec'ing your functions is a good practice and habit to get into anyway.
Erlang 19's included Dialyzer improves the scenario of type-checking maps in useful ways. Namely that now you can represent an empty map, an arbitrary map of any type, and a partially arbitrary map which must include certain key type and value type associations but is not limited to those. Which leaves out one representation which is a map which includes and only includes a specific set of key type and value type associations.
Erlang 18's Dialyzer has basically just #{} =:= map() which is equivalent to the union of #{none() => none()} and #{any() => any()}, so it was basically a giant escape hatch in the type-checking system, and thus not particularly valuable.
Looking forward to a pending change in laxness as a result of the coming changes in 19. :-)
I think the static/dynamic client/server split is more coincidence than brilliance.
Elm and Elixir are like two neighborhood kids growing up together as best buddies. They are both new, functional, webby languages with communities that are very friendly and very interested in inventing new ways to make programming better. It's natural that both groups would be excited about working together.
I'm glad to dive in. On the client, fault tolerance is basically not a concern of mine. On the server, it's the most important concern. I find it more useful to think of Elixir as a highly concurrent language built for fault tolerance, where Functional Programming was a necessary requirement to get there. Jose has a great post on this here: http://blog.plataformatec.com.br/2016/05/beyond-functional-p...
What makes Elm + Phoenix so good together? I use Elm professionally and love it, but a back end is a back end. Is the love just "I really like Phoenix?" The way people talk about it makes it sound like it is uniquely suited to Elm, which I don't understand.
With such high praise, I would expect the language to be more popular. What's with the disconnect? My hypotheses:
1) There are no unhappy users because unhappy users just don't use it. 2) HN goes easy on technological curiosities, saving harsh criticism for large projects that deserve it 3) While there may be a widespread lovefest for Elm, there is too much momentum behind current technologies.
Any other thoughts as to what the disconnect is? Moreover, how do we get to a world where the webstack we all use is "a great little webstack"?
[0] https://news.ycombinator.com/item?id=11846707
edit: clarity