Hacker News new | ask | show | jobs
by lostcolony 1754 days ago
And sane strings. And I really like Mix.

That said, I generally prefer Erlang, for the syntax, for Dialyzer, and for the one less level of abstraction. But recognize the future in the space is probably Elixir, and being fluent with both is probably helpful.

1 comments

And Task, and Registry. Those don't exist in erlang, and they are fantastic.
Eh, Task is super easy to build though, and is little more than syntactic sugar for what I rarely did anyway (and it also obfuscates the fact that the asynchronous task may never return; yes, a timeout is thankfully included, and will by default tear the task down, but I still like the explicitness of "I sent a message...I need to receive a response with a timeout"). I agree it's a solid pattern to add, just not really impactful for me.

Registry I will admit to never really looking at; I assumed it was the same as Erlang's process registry. Looking at it, yeah, having that as part of the default library seems nice, though in Erlang the few times I needed more than what the process registry gave me I just used a library. Given the evolution in that space just from the time I was in Erlang, I'm actually curious how Elixir's is implemented, but regardless I agree it's nice to include a default one.

So, yeah, solid additions, but I don't know if I'd phrase it that way, that they "don't exist in Erlang".

> Task is super easy to build though, and is little more than syntactic sugar for what

That's the prevailing mindset in Erlang, and it's holding Erlang back. "Why build X, when you can just build it yourself". And so you have everyone building a variety of Xs in each project, all of them subtly different, all of them slightly inconsistent.

Why not have these useful abstractions in the standard library? "Little more than syntactic sugar" goes a long way towards improving developer experience and frees you to do other things than reimplementing stuff that should've been in the standard library in the first place.

I did say - "I agree it's a solid pattern to add, just not really impactful for me."

I'm not at all against having it there, I even call it out as a positive addition. Just not one, I, personally, found as transformative as the things I called out. There are other things that are -nice- in Elixir, the pipe symbol, revamped standard libraries, etc, but they didn't change the experience for me the same way.

Strings in Erlang are a pain point. Lack of a standard build tool (and thus using things like rebar3 and the like) is a pain point. Lack of macros wasn't a pain point, but it did enable new approaches, so I would consider it transformative.

Task? Task is nice syntax sugar, but it's not solving a pain point or enabling anything new coming to Elixir from Erlang (which, as you may note, was the point of this thread). I'm not dismissing it, it -is- a nice addition, and just like Registry having a standard approach is a benefit, but it just isn't nearly as impactful.

I agree, Task and Registry are nice, especially for newer folks, but if you know your way around OTP you can write your own specialized version in 1-2 hours.

The protocols, structs and macros are game changers in comparison. All the Phoenix, LiveView, Ecto stuff is possible because of those.

Task also does some magic with the process dictionary which has buy-in from the community, so if you rebuilt task, you wouldnt get the ecosystem benefits.

For example, if I make a database checkout in testing, using ecto, the checkout lifetime is tied to the test process, as is typical in BEAM for sane resource cleanup. If you execute code which spawns a new process it does not know about the database checkout because it's a new PID. Task stashes it's caller PID (this is not the same as ancestor because you might want to supervise a Task) in the process dictionary, so libraries that need that association can find it.

So yeah, you may have a point about Registry, but Task really "doesn't exist in erlang" because no 3rd party erlang libraries know about your ad-hoc Task clone, so even if you built caller knowledge into it, it would only be useful for your own code. At best you could correctly emulate Task's api, but then you would only be able to get that functionality with your code + Elixir libraries that use Elixir Task, and no erlang libraries.

Setting standards is an important role for languages.

Sure; I will grant you (and I think already did in my original post) that a standard approach to a pattern is better than multiple ad hoc implementations. That said, I appreciate the callout for Task; that does make it sound like it brings more to the table than appears on the surface (to 'mix' a metaphor).