Hacker News new | ask | show | jobs
by enraged_camel 2540 days ago
> I don't think I've liked a technology this much ever and I'm honestly surprised it's not already more popular than it already is.

To be honest, this can probably be almost 100% attributed to the fact that it is not backed and heavily promoted by a tech giant.

1 comments

I love Elixir, but the learning curve was steep. Async everything, dialyzer, macros, Erlang errors, charlist vs string vs iolist... It was a lot to take in.

Edit: 4 upvotes in 4 minutes. I guess people are reading this... for anyone who hasn't already discovered it, the saving grace for me was the Elixir Slack channel. I also learned while working with someone who really knows Erlang, which helped quite a bit, too. If anyone learning Elixir gets to the point where they want to scream, feel free to email me. If I can help, I will! Email in profile.

Hmm, I'm primarily a C# dev and recently spent a morning getting to know Elixir, and was actually surprised with how flat the learning curve was.

Now, writing idiomatic functional code while coming from an OO background, now that is difficult!

I have to say though, I loved the short time I spent with Elixir so far - it's hard to put a finger on it, but it just feels right. But... I do wish it was statically typed :(

> Now, writing idiomatic functional code while coming from an OO background, now that is difficult!

This is one of my favorite parts. I mostly program in Python and Ruby and am very very wired to write programs in an imperative way.

So when you finally "get" things like Enum.reduce and you use it twice in 1 day to solve 2 different problems, it's a real rush.

> Async everything

What do you mean by that? Most code in Erlang/Elixir is synchronous, meaning it will block the process (but not the scheduler). Maybe you meant concurrent (or message-passing) everything?

Yeah I'm curious too.

I've written about 2,000 lines of code on this course platform so far and everything except for 1 function is synchronous from a "this is my code" standpoint. I only used Task.start once to launch something in the background.

This is what I like about it: my junior had an ask from management to profile a customer task, as a single process, and as a concurrent job to simulate more than one simultaneous client. I'm nonzero suspicious it was asked to try to get him to trip up and have an excuse to can him. I instructed him to do the job in elixir. He got it done, then I wrapped it in task.async one-line, and it just worked and he understood what was going on, and was able to generalize the concurrency rules.

The elixir standard library is just full of things that make your concurrent programming seamless, easy, and bulletproof, even for a junior that's never done things that way.

I can't imagine him getting this correct with python async, JavaScript promises and callbacks, or having to create go channels.

In the Erlang VM, process execution can stop at an arbitrary point and resume later on. This time slicing is done to ensure that no process, takes up too much time. So you must treat your code as asynchronous since if you get a value from another module, then get it again in the next line it might have changed because your process was suspended in between those two lines.
While that is true it does not make a difference for day to day programming, unless you are super accustomed to think about locks.

You can get very far in Elixir without considering the nitty gritty parts of OTP.

It's interesting that people would like Elixir without understanding OTP.
All of the GenServer stuff is built on top of regular Erlang processes. It's all async. You'll might find out when your server gets busy and GenServer calls start timing out
I don't think it's a good idea to worry about dialyzer, iolists or especially macros for someone just learning. In fact, I don't think OTP should be the first step, either.

You can be very productive with Elixir before learning the things that it's famous for!

.... and no vectors/arrays.
You've got:

http://erlang.org/doc/man/atomics.html and http://erlang.org/doc/man/counters.html for cheap, mutable uint64 arrays;

• The http://erlang.org/doc/man/array.html module for a functional persistent vector abstraction (similar to the one in Clojure);

• ETS ordered_set tables, for mutable AVL trees (for when you want to cheaply apply a sequence of random mutations to a collection of terms without building a lot of garbage);

• The process dictionary (https://www.erlang.org/course/advanced#dict), a mutable per-process hash-map data-structure, for when ETS ordered_set tables have too much inter-process copying overhead.

All that, plus Erlang lists (singly-linked lists) are really cheap the way Erlang does them. (Each Erlang actor-process gets its own heap that gets independently GCed; short-lived processes never experience even a single GC, so allocating linked-list nodes (by consing to the beginning of a list) is just a matter of incrementing the actor-process's heap's free pointer—about the same level of optimality you'd hope to get from pushing to the end of a vector.)

Thanks! Didn't know about some of those.
There is List, which is similar (but not quite the same).

Other than that, you may want to give this a read: https://elixirforum.com/t/arrays/8850/13

tl;dr: the type of data structure that would satisfy your use case almost certainly exists in Elixir, but you need to look around a bit.