Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
The Erlang Rationale (rvirding.blogspot.com)
211 points by lelf on Aug 9, 2019 | hide | past | favorite | 38 comments


I think the world of Joe Armstrong (may he rest in peace), and was really excited about jumping into this world. In practice, I think this philosophy is better on paper than in the real world.

Start with message passing over multiple processes. The Erlang/Elixir ecosystem leans toward lightweight processes and message passing for everything. Isolation is great, but it has a cost. Part of that is paid in reduced inspectability. Good luck getting a meaningful stack trace, or figuring out what someone else's code does, when even the simplest action is split over a half-dozen concurrent processes and supervisor trees. I know it's a bridge that eventually has to be crossed, but a very expensive one!--like pouring the foundation for global HQ before the first customer has even signed.

Dynamic typing is another pain point. Wrangling types is not fun, but to keep growing something, they're non-negotiable. Facebook and Hack. Microsoft and TypeScript. The preponderance of C# and Java in the enterprise world, and C++ in games. These weren't accidents of history. Without mandatory compile-time type-checking, re-factoring eventually becomes so perilous that it is avoided, and the product withers. Why they chose that in a "robustness" language is a head-scratcher.

Also, the compiler is slow--which wouldn't be so bad if it caught more errors (like type mismatches), but it doesn't.


In my experience the stack traces from Elixir (or even Erlang) are pretty useful. Sure there isn't a full stack trace back to a main function however that really isn't different than a framework with any level of indirection. Given the choice between a C#/Java stacks trace 40 lines deep and a BEAM stacktrace of only 6 lines I'll take the latter. Even better you get both the value of the last received message and the state of the process in the stack trace makes reproducing an issue simple.

Based on what you're saying given the lack of inspectability it sounds like you haven't tried out some of the introspection capabilities of BEAM. Maybe you have, but I've seen little that compares to the Observer module that comes included in a language. Realtime introspection of processes and the ability to see the message queue for any process makes inspecting the whole system very interactive and powerful.

There's a point that message passing lowers max performance, but given the rise of multicore processors it's pretty powerful platform. Future hardware likely could weaken memory coherency between cores which could be taken advantage of by BEAM. Overall it takes a different mindset to work well with Erlang philosophy IMHO.


I'm getting the same issue with async/await in Javascript and I'm worried about the same happening in Rust.

There should be a way to extend these traces. I don't know what the costs would be like to trace back across calls, but I would expect they should be somewhat reasonable in the case where the caller expects a response (you already have the bookkeeping and the stack frames).


>As of V8 v7.3, --async-stack-traces is enabled by default. https://v8.dev/blog/fast-async


Yeah we aren't on 12 yet. In fact we just got off of 8.


Agreed that the tooling is good. I just think not having to inspect multiple processes and message queues is better.

Whenever I've really needed concurrency and robustness, I like OS processes better. Not as lightweight, but I can keep the logic in each component mostly sequential, use the best language for each component, use the tried-and-true OS tools for monitoring, and moving a component to run on a different box is trivial.


Regarding message passing, it seems that everything you said applies to a microservice architecture. Yet people do it in hopes of scalability.


"like pouring the foundation for global HQ before the first customer has even signed"

I think this is a bad paradigm for early-stage software. It's premature over-engineering. It's taking a fundamentally sequential process, and busting it up into a nest of messages and concurrent LWPs that "fail fast" when all of that could be easily foregone by just staying lean and handling the errors.

I also think this is a bad paradigm for large-scale software--jamming all of the pieces into one dynamically typed language/VM with its own bespoke distributed protocol and monitoring tools. Common standards like HTTP/RPC/GraphQL/etc are far more flexible at connecting the nodes, and BEAM has a long road ahead to catch-up to existing OS tooling.


The difference is you scale your microservice across many machines. Sure you could probably do this with Erlang but that's not the kind of perf the parent is talking about

I do agree that there's a striking resemblance between the goals of Erlang and the goals of microservices though.


Should be of interest to anybody interested in this, Joe Armstrongs Ph.D. thesis: http://erlang.org/download/armstrong_thesis_2003.pdf


I'm about halfway through the meat of it, it gives alot of good insights and Joe's writing style is very easy to read through


Came across it from the reading list on the Alan Kay post. Good to hear its an easy read, might sit down and dive into it tonight.


Is this better of an introduction to Erlang (and in general distributed fault tolerant systems) than other sources (e.g. programming Erlang)? I come from a telecom background and worked on high reliability/robust systems, somewhat on the principles of this book [1]. Wanting to learn Erlang.

[1] Robust Communications Software: Extreme Availability, Reliability and Scalability for Carrier-Grade Systems - Greg Utas


Am a noob in Erlang studies but i have settled on the following three books.

1) Introducing Erlang: Getting Started in Functional Programming. - Just to get an easy intro.

2) Programming Erlang: Software for a Concurrent World by Joe Armstrong himself.

3) Erlang and OTP in Action - This one seems to be the advanced book.


What other books would you recommend to study about programming High Reliability/Robust/Fault-Tolerant systems?


A not very useful level of indirection: it's a blog pointing AT the Erland rationale, not the rationale itself.


It's a shame that the elegance of Erlang has been distorted with Elixir.


Notably not the impression Joe Armstrong, creator of Erlang, had when he tried Elixir out for a week:

> This is good shit. The funny thing is that Erlang and Elixir are the same thing under the surface. They “feel” the same to me.

https://joearms.github.io/published/2013-05-31-a-week-with-e...


It’s a shame this thread has to be spoiled by off-topic criticism of another language. Why even bring it up? You can promote Erlang without tearing down Elixir.


I don't particularly care for Elixir, but it's kind of nice having more people on the BEAM.


I don't think the above comment is put in the best way...

But I do have a certain duality about my feelings on Elixir

On one hand, yes, it is cool to see more adoption of BEAM, I do wish Erlang could have done that by itself.

I vastly prefer Erlang to Elixir and find it does slightly... taint the simplicity and cleanliness of the syntax Erlang made made me fall in love with, just to be Ruby-like.

I don't feel it actually benefits the language at all past the meta reason of attracting Ruby-ists (which again, isn't necessarily a bad thing by itself)


It's interesting that you would say a language could 'taint the simplicity and cleanliness of the syntax' of another language. You can still work purely in Erlang and not deal with Elixir can you not?

I'll say my own personal experience is that I knew of Erlang but had never really looked into it or knew of the benefits of OTP and BEAM. Being a Rubyist, Elixir bridged that gap for me and I've been reading more and trying to learn more about this new (to me) environment.

I would also say that Elixir has benefited Erlang because José hasn't just built Elixir, but has gone and helped implement new things into Erlang; the entire environment is benefiting from drawing in new engineers.


My problem with Elixir is kind of similar to C/C++. Interfacing with C code from C++ is easy, interfacing with C++ code from C isn't easy and you end up with loads of ugly wrapper code. The same goes for Erlang and Elixir, interfacing with Erlang code from Elixir is easy, interfacing with Elixir code from Erlang is ugly. And the more people start writing code in Elixir I fear that more people are turning away from Erlang. And even if the entire environment in total benefits from more people using Elixir, that environment will more and more turn into an almost pure Elixir environment with very little of Erlang left.


It's interesting how your comment seems to be trying to refute parts of mine... yet says nothing contrary to what I've said, and in fact repeats a lot of it, but in different words

I mean, I didn't imply you can't work in Erlang, and I already stated drawing Ruby-ists isn't a bad thing... so I guess I don't get why anything but the middle paragraph was needed here.


The advantage isn’t Ruby syntax - it’s the macro system.


Macros are the perfect example of things that go against the core of why I love Erlang.

Erlang actively makes it hard to write hard to maintain systems because it's syntax is so lean, there's no way to make your FactoryFactoryBeanFactory

Macros can easily be abused, and to me the biggest gain I've seen is removing OTP boilerplate, which is not that much compared to what you get out of it

I will say I haven't used Elixir in anger so I don't know if people are doing more with it now, but I'd just rather not have it.


I feel the same way. Elixir users keep banging on the macro drum but most Erlangers don't want them.

I can read any Erlang program I wrote 10 years ago with ease. I have difficulty understanding a small Elixir project I wrote just a few months ago.


This is subjective. I never wrote a macro in Elixir after two years of being paid to work with it. I remember I studied Erlang in 2010 and I was like "great concepts but the syntax is horrible, no wonder it's very niche." I never wrote anything with Erlang but I can read it. I looked at Elixir when it was at one of its early versions and I could immediately work with it. I wrote some code and eventually got a customer.

This could be affected by my background. My trajectory is 99% in the imperative set of languages. BASIC in the 80s, a little COBOL and Pascal, a lot of C and Perl, some Visual Basic, a few PHP, a little eLisp, some Java, a lot of JavaScript for the web but mostly Perl until I picked up Ruby on Rails in the middle 2000s. Some Node and some Python until I got a customer with Django. I'm mostly work with Elixir, Python, Ruby and some React now.

I script in Ruby for myself. The Python ecosystemis for the web looks complicated by design (but simple compared to Java), Elixir is OK for large projects, too cumbersome for small ones.

I sincerely dislike the syntax of GenServers (this would need a blog post) and Ecto is unnecessarily complex and a productivity sink. But the Elixir and Erlang way to pattern matching is heaven.


Almost no one writes macros in the elixir ecosystem though, only the biggest players (phoenix, ecto, exunit).

I have no problem reading my elixir code from a year ago. The erlang otp tftp module, by contrast, is indecipherable, with three layers of module indirection I had to fight against (there was a fatal bug with a misspelled atom that I couldn't trace the code path to). In the end, I just wrote my own tftp.


Exactly right. I can easily read my Erlang code years later. The syntax is so simple I can teach it to someone in a day.


Erlang has macros though? Did elixir add something to it?


That's funny because I think that the syntax of elixir is simpler than that of erlang. Records, for example, are rather atrocious, and meaningful line terminators makes code slightly harder to read, and reuse and refactoring... Annoying. And then there's header files...


I feel the same way - Erlang looks like someone mashed their face over their keyboard, whereas Elixir looks simple and readable.


What’s been distorted?


"The language should be simple – Simple in the sense that there should be a small number of basic principles, if these are right then the language will be powerful but easy to comprehend and use. Small is good."


Elixir has Erlang semantics + hygienic macros and a few other niceties. Judicious use of macros in libraries can actually make the experience simpler for the developers.


If both languages have the same semantics, why choose the one with more complex syntax?


Syntax complexity is highly debatable topic. It involves complexity of parsing (by machine), reading and scanning(by human), conciseness, coherence of syntactic constructs and more things I don’t know. I wouldn’t say prolog based syntax is necessarily simpler than ruby(?) based one in all those categories.

Of course only LISPs have achieved syntax perfection, all hail LFE and other lispy fronts to erlang!




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

Search: