Hacker News new | ask | show | jobs
by Scramblejams 2224 days ago
The older I get the grumpier runtime errors make me.

I want ReasonML (language!) and Erlang (OTP!) to have a baby, and I want it birthed by the Go runtime. (Go? Yeah, Go. I don't love the language, but I am a lover of low latency and garbage collection, what can I say?) Yes, there's Gleam, but if something's based on BEAM, the throughput generally won't impress. :-( Would seem a shame to do all that static typing, and then not reap the speed benefits.

Relatedly, I think there's a sweet spot for a language that accepts mutability inside of actors, but only allows immutable objects to be sent as messages, with an escape hatch available if needed. (Pony explored this space, would love to see it evolve.) Combine that with OTP for happy-path programming, and an ML so you catch most of your errors at compile time, and you could end up with great throughput, low latency and great ergonomics, all at the same time.

6 comments

> but if something's based on BEAM, the throughput generally won't impress

I'm not sure where you're getting that from- that's typically the area it does well. It's bad at number crunching, but you if the work is IO bound (say, like a web application backend) it offers consistently low latency with high throughput.

We're defining throughput differently. I'm talking about CPU utilization, i.e. non-IO-bounded work. Sorry for the ambiguity.
I would be very surprised that Go had lower latency than BEAM based languages, higher throughput/better CPU utilisation OK, lower latency??

Do you have a benchmark showing this?

As for Pony, in theory it should be great but it looks very complex..

Not sure where I implied Go would beat BEAM on latency, didn't intend to. On the contrary, BEAM's had decades poured into keeping the long tail under control, while with Go it's a work in progress.

I singled out Go because it's the only reasonably mainstream multithreaded (need this for actors), statically typed (need this for CPU throughput), garbage collected (need this for ergonomics) language out there with an emphasis on keeping latency under control, and as such would be the only sensible target I know of to host the language I proposed.

I'll say one thing. I accidentally forkbombed my running elixir system in prod (miscontacting an error reporting service triggered two more error reports, and the error reporting service 500'd during an outage), and it kept servicing user requests without much of a sweat.
I have assumed BEAM has similar latency to Go and is garbage collected?

Here is some benchmarks where Erlang beats Go in throughput:

https://timyang.net/programming/c-erlang-java-performance/ https://stressgrid.com/blog/benchmarking_go_vs_node_vs_elixi...

That first link is from 2009. A lot's changed since then, so I didn't read it.

And maybe I missed something in the second link, but Go showed very similar I/O performance to Elixir, while consuming a boatload less CPU doing it. That's what I'm after. Open to being told I missed something, though.

> Open to being told I missed something, though.

The Bean keep using CPU even with no work to be done, so avoid context changes. We can't compare about CPU values.

We can't compare about CPU values

Can you explain more why we can't compare? Looking at this chart...

https://stressgrid.com/blog/benchmarking_go_vs_node_vs_elixi...

...shows pretty clearly how the CPU utilization grows linearly (ignoring some sawtooth) as the load increases, plateaus once the load remains constant, and then comes down linearly as the load decreases on the other end. Looks like a very clear mapping between work done and CPU load to me.

It is explained in the blog post after that benchmark - https://stressgrid.com/blog/beam_cpu_usage/ .

Essentially in order to optimise responsiveness the BEAM uses busy waiting, which in reality is not actually utilising the CPU as much as is reported by the OS, which results in misleading CPU usage being reported by the operating system.

"I think there's a sweet spot for a language that accepts mutability inside of actors, but only allows immutable objects to be sent as messages, with an escape hatch available if needed."

That's kind of what akka is on scala or java. Messages are immutable _BY CONVENTION_ but you can do whatever you want.

Isn't that the basis/point of the actor model? Actors can message each other and processing the message can trigger state mutation of the recipient, but they can't directly mutate each other.
All data is immutable on the BEAM with a few exceptions, so no mutation within actors.
No, that's not true. Actors in elixir/erlang mutate their state through tail call recursion through the loop function.
I said data is immutable on the BEAM, actors can update their state.
"I think there's a sweet spot for a language that accepts mutability inside of actors, but only allows immutable objects to be sent as messages"

Absolutely agree. I had great hopes an "Actor" type would be created in Swift, where every public function would be thread-safe, accept only "pure" structs / value objects, and which would automatically run on its own coroutine.

Unfortunately the concurrency story seems completely abandoned for this language.

We may get our wish when multicore finally drops for OCaml.
The Kotlin KTOR framework is the most promising new web stack I’ve seen. It doesn’t have the higher level runtime features of Erlang but it checks most of your other boxes.
I like Kotlin but I'd say a strength of BEAM is that it doesn't allow for infinite loops, which means coroutines can't block others. This is a fundamental strength.

It allows the runtime to schedule coroutines effectively - they can't block for more than a function call (recursion is how you do "infinite" loops).

I think a future competitor to BEAM languages would need this feature.

This is the kind of thing I was referring to by higher level runtime features in Erlang. If you really need this sort of thing then you should probably be looking at an Erlang stack but I think for a lot of projects a less exotic and also much more rigorously typed language is going to be more productive.
What do you mean "more productive"? You'll get your code out to prod way faster in a BEAM language and in my experience the only remaining errors are relatively minor and easy to "wait to fix", because the BEAM will keep on keeping on and there's no user facing effect (maybe your error logs are a bit polluted with them). Whole classes of errors are not even possible because of "copy-on-write" function passing. I recently fixed a code bug that tripped during a race condition entangleing with a blocking call across two datacenters 1000 miles apart in about one hour, because you can introspect literally everything in the vm with very little hassle, and IO writes are atomic (if you call an IO write to screen it will never be interrupted by another IO write to screen).

I call that productivity.