So a net reduction of 60K lines of code? And yet functionality was added to the system as well. That's praiseworthy IMO.
Imagine if "we did more with less" infected much of software development today.
I'm not trying to fractally compress my code. I'm trying to make it succinct. Those two things are very different. Now if I could only convince a particular coworker of that...
1. Make it so you'll understand it in 2 minutes after being away for a year. Positive side effect: it's very readable for your colleagues.
2. Make it brief.
3. Make it fast.
4. Make it pretty (although often times readable + brief code is pretty but obviously it's subjective).
So far I've gotten a lot of pushback from others on my team. And, what starts as "oh, you should just have to ____" gets really messy as the implementation takes shape.
Yup.
> Imagine if "we did more with less" infected much of software development today.
Taken to its logical conclusion this should mean that the ultimate piece of software, that does everything and does it perfectly, is 0 LoC.
Hmm, fells like I need to check my logic here...
BEAM just gets better and better. It's a good time to be an Erlanger/Elixirist...
Not comparable to going from a Javascript interpreter to v8.
But it's a great starting point.
It won't be anything like V8, entirely correct, but it brings some VM code to native performance, beating NIFs in some cases.
I think some RabbitMQ tests reported 30% increase in throughput which is pretty wild.
Overall this looks like quite a nice set of improvements. Kudos to the team.
Looks like Elixir 1.12 will take full advantage of EEP 54:
https://github.com/elixir-lang/elixir/releases/tag/v1.12.0-r...
Looks like we get the JIT performance improvements for free.
And unrelated to the Erlang/OTP changes, Elixir 1.12 looks awesome. Totally small, but such an unexpected little quality of life improvement, Kernel.then/2 for pipelines, looks great. I love the core team's focus on the UX of the language.
I have just a few remaining complaints about the language at this point, and Kernel.tap/2 and Kernel.then/2 will solve two of them.
When Jose mentioned a few years back that Elixir the language was more or less "done" or at least stable, and that they would focus on ergonomics and UX going forward, I remember getting a little worried. But I’ve found myself agreeing more and more - there’s not much I miss in the language itself, and projects like Nx, LiveView and LiveBook have shown that it’s an excellent foundation to build very powerful and modern stuff on top of.
I have a stateless java backend servicing REST APIs. These backends are load-balanced by nginx.
Now the time is approaching where I need to introduce some form of global state (that involves global caching, message passing, registering/discovery of known workers, periodic (cron-like tasks), etc).
I would much prefer a single tool to add to my backend stack (currently Java + postgres) to cover most of the above needs.
With the performance improvement + persistent_term [1] -- in current Erlang, I basically get:
- a light weight distributed K/V cache
- a ZeroMQ like on-wire messaging system (built into erlang)
- discovery/coordination
- a distributed compute grid
- a way to write my own routines within that compute grid, and have them exposed via Java interface to my existing backend.
I do not need 'fastest' possible performance or least memory consumption. I just need them to be 'reasonable', 'known' and 'controllable' (not to exceed some baseline).
Erlang is just looking better and better (and I prefer its syntax to Elixir, for some reason.).
Speaking of error message. I love that Erlang gives the exact parameter values in the call stack. (I guess this is generally possible because immutable data structures are enforced in the whole language?) It saves a lot of time than just speculating with call stack only.
When Rust was created doesn't really matter, exactly. For a very long time, errors looked something like this:
hello.rs:2:4: 2:16 error: unresolved name: print_with_unicorns
hello.rs:2 print_with_unicorns("hello?");
^~~~~~~~~~~~~~~~~~~
At some point, "improving the error messages" became a project goal, and Jonathan Turner decided to take this on. This is described in https://blog.rust-lang.org/2016/08/10/Shape-of-errors-to-com... . The post explicitly cites Elm as inspiration because Rust was directly inspired by Elm in this regard.Yes, other languages may have started this trend earlier. Yes, maybe they influenced Elm, which influenced Rust. Yes, Rust may be "older" than Elm. But if you ask the people who began this effort, they will name Elm as the inspiration.
(And yeah, then you can try to argue about who has influenced the broader public, which is effectively impossible to prove, IMHO.)
Today that error looks like
error[E0425]: cannot find function `print_with_unicorns` in this scope
--> src/main.rs:2:5
|
2 | print_with_unicorns("hello?");
| ^^^^^^^^^^^^^^^^^^^ not found in this scope
incidentally, and there's also JSON output, and if you're not on a terminal, you get the line numbers like before... lots of things are improved. This particular error doesn't show off some of the nicer things. Esteban Küber has taken up where Jonathan left off, and has been doing amazing work.Clang was released 2007 and was usable 2009/2010-ish. Rust dev started 2010.
I'm not saying the trend of having good diagnostics was started by clang, but it's a more believable than the claim that it was started by Rust.
--
Rust-the-language is nice, but the Rust community feeling the need to mention Rust on every unrelated thread is a bit of a turn-off for me.
Rust wasn't even a thing (not as hype and mature) at that time.
Rust is nice, but the hype train is toxic (and that's true for every language/technology).
No it didn't. Lets not try to rewrite history here, clang started the trend of meaningful error messages, gcc quickly caught up.
https://en.wikipedia.org/wiki/Rust_(programming_language)
https://en.wikipedia.org/wiki/Elm_(programming_language)
That said, the concepts in question are all much older. If you're ever bored, check out the "Influenced by" sections of the Wikipedia pages on programming languages. It's amazing how old so many of the "new" ideas really are.
There is a lot of research work to do and noone to pay for it. That said, if you know of a company interested to fund this work, i am interested and would love to hear more about it.
In Elixir apps you'll frequently find the aforementioned Ecto "ORM", which has adapters to different DBMSs like MySQL, PostgreSQL, and even Mnesia.
Mnesia lets you do a lot of cool things (in memory DB by default! Super fast!) but it also has some pitfalls (Doesn't write to disk by default! Lose all your data when you restart the BEAM!).
Generally, I think it's a fine system if you're willing to put in the time to optimize it.
Horizontal scaling of the DB seems like a problem in many architectures. For SQL I'd be looking at CockroachDB as it is Postgres-compatible and is built with scaling out in mind. Haven't tried it though. Most of my work hasn't needed that for the DB recently.
Since BeamASM doesn't support HiPE - has anyone seen benchmarks of BeamASM (JIT) vs HiPE. I've searched and searched and can't find such analysis.
(Super excited the JIT work is seeing light after 10+ years)
Erlang/OTP 23 [erts-11.1] [hipe]
Erlang/OTP 24 [erts-12.0] [jit]
binarytrees,hipe,1,7.531
binarytrees,erlang,1,11.768
binarytrees,hipe,2,4.172
binarytrees,erlang,2,5.149
fannkuchredux,hipe,1,59.079
fannkuchredux,erlang,1,73.151
fasta,hipe,1,57.006
fasta,erlang,1,50.843
fasta,erlang,2,20.209
knucleotide,hipe,1,92.662
knucleotide,erlang,1,80.360
knucleotide,hipe,3,86.793
knucleotide,erlang,3,70.949
mandelbrot,hipe,1,118.623
mandelbrot,erlang,1,48.756
mandelbrot,hipe,2,101.211
mandelbrot,erlang,2,46.154
mandelbrot,hipe,3,87.793
mandelbrot,erlang,3,44.633
mandelbrot,hipe,4,84.878
mandelbrot,erlang,4,44.976
nbody,hipe,3,140.025
nbody,erlang,3,100.630
pidigits,hipe,1,8.791
pidigits,erlang,1,8.008
pidigits,hipe,2,8.515
pidigits,erlang,2,8.673
pidigits,hipe,3,7.935
pidigits,erlang,3,7.748
regexredux,hipe,6,42.757
regexredux,erlang,40.402
revcomp,hipe,1,25.622
revcomp,erlang,1,23.070
revcomp,hipe,3,188.990
revcomp,erlang,3,155.024
revcomp,hipe,4,122.507
revcomp,erlang,4,106.456
spectralnorm,hipe,1,92.347
spectralnorm,erlang,1,62.519
spectralnorm,hipe,2,11.176
spectralnorm,erlang,2,11.460
https://benchmarksgame-team.pages.debian.net/benchmarksgame/...The Erlang folks are looking for maintainer volunteers to continue working on HiPE support, they don't have the manpower right now to maintain it themselves.
Both HiPE and this JIT have drastically different improvements depending on the specific code that's running, which makes it challenging to have a real world benchmark as well.
I feel like I saw graphs in one of the presentations, but I don't recall which, or if it was about the final iteration of the JIT.
I suspect HiPE would beat the JIT on tight loops, but the JIT wins in general because of the lack of switching cost between native and interpreted code.
Great work on the improvements!
Erlang/OTP 24 Release Candidate 1 - https://news.ycombinator.com/item?id=26260127 - Feb 2021 (15 comments)