Live data from Hacker News

Why Erlang Matters

sameroom.io

201–210 of 210 posts

Re: Why Erlang Matters

#201
post #25

Earlier quoted context omitted.

The interesting aspect of scaling up is that it doesn't matter how fast you are at individual single-core computation. Fast single core computation, or even SIMD GPU processing, is largely an "easy" problem: get a stream of data going, or get a chunk of data into the system, and work away on it. What makes scaling up hard is moving data around. Once you have more than a single computer, there is no way you can easily…

> Before Erlang, Tandem systems built hardware/software with many of the same ideas in them. Indeed, Jim-gray's (from tandem) paper 'why computers stop and what we can do about it' is an quite good. It contains a detailed report of machine failure including s/w and h/w and details techniques for reducing the mtbf by these. Erlang's language and runtime seems to have picked seminal ideas from here...

Indeed, Jim-gray's (from tandem) paper 'why computers stop and what we can do about it' is an quite good

For your convenience: http://www.hpl.hp.com/techreports/tandem/TR-85.7.pdf

Re: Why Erlang Matters

#202
post #2

I'm a very green Erlang noob, but given what I have seen from it I find articles like this kind of strange. Sure concurrent programming is difficult and we need to think hard about how to make programs run quickly in a multiprocessor environment, but the fundamental architecture of Erlang seems to be in conflict with big data and high speed computing. It seems like a language that can scale much better, but has such…

> the fundamental architecture of Erlang seems to be in conflict with big data and high speed computing Because they are different problems. Concurrency, meet parallelism. Concurrency: many smaller tasks that can be multiplexed over one core. The core doesn't need to be particularly fast; it just needs to be able to handle multiple tasks in-flight at once. Web serving, etc. Parallelism: one big, honking task that can…

Not sure who is doing big data with Erlang, or why anyone would want to

Nokia created an open-source Hadoop-replacement called Disco [0] that used Erlang for coordination/orchestration -- an underappreciated strength of the language -- of map-reduce jobs, where the jobs were written in Python (and later OCaml, etc.). They've shown that it can handily outperform Hadoop (at least in the canonical wordcount example shown in this talk[1] -- there may be other examples, I haven't actually watched the talk yet). They've used it to mine terabytes of logs, daily, as described in this talk[2] and others apparently have used it as well.

From the abstract[3] describing the first talk, about the project:

We will describe our experiences using Erlang within Nokia to build Disco, a lean and flexible MapReduce framework for large-scale data analysis that scales to large clusters and is used in production at Nokia. Disco is an open-source project that was started in 2008 when attempts to use Hadoop to analyze data proved to be a painful experience. The MapReduce step formed only a portion of the analytics stack, and it was felt that it would be faster to write a custom implementation that would integrate well, than adapt Hadoop with the amount of internal Hadoop expertise available. Among the crucial tasks of such an implementation would be to deal with cluster monitoring, fault- tolerance, and the management and scheduling of a large number of concurrent and distributed jobs. To keep the implementation simple, the use of a platform that provided first-class support for distribution and concurrency was imperative. This motivated the choice of Erlang/OTP to implement the core control plane of Disco. It bears stressing that this choice was driven primarily by pragmatic concerns, as opposed to any beliefs about the superiority of functional programming languages in general or Erlang in particular.

The project's homepage [0] has information, a link to its Github, etc.

[0] http://discoproject.org/

[1] https://youtu.be/IjOGUC-iR_Q

[2] http://vimeo.com/23550705

[3] http://cufp.org/2011/disco-using-erlang-implement-mapreduce-...

Re: Why Erlang Matters

#203

Earlier quoted context omitted.

There is one other. Haskell has green threads, a preemptive scheduler, and it has a pretty decent implementation of Erlang-inspired multi-node concurrency primitives and higher-level framework including supervisors, gen_server equivalent etc in the Cloud Haskell project. It does NOT have Erlangs deployment base and track record but it is still a very promising framework and very appealing if you like Haskell's type s…

Just a nitpick, but Haskell's scheduler (like Go's) is "less preemptive" than Erlang's. If you have e.g. i = 0 for{ i += 1 } or equivalent in Go/Haskell, then the HS thread/goroutine running it cannot be interrupted, as interruption can only take place at certain points (e.g. allocation or function calls). Erlang on the other hand assigns a certain amount of time units to each process, and each pure-Erlang operation…

Here's a minimal example:

  package main

  import "fmt"

  func main() {
    go hog()
    for i := 0; ; i++ {
      fmt.Println(i)
    }
  }

  func hog() {
    for {
    }
  }
It stalls after about three seconds on go version 1.6.

Here's the issue on github:

https://github.com/golang/go/issues/543

Re: Why Erlang Matters

#204
post #203

Earlier quoted context omitted.

Just a nitpick, but Haskell's scheduler (like Go's) is "less preemptive" than Erlang's. If you have e.g. i = 0 for{ i += 1 } or equivalent in Go/Haskell, then the HS thread/goroutine running it cannot be interrupted, as interruption can only take place at certain points (e.g. allocation or function calls). Erlang on the other hand assigns a certain amount of time units to each process, and each pure-Erlang operation…

Here's a minimal example: package main import "fmt" func main() { go hog() for i := 0; ; i++ { fmt.Println(i) } } func hog() { for { } } It stalls after about three seconds on go version 1.6. Here's the issue on github: https://github.com/golang/go/issues/543

Here's a modified version that doesn't stall:

  package main

  import "fmt"
  import "runtime"

  func main() {
    go hog()
    for i := 0; ; i++ {
      fmt.Println(i)
    }
  }

  func hog() {
    for {
      runtime.Gosched()
    }
  }

Re: Why Erlang Matters

#205
post #25
post #2

I'm a very green Erlang noob, but given what I have seen from it I find articles like this kind of strange. Sure concurrent programming is difficult and we need to think hard about how to make programs run quickly in a multiprocessor environment, but the fundamental architecture of Erlang seems to be in conflict with big data and high speed computing. It seems like a language that can scale much better, but has such…

The interesting aspect of scaling up is that it doesn't matter how fast you are at individual single-core computation. Fast single core computation, or even SIMD GPU processing, is largely an "easy" problem: get a stream of data going, or get a chunk of data into the system, and work away on it. What makes scaling up hard is moving data around. Once you have more than a single computer, there is no way you can easily…

Wow, when I first read about OTP (via learning Elixir) my immediate thought was this sounds like the Tandem systems I coded in the early 90's. Glad I'm not the only one to make the connection.

Re: Why Erlang Matters

#206
post #185

Earlier quoted context omitted.

Could a function with a body like just for(;;){ } be preempted?

You could, but we removed time-slice-based preemption a few versions ago b/c it doesn't make sense for fibers if you also have access to heavyweight threads, so now we only preempt on IO/sleep etc.. The thing about time-slice preemption is that it just doesn't help with lightweight threads anyway, as your machine can only support a tiny number of execution threads that require time-slice preemption while you can have…

>now we only preempt on IO/sleep etc

The IO you are talking about - that is I assume IO methods/libraries that are specifically written/adapted for use in Quasar, yes? If you just use an off-the-shelf JDBC provider, you would block the entire thread when one fiber calls out to the database right?

If so, that is not preemption, that is cooperative multi-tasking.

Re: Why Erlang Matters

#207
post #185

Earlier quoted context omitted.

You could, but we removed time-slice-based preemption a few versions ago b/c it doesn't make sense for fibers if you also have access to heavyweight threads, so now we only preempt on IO/sleep etc.. The thing about time-slice preemption is that it just doesn't help with lightweight threads anyway, as your machine can only support a tiny number of execution threads that require time-slice preemption while you can have…

>now we only preempt on IO/sleep etc The IO you are talking about - that is I assume IO methods/libraries that are specifically written/adapted for use in Quasar, yes? If you just use an off-the-shelf JDBC provider, you would block the entire thread when one fiber calls out to the database right? If so, that is not preemption, that is cooperative multi-tasking.

It's not cooperative because the fibers don't explicitly yield control; they are preempted as soon as they perform an operation that does not require use of the CPU.

As to the choice of libraries, that is an artificial distinction. Runtimes like Erlang and Go also require libraries specifically written/adapted for the runtime; calling an off-the-shelf IO library from Erlang/Go would also block the entire thread. As integrating a library with Quasar does not require changing its interface, the question of whether to trap calls to specific implementations (which is trivial on the JVM) or require the use of fiber-friendly implementation (wrappers) is a question of design. So far, we've opted for the latter simply for the sake of "least surprise", but we may choose to do the former, too. Also, unlike Erlang/Go (I believe), any accidental blocking of the kernel thread is automatically detected by Quasar at run time, and reported with a stack-trace.

Quasar operates in the exact same manner as Erlang/Go, only that we've disabled time-slice preemption once we realized it neither helps nor is it required on the JVM. The only real difference is one the nature of the ecosystem: while all pure-Erlang libraries are designed to work with fibers, most JVM libraries aren't, and so require a thin integration layer that is provided separately. OTOH, thanks to the size of the JVM ecosystem and the standard interface approach, I believe it is the case that today there are more IO libraries that support Quasar fibers (e.g. all servlet servers) than those supporting Erlang processes.

Re: Why Erlang Matters

#208

Earlier quoted context omitted.

> "(ok, excluding numbers)" That's a pretty big exclusion. There are times one really doesn't want type promotion from a particular number representation for performance or accuracy reasons, and if your dynamic typing system does not allow contracts to reject numerical types that will implicitly promote, you can run into huge performance problems. An example: suppose you want to divide a list of numerators by a singl…

Because Erlang is a dynamically typed language, in your example, dividing a list of numerators can give you any type back. It could be a list of numbers, integers, floats, tuples, strings. It might not even be a list at all. This is just something you deal with in dynamically typed languages. You're making a case for statically typed languages, which is fine. But that's not Erlang (or Python, or Ruby etc. etc.). Erla…

There are quite a few dynamically typed languages which let you restrict the numeric types that polymorphic operators can consume and produce. A long heritage of that is in Common Lisp (see the Type Specifiers section in CLtL) and several other Lisp-family languages allow this too (e.g. Racket, which has a pretty substantial contracts sytem).

So it's not new. It doesn't make Lisp any less dynamically typed as a language, and it is wholly optional. Newer dynamic languages also let one do some partial or "gradual" typing where a programmer wants to use it.

There is a cost to this at function calling time, but then there is also a cost if one manually programs in a check on the type of an argument, for instance. Good compilers, however, can prove that functions that aren't of (or exported to) global scope will never be called with anything other than the specified types, and will omit the type-checking code.

Additionally, there is plenty of research into interoperation between code in statically typed languages and dynamically typed ones.

Naturally you can always convert back after your arithmetic operator produces the wrong type. But that can be expensive in itself, and it hurts more when the arithmetic operator could have performed a much cheaper operation.

A way around this of course is to eventually de-polymorphize the potentially-expensive operator and program in a hopefully cheap type-check by hand, in write-generically-first/optimize-(or even make correct)-after fashion.

Re: Why Erlang Matters

#209
post #108

I'm really interested in BEAM languages, but the fault-tolerance / supervisor aspect of it doesn't speak to me. Aren't all modern application fault-tolerant, as long as you don't design something really poorly? For example, I've never had a single HTTP request bring down an entire website -- that's already isolated. Same with message-queue listening processes. For general batch applications, I've always had them shor…

The fault tolerance allow you to have processes and state to be available reliably for longer than the duration of a HTTP request.

You can have continuously running processes without relying on something outside of the language. You can more easily distribute such code as an Elixir package. The code can work without relying on e.g. cron or redis being available and configured.

Re: Why Erlang Matters

#210
post #197

Earlier quoted context omitted.

I think you are seeing two definitions of "live reload". One is where you live upgrade a full running release, including all applications and version, where you mutate state that had its format changed. All this in production, without any downtime. This is incredibly hard to get right. Erlang gives you a lot of tools (OTP & friends) to achieve this, but it is still very complex. The other is reloading Erlang code in…

I haven't seen it used directly, but it seems like Elixir macro based code could be altered and recompiled based on runtime configuration. An example would be changing log level settings. Normally Elixir log blocks can be compiled entirely out when running in production mode. But it should be possible to fairly safely recompile with debug logs enabled and reload without missing a beat.

We do this in our project, for two reasons. One for logging (as you mentioned) and the other for configuration (compiling configuration into a module for efficiency reasons). The Elixir primitives makes this a breeze.
Post reply on HN