Hacker News new | past | comments | ask | show | jobs | submit | page 2 login
Elm changed my mind about unpopular languages (realkinetic.com)
509 points by lyddonb on Feb 19, 2018 | hide | past | web | favorite | 312 comments



> You probably can’t use it (Elm) on the server side

Some people mention this as a disadvantage. I think it would be cool to have a decent DSL dedicated to just frontends.


If one really wanted to... one could run a browser on the server to run a page powered by Elm, and then click on the page using Selenium style web driver. I'm guessing it wouldn't scale well :)

"What stack are you guys using for the backend?"

"SLEW: Selenium Webkit Elm LocalStoarge"

"Wat..."


I wonder how to become a good functional programmer. I think I'm already decent at procedural/OO.

Do I need to have a strong maths background? I didn't learn it very well at university and this worries me. Many functional language fans seem to have degrees in maths.


FP is mostly a state of mind - of course picking the language really helps about incentives, but you can do it even in Java/C# (in fact if you do C# there is the great LINQ library that helps).

How to approximate FP in a mostly OOP language:

- use immutable data structures: there is no way around being able to fearlessly modify something. The naive way is to copy the object before touching it, the better way is to use efficient structures, e.g. Clojure data structures from Java.

- you either have data classes (no methods, no private fields), or execution classes (no data fields, only static methods), no mixing

- of you stick to the above, you will find that returning void from a method is very difficult.

Congrats, you're doing FP: the gist of it is that it's all about keeping state explicit; if you pass some A in a function, you will return a B at some point, and that's your result. No implicit state.

Of course, we're missing the whole part about side effects, so to add to the above: if you cannot write a unit test without mocking something in your method, you're doing side effects. They should be done only at the "border" of the application, to (maybe) get you the data you need, so you can bring it and process it in the pure core.

And this is where languages like Haskell help: to understand where the side effects are (because they are included in the types) and to prevent mixing them around (which only gets you an untestable mess in the end).

HTH


What a great explanation of the "state of mind" of FP!


Math isn’t required. FP is about thinking of data structures and transformations from A to B. If you’ve ever used underscore.js, you’ve probably used FP patterns and functions. Map, filter, reduce are all part of that.


I don't think so. If anything I feel it's a bit easier as you don't need to reason about object state. It's also different, which is the main hurdle. If you use emacs you've already been exposed - Emacs Lisp is functional. If you're coming from a Web background both Elm and Elixir are great places to begin. You'll often hear stuff like "Javascript can be written in a functional style" - which is true, functional programming is a paradigm you can just go with - but seeing it really embraced by the language is really inspiring.


Pick a project. Pick a functional language. Code the project. That's it. It's not that different that, given enough willingness, you wouldn't be able to learn it yourself if you are decent at procedural / OO. You don't need any advanced math whatsoever.


Check out the humble functional bundle, two of the books in there are about the transition from imperative to fp.


> But when I joined Real Kinetic, I found out we were writing web client code in Elm. Elm? Really? The experimental language created for Haskell snobs who can’t handle stooping to the level of a regular blue-collar language like Javascript?

'bit of an odd thinking considering Evan's aversion to high-minded abstractions.


Elm is not unpopular: its just not yet common. its popular with people heading to strongly typed FP. GHC-JS


> "I don’t want to be the guy that finds a bug in the compiler."

When I'm wearing by "be productive" hat, I don't, either, but how realistic is that? Unless you've memorized the bug database for your compiler, running into a known bug is just as frustrating as discovering a new one, and I'm pretty sure I've run into at least a few bugs in every compiler I've ever used. According to my comments, my current flagship program has workarounds for 5 (known) compiler bugs.

I'd love to use only stable bug-free compilers (maybe Forth?), but I'm not sure that's practical. A more reasonable solution is to only use the popular parts of languages -- though apparently I'm not so great at discerning what those are, either!


At least you save a few hours when you look up the known bug


> Elm requires that you think through all the edge cases. You must consider and specify what will happen in every case.

Wouldn't that be the case with _every_ typed and compiled programming languages (or at least, every typed and compiled programming languages that support pattern matching)?


Not to the same extent, Elm:

* sum types and exhaustive pattern matching (incidentally, still not the default in GHC in 2018 because reasons[0])

* has only one escape hatch of "Debug.crash", which it strongly recommends not using and which it seems many Elm devs aren't even aware exists (in my avowedly shallow experience)

* and which you use as bottom by hand-rolling pattern matches

* at which point you might as well do it correctly

To the extent that you can require proper handling of everything, I would say that Elm is much stricter than Haskell or OCaml or Rust.

You can be very strict in them, but they don't enforce it to the extent Elm does. At least in my experience.

[0] https://ghc.haskell.org/trac/ghc/wiki/PatternMatchCheck


GHC will coverage check any case equivalent to one you can write in Elm. You can just write more powerful types where GHC can't tell that your case is exhaustive so it warns about missing branches that won't ever actually be taken. I seem to remember that perfect exhaustive checking for some combination of Haskell extensions is undecidable.


Pattern matching on GADTs will get you there, I believe.



exhaustive pattern matching


Exactly. That's why I started using F# wherever I can get away from it at work.


> Even though Elm is a small language with a small community, that doesn’t affect the Elm experience in a noticeable way.

This conclusion was pulled out of thin air, with no justification from the rest of the article. The title is misleading, the article is really about why the author enjoys Elm over JavaScript...

The general rule of thumb that a larger active community leads to faster software development is more or less still true. There is no reason to suspect this is not the case with Elm.

It's all fun and games until you get hired to build a production-grade web stack in a dinky game-scripting language with no community, that you have written 0 lines of code in. Some people live and breath to reinvent wheels in 19 different languages. Not my cup of tea.


> The general rule of thumb that a larger active community leads to faster software development is more or less still true. There is no reason to suspect this is not the case with Elm.

Yes, and not only because the volume of copy-paste source code on StackOverflow. I suspect Elm is slower to get a feature out, but once it is out you spend less time fixing bugs in feature A caused by adding feature B silently changing some assumptions you made in code. And so later on in the same project ... you are faster.

> It's all fun and games until you get hired to build a production-grade web stack in a dinky game-scripting language with no community, that you have written 0 lines of code in. Some people live and breath to reinvent wheels in 19 different languages. Not my cup of tea.

From what I have seen Elm is absolutely fit for production grade work. There is a community. The community tends to have smarter on average people in it. Simply because all the less smart people are put off. Sounds elitist? Maybe.


> There is a community. The community tends to have smarter on average people in it. Simply because all the less smart people are put off.

A community shouldn't be judged based on how smart everyone is (quite a difficult measure), a more useful metric would be how many useful community libraries there are. For example, if I can choose between 50 carousels implemented in React vs. 2 in Elm, and I'm an average developer -- what will I choose?

Modern JavaScript undoubtedly towers over Elm in terms of go-to-market time for arbitrary apps.

> you spend less time fixing bugs in feature A caused by adding feature B silently changing some assumptions you made in code.

This is a big problem with 2007 JavaScript and jQuery. React/Vue and other declarative VDOM frameworks bring the Elm philosophy to the masses.


> For example, if I can choose between 50 carousels implemented in React vs. 2 in Elm, and I'm an average developer -- what will I choose?

IMO this is an advantage of the smaller/smarter/niche (whatever you want to call them) programming communities. When they congregate around a couple libraries for common problems, those libraries tend to be very good. Speaking from experience in the Elm and Clojure ecosystems.

It’s much better in terms of developer time to evaluate 2 good libraries than 50 libraries where the quality ranges from abysmal to good.


> This is a big problem with 2007 JavaScript and jQuery. React/Vue and other declarative VDOM frameworks bring the Elm philosophy to the masses.

But ... in addition to npm/babel etc. you need a wetware constraint checker. React says "human: make sure your data is immutable - please don't forget or something might break later in production". Elm says "I guarantee immutability"


> A community shouldn't be judged based on how smart everyone is (quite a difficult measure), a more useful metric would be how many useful community libraries there are

That seems more of a metric for an ecosystem than a community.


It's presumptuous to assume "community A is smarter than community B". It's just not even the right question to ask. Better questions to ask are "what are third party libs like?", "how active are people in this community?", "how active is the SO and other forums?". These are actionable questions.

"People who use Elm are smarter" is simply not actionable information. What does it even mean? It's meaningless.


> It's presumptuous to assume "community A is smarter than community B"

You can e.g. Rocket scientists VS. Janitors.

Note what I am not saying (which people might take offense to) is "you use Vue not Elm, so you are dumb". Nope of course that isn't true!. I am saying in aggregate, due to selection biases etc, Elm attracts smart people. A lot of really smart people will stick to popular frameworks and not use Elm. Some bad programmers might use Elm for some reason. Aggregates are what I am talking about.

> "what are third party libs like?", "how active are people in this community?", "how active is the SO and other forums?". These are actionable questions.

These are good questions.

Another question though is: how much do I trust another library to not have bugs? Given Elm's design vs. vanilla JS, I'd go for Elm. That confidence extends to "How much do I trust a Library I knocked up over the weekend to solve an previously unsolved problem in Elm".


> It's presumptuous to assume "community A is smarter than community B".

To assume with no basis, sure; to conclude it may or may not be.

> It's just not even the right question to ask.

It's not inherently operationalized, sure, though (as seen elsewhere in this thread), “advertising jobs for platform A results in us needing to filter out fewer candidates with no real programming ability than when we advertise jobs for platform B” I'd pretty much an operationalization of it, and quite (to address your later point) actionable.


You're saying the "simpler" route will attract newer devs and dilute the skill pool.


> The community tends to have smarter on average people in it. Simply because all the less smart people are put off. Sounds elitist? Maybe.

Have you thought about the possibility that it's actually a community of people who first and foremost _consider_ themselves as being smarter than the rest? Maybe this is what's really off-putting to equally smart, but more humble developers?


Not with elm. Its a nice intersection of smart and down-to-earth / helpful types. And "smart" here means "conscientious, passionate developer smart" not "born with 200 IQ". I don't get any impression that elmers "_consider_ themselves as being smarter than the rest" from talking on the reddit etc. Haskellers though, I think it's a different story, but YMMV.


I tried and failed to pick up Elm. I've tried and failed to pick up a few FP programming languages. They tend to become more and more cryptic as I progress with them. I feel dumb, but I'm happy to stick with C like languages, like PHP for web development.


You can adopt some practices from fp when writing PHP. For example often instead of iterating over an array and doing some imperative sequence of modifications you can do a sequence of maps, filters and reduce... you replace error prone mutable code with more a declarative approach that says what you are doing clearly.


I've played with Elm a while ago and it's been a very nice experience.

I wouldn't use it for any frontend work just because I believe that it's possible to avoid single page apps if possible, but if I had to write a SPA I'd reach for Elm.

The only thing that makes me worried is that Elm 0.18 has been out for quite a while now and most of the development has been carried on behind the scenes by Evan.

This is good because it gives the time to the language to evolve in a coherent way instead of being a collection of bolted on features, but it also means that for outsiders is a bit hard to track progress in the language


> choose the one more people were using

After reading this article and reflecting on my own experiences and habits, my rule of thumb would be "choose the best of those with second-tier popularity." It's common that the most popular isn't the best, has advantages in numbers, but also disadvantages like low S/N ratio.

Many of the pitfalls of a scarcity are avoided, and can sometimes find a well-organized, curated, cultured pocket of enlightenment.


Programmers who believe just one stack is the right way to do things aren't probably the best hires long term.

While Tech evolves, being able to work with what exists and the future remains incredibly valuable.


I see that the current version is 0.18. Curious if the language has become more stable with fewer breaking changes than when I looked at it two years ago.


It actually has... due to not having any major release in 2 years.


So it's abandoned?


No. It is still being actively developed: https://github.com/elm-lang/core/commits/master / https://github.com/elm-lang/elm-compiler/commits/master

But it's been 14 months since the latest full release.


Can rewrite the example from the post:

  uniqueAuthors =
              books
                  |> List.map .authors
                  |> List.concat
                  |> Set.fromList
                  |> Set.size
as

  uniqueAuthors =
              books
                  |> List.concatMap .authors
                  |> Set.fromList
                  |> Set.size


Is it true that Elm is going to remove custom operators in the next release?


Yep, we are on ELM


I feel unpopular languages are best relegated for niche use cases the language is well suited for. If you are going to build something mundane like a CRUD App or a game, or an ERP, why wouldn't you just use some mundane blue-collar language like Javascript or its equivalent?

What you are doing isn't new or groundbreaking, so why bother bringing in extra drama and ceremony by using a language very few people use to achieve the same result? Just seems like added complexity for no reason, even if the code looks simple with the first pass.


> why wouldn't you just use some mundane blue-collar language

Because for something so mundane then it really doesn't matter what you use and you know the domain so well that you can recover from any hangups.

I certainly don't consider it self-evident that you always just use mundane solutions to mundane problems. Depends on your appetite for risk and how biz-critical the problem is.


I find this line of reasoning a bit strange. I've only dabbled a bit with some unpopular languages, but I don't think their limited popularity implies they're only suitable for niche use cases. In fact after using some languages (most recently Clojure) I find programming in other mundane languages like JS a huge step backwards.

People are probably the biggest determining factor in achieving a quality result. But I don't think that means we should forget about trying to improve our tools.


It’s not just about the language itself.

You might think Japanese is an awesome language and decide to learn it, but then what use is speaking Japanese outside of Japan? Around the world people still just use boring ol’ English, even though English is actually a pretty shitty language and full of hacks to make up for weird edge cases (read and read, goose and geese, mice and meese?, Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo)

Likewise, if you write something in Clojure, you have far less people and libraries and platforms that can help you accomplish whatever you are doing. If what you are doing is not something new or groundbreaking that could only be done well with Clojure, then the extra effort you have to spend to get up and running is not worth it.


I have thought about this problem some and currently see it as an issue of scaling thresholds.

If it's literally just you, there's a lot of benefit to leveraging existing work so that you can focus on the differentiating part of the project(which is probably not a language innovation). It's not just the libraries but the whole ecosystem - example code, troubleshooting help, IDE support.

If you have an engineering team of even modest size, the picture can change very swiftly towards ensuring your result is built on a solid foundation, even if it means a lot of pioneering infrastructure has to be built and a lot of late nights spent debugging core toolchain issues. Team efforts have the necessary momentum to break free and do that ground work as the overhead gets swiftly absorbed in "person-year" budgetary terms. Individuals can only really justify the same as their core direction of research, sole hobby, or speculative investment - e.g. being the "first to implement" some hot new standard could be a well incentivized career move.


That argument may be true for other languages, but Clojure is a hosted language which means you have access to all the libraries created for that mundane Java language (should you need to use them).


>I made it a hard and fast rule: if I found two technologies that could solve a problem, I would choose the one more people were using. I didn’t want to include an obscure graphics API and then discover that no one had ever called set_color() followed by resize_window() (resizing is hard) and somehow those two functions in sequence cause a segfault. I don’t want to be the guy that finds a bug in the compiler. I just need to ship the product.

Then he links to issues for Qt and Go. They're certainly not obscure. What kind of weird argument is this? If anything, the argument there is that it doesn't matter how popular something is, as even extremely popular things like Qt and Go will still have bugs.


Nowadays it's really easy enough to use real Haskell in the browser with GHCJS, and FRP libraries like Reflex provide a much more complete experience than Elm's restricted form.


I used to use Elm, then I moved to Pine, then Mutt (which is still going strong)

I guess there's only so many names in the world, and they're bound to be reused.


True, I still think article with ML in the title are all about ML the programming language.


This is why I'll never be a web developer. "Let's drop names! I made bridges out of Wood.io, then I used Steel (TM), now I use Stone.js. What's fun, now there's data in the kiddie pool!"

It feels like watching a cult of optimization function in a culture where measurement is taboo. It's absurd beyond belief.


That's fine. I don't think the ecosystem needs any more people that get their blood pumping over some inconsequential name reuse.

To get Elm confused with the email client with this title, you'd have to not know the Elm language existed. So it seems like it's a moment to go "oh I see, that exists" than cursing the world because you thought "Elm changed my mind about unpopular languages" somehow referred to an email client.

But I get it. It's cathartic to be angry on the internet. The angry shadow boxing just gets pretty old for the rest of us no matter what kind of developer you are.


I'm talking about the uselessness of saying "I used X, now I use Y." WHY does one change what one uses? For reasons supposedly. But of course nobody ever provides reasons. It is enough to simply drop names. Print out your resume. Because heaven forbid anybody provide some real data that shows why one platform is better than another.

I'm certainly not confused about what Elm is. That'd be easy enough to find out. But "why you stopped using it" sure as shit isn't something I can google.




Applications are open for YC Winter 2020

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

Search: