sasa555's comments

sasa555 | 9 years ago | on: Comparing Elixir and Go

Are you asking about BEAM or Go? Preemption already works in BEAM and doesn't lead to race conditions because of nothing shared concurrency.

sasa555 | 9 years ago | on: Comparing Elixir and Go

Dirty schedulers can help with long running NIFs, but they can't help with e.g. a segfault in a NIF taking down the entire system.

sasa555 | 9 years ago | on: Comparing Elixir and Go

Precisely, which is why I always advise to consider ports first :-)

However, in some situations the overhead of communicating with a port might be too large, so then you have two options:

  1. Move more code to another language which you run as a port.
  2. Use a NIF
It's hard to generalize, but I'd likely consider option 1 first.

If you go for a NIF, you can try to keep its code as simple as possible which should reduce the chances of crashing. You can also consider extracting out the minimum BEAM part which uses the NIF into a separate BEAM node which runs on the same machine. That will reduce the failure surface if the NIF crashes.

I've also seen people implementing NIFs in Rust for better safety, so that's another option to consider.

So there are a lot of options, but as I said, NIF would usually be my last choice precisely for the reason you mention :-)

sasa555 | 9 years ago | on: Comparing Elixir and Go

Thanks, nice to hear that!

Basically a NIF blocks the scheduler, so if you run a tight loop for a long time, there will be no preemption. Therefore, invoking foo(), where a foo is a NIF which runs for say 10 seconds, means a single process will get 10 seconds of uninterrupted scheduler time, which is way more than other processes not calling that NIF.

There are ways of addressing that (called dirty schedulers), but the thing is that you need to be aware of the issue in the first place.

If due to some bug a NIF implementation ends up in an infinite loop, then the scheduler will be blocked forever, and the only way to fix it is to restart the whole system. That is btw. a property of all cooperative schedulers, so it can happen in Go as well.

In contrast, if you're not using NIFs, I can't think of any Erlang/Elixir program that will block the scheduler forever, and assuming I'm right, that problem is completely off the table.

sasa555 | 9 years ago | on: Comparing Elixir and Go

It is possible to start external processes from BEAM and interact with them. I've blogged a bit about it at http://theerlangelist.com/article/outside_elixir

You can also write NIFs (native implemented functions) which run in BEAM process (see http://andrealeopardi.com/posts/using-c-from-elixir-with-nif...). The latter option should be the last resort though, because it can violate safety guarantees of BEAM, in particular fault-tolerance and fair scheduling.

So using BEAM facing language as a "controller plane" while resorting to other languages in special cases is definitely a viable option.

sasa555 | 9 years ago | on: Reducing the maximum latency of a bound buffer in Erlang

The atom always means the same thing - a symbolic (named) constant.

The dot operator can be used on an atom type to invoke a function from the corresponding module. A capital Foo.Bar is called an alias in Elixir, and it's the same as an atom :"Elixir.Foo.Bar".

The usage of __MODULE__ is optional. You can also write %Buffer.Ets{...} if you prefer.

There's no hidden magic with %__MODULE__{buffer | ...}. It's an "update" syntax which allows you to take an existing "struct" (essentially a bunch of well-known named fields), and create a transformed version of it with some fields changed. The code %__MODULE__{buffer | size: buffer.size + 1} is therefore the same as %Buffer.Ets{buffer | size: buffer.size + 1}, and it evaluates to a transformed buffer with the size field set to the size of the original buffer incremented by 1.

The original buffer is left intact (since you can't do in-place data mutation in Elixir). However, the transformed version is not a full deep copy of the original. It's going to share as much data as possible with the original version.

Hope that helps :-)

sasa555 | 10 years ago | on: Erlang Scheduler Details and Why They Matter

I like to say that in NIFs (and port drivers) all the bets are off anyway, most notably process isolation and fault-tolerance. The guarantees such as "preemption" and fault-tolerance happen in the layer above (i.e. pure Erlang), and can only be satisfied if the underlying layer behaves properly.

sasa555 | 10 years ago | on: Erlang Scheduler Details and Why They Matter

I like to think of it as preemptive because (putting NIFs aside) it's not possible for a single process to completely block the entire scheduler, even if it ends up in an infinite CPU bound loop.

So in other words, a task (i.e. process) doesn't have to cooperate with others. It can do whatever it wants, be it I/O or CPU bound, and doesn't have to yield explicitly. Due to aggressive "preemption" it won't block other pending tasks significantly.

In contrast, if this is not guaranteed (which is not in most other Erlang "alternatives" I've looked at), then a task might accidentally paralyse large portion of the system.

sasa555 | 10 years ago | on: Phoenix 1.0

I've been doing full-time Erlang for five years, and I personally prefer Elixir.

Elixir is semantically close to Erlang the language, and allows you to take advantage of all the great benefits of Erlang/OTP.

It's benefit is dev's productivity. Creating OTP applications and releases is simpler, and there are tools in the language (e.g. macros, polymorphism via protocols, tidier stdlib), and around it (e.g. Hex package manager, mix tool, doc tests) that make developers' life simpler.

All of this is possible in plain Erlang, but it's more cumbersome, and sometimes requires home-brewed solutions.

Notice that I'm not discussing syntax at all, because it (mostly) doesn't matter. I actually like the Prologness of Erlang. What I dislike is that some chores require more of my time and yak shaving, compared to Elixir.

sasa555 | 10 years ago | on: Phoenix 1.0

Everything is possible in a Turing complete language (assuming enough of base utility functions are provided by stdlib), so the question is not possible vs impossible, but how much of a help the tool is.

Erlang provides great abstractions for building fault-tolerant, scalable, distributed, soft real-time systems. That's not to say you can't do it with Erlang, but Erlang does give some simple, yet very powerful tools for making developer's life easier.

Without Erlang you have to work harder to get similar effects. Again, it's not impossible but there's more burden on developers because the runtime provides less guarantees. I elaborated a bit on the topic in the promo interview for my book (http://www.infoq.com/articles/elixir-in-action-erlang-review).

sasa555 | 13 years ago | on: The Future of Riak at RICON East

I guess JVM or .NET preference is often caused by inertia, ignorance or fear of change.

In the company I used to work for, they had religious devotion to Microsoft. Everything that didn't come from MS was frowned upon, not only open source or competing closed source technologies, but also 3rd party .NET components/libs.

As far as Erlang is concerned it is somewhat exotic, so I can understand why mainstream population won't pick it up. Not only is it functional language, but it is Prolog based, so I see why that turns off most of the people.

Even my current boss, who is very open minded, objected when I introduced Erlang, wondering who will maintain the code if I leave the company.

Nevertheless, Erlang has gathered some impressive references lately, not only Ericsson, Riak or Facebook, but also WhatsApp, Chef, Heroku, Amazon SimpleDB, Call of Duty, and so on.

For what it's worth, these days I would choose Erlang/Elixir combination for almost anything server side.

sasa555 | 13 years ago | on: The Future of Riak at RICON East

I have more than 10 years of professional experience using C++, C# and Ruby to develop "classical" business web and desktop apps.

I started using Erlang two years ago to implement a push server, and fell in love with it immediately. The language has its quirks, but the virtual machine is fantastic, and it really makes it easier to manage massive concurrency, which is almost always the case on the server side.

If you find the language too strange, you should also check Elixir, a Ruby flavored language which compiles to the Erlang bytecode and can normally cooperate with other Erlang code. Starting this year, I am adding new feature for my Erlang based system using Elixir as much as possible. At the moment, you should really be familiar with Erlang to be able to fully understand and utilise Elixir.

Other alternatives to Erlang would be Go, Scala/Akka, or reactor based platforms such as node.js or EventMachine. Also, probably Haskell and Clojure, but I'm not really familiar with those. Personally, I find them all to be inferior to Erlang VM, although Go and especially Scala/Akka are really close. I wouldn't recommend reactors despite my great affection for both Ruby and Javascript.

Some detailed ramblings on what I really love about Erlang can be found on my blog: http://www.theerlangelist.com/2012/12/yet-another-introducti...

http://www.theerlangelist.com/2013/01/erlang-based-server-sy...

page 1