Live data from Hacker News

Comparing Elixir and Go

blog.codeship.com

151–160 of 202 posts

Re: Comparing Elixir and Go

#151
post #87

Earlier quoted context omitted.

May I suggest some changes to the type parts: * Elixir doesn't infer types. The language is dynamically typed, just as Erlang is. Using the word "inference" is somewhat dangerous since it means something very specific to a type theorist. * Likewise, the compiler catches nothing, unless you are passing in a constant or literal. If you have `X Y` for arbitrary X and Y, the compiler can only catch it in statically typed…

I was talking about Dialyzer when mentioning that but I wrote it that way because I didn't want to derail into an explanation of Dialyzer and how it works. I did link to a talk on it though. It's such an automatic part of the stack with no drawback to using it that it's why I wrote it that way. Check that talk though, it's really interesting.

Perhaps some quick parentheses--'(via Dialyzer)' would be enough. I'm familiar with Dialyzer but missed the reference in your post and thought wow, I didn't realize Elixir/Erlang had all this type checking built in... so definitely some potential for misunderstanding there. Overall excellent post though! Thanks for writing it.

Re: Comparing Elixir and Go

#152
post #113

Earlier quoted context omitted.

how easy is it, even if you do need complex calculations, to get the best of the Erlang VM and call out to say, Python/Numpy or C when necessary? Can these external processes still be supervised, for example? Are decent sized matrices (for example 100x20000 floats so an 8MB data structure) easily movable around the Erlang VM via message passing? IE is it viable in your opinion still to use Erlang as a system for dist…

You can write NIFs in Rust (which is made even simpler by supporting libraries like Rustler). scrogson, for instance, is using this to fiddle with lower-overhead json. Re: supervising external processes, an easy hack if you're writing the processes is to add a deadman's switch to both sides, and then launch the processes from a port in BEAM-land. This effectively makes them supervised; kill the beam process and the e…

[deleted]

Re: Comparing Elixir and Go

#153
In Elixir, error handling is considered “code smell.” I’ll take a second to let you read that again.

I think that this makes a lot of sense. My experience in just about any language, is that the official means of error handling already feels like a code smell, even before you start using it. And if that's not the case, then it still manages to feel that way when used in a large project.

Lots of Smalltalk projects would actually handle errors by saving the image on an unhandled exception. For server applications, this was like having a "live" core dump where the debugger could open up right on the errant stack frame, and you could perform experiments to aid in debugging.

Re: Comparing Elixir and Go

#154

Go's philosophy around error handling (or lack thereof) is arguably atrocious compared to BEAM's "Let It Crash (And I'll Just Log It And Restart In 1 Millisecond With Exponential Backoff)" philosophy. To review: https://gobyexample.com/errors Manually checking every possible error (and then, only in the spots where you can imagine an error occurring ) is a heck of a lot of extra work for the programmer (and code for…

While I agree wholeheartedly that Erlang's design is better:

To be fair, you can't get Erlang's semantics without also inventing processes and supervisor trees. And those things would be largely meaningless without immutability.

Erlang's magic comes from how all the puzzle pieces fit together into a whole: For example, with immutability comes the ability to always be able to restart from a known state, and probably greatly simplifies the internal implementation of the per-process heap.

Those things fundamentally change the language; Go couldn't adopt Erlang's semantics without eschewing almost everything that makes it "Go".

Error handling is really the least of it. Attempting to replicate some of Erlang's high-level design principles at a quickly lead to roadblocks. For example, goroutines cannot be killed; this means it's impossible to fully implement supervisor trees in Go. It's possible that the runtime could support this at some point, but it's a big can of worms.

Re: Comparing Elixir and Go

#155

Go's philosophy around error handling (or lack thereof) is arguably atrocious compared to BEAM's "Let It Crash (And I'll Just Log It And Restart In 1 Millisecond With Exponential Backoff)" philosophy. To review: https://gobyexample.com/errors Manually checking every possible error (and then, only in the spots where you can imagine an error occurring ) is a heck of a lot of extra work for the programmer (and code for…

While I agree wholeheartedly that Erlang's design is better: To be fair, you can't get Erlang's semantics without also inventing processes and supervisor trees. And those things would be largely meaningless without immutability. Erlang's magic comes from how all the puzzle pieces fit together into a whole: For example, with immutability comes the ability to always be able to restart from a known state, and probably g…

Agree, and thank you for pointing those additional considerations out!

Re: Comparing Elixir and Go

#156
post #123

Earlier quoted context omitted.

I think the person's point was that you sacrifice performance - having the ability to mutate is only a good thing there, as immutability without being able to exit out of that is too inflexible and potentially could cause other hacks to appear when trying to solve that problem. FP with a focus on immutability is good for the default, but ignoring its limitations is bad.

Sure, but I don't know any pure languages that provide no facilities for mutation whatsoever, they just ask you to be explicit about it and add some syntactic weight (which is a good thing, you want mutation called out as a reader). Haskell provides several different mutation options from simple references to various kinds of thread-safe references depending on what semantics you need. There's even a "no-really-trust…

Erlang is purely immutable and doesn't have any "facilities for mutation" that I know about, although it does have side effects (I/O, but no Haskell-style effect system).

Re: Comparing Elixir and Go

#157

I still don't understand what all the hype is about pure functional programming. Sometimes mutations are useful. There are lot of good programming design patterns which depend on mutations. Also, always copying objects by value every time you call a function seems very expensive; especially if you're dealing with very large objects/structs/maps/strings which have to be processed by many functions.

I still don't understand what all the hype is about pure functional programming.

Sometimes mutations are useful. There are lot of good programming design patterns which depend on mutations.

Study the Chomsky Hierarchy and the Theory of Automata. https://en.wikipedia.org/wiki/Automata_theory > Here it is in a nutshell:

Languages are synonymous with computation. These can be divided into just a few types, based on how they can use state. One can observe that the complexity of an automata and its corresponding language increases dramatically with its use of state. (Turing Tarpit https://en.wikipedia.org/wiki/Turing_tarpit) You can avoid complexity by avoiding complex interactions with state.

Also, always copying objects by value every time you call a function seems very expensive

In the case of parallel/concurrent computation, it can be the less expensive option. https://mechanical-sympathy.blogspot.com/2011/07/false-shari... > As always, the devil is in the details, and it's all about context. So you are correct. Sometimes mutations are useful. However, sometimes, you can get a benefit from avoiding them.

Re: Comparing Elixir and Go

#158

Earlier quoted context omitted.

I was talking about Dialyzer when mentioning that but I wrote it that way because I didn't want to derail into an explanation of Dialyzer and how it works. I did link to a talk on it though. It's such an automatic part of the stack with no drawback to using it that it's why I wrote it that way. Check that talk though, it's really interesting.

Perhaps some quick parentheses--'(via Dialyzer)' would be enough. I'm familiar with Dialyzer but missed the reference in your post and thought wow, I didn't realize Elixir/Erlang had all this type checking built in... so definitely some potential for misunderstanding there. Overall excellent post though! Thanks for writing it.

I think this is an excellent suggestion. Another point could be to push the aside down into a footnote. Readers can then peruse that part on their own leisure, without having to stop your flow in the article.

Re: Comparing Elixir and Go

#159
post #87

Earlier quoted context omitted.

May I suggest some changes to the type parts: * Elixir doesn't infer types. The language is dynamically typed, just as Erlang is. Using the word "inference" is somewhat dangerous since it means something very specific to a type theorist. * Likewise, the compiler catches nothing, unless you are passing in a constant or literal. If you have `X Y` for arbitrary X and Y, the compiler can only catch it in statically typed…

I was talking about Dialyzer when mentioning that but I wrote it that way because I didn't want to derail into an explanation of Dialyzer and how it works. I did link to a talk on it though. It's such an automatic part of the stack with no drawback to using it that it's why I wrote it that way. Check that talk though, it's really interesting.

I had a hunch you were talking about the dialyzer, but unless you happen to know about it a priori, this part reads like false information, and it almost had me tune out of the rest of the article.

I fully understand you intended to write something else, and I very much agree with the power of the dialyzer :) It was more a "I dualized this section by accident, perhaps other readers would do the same?"

Re: Comparing Elixir and Go

#160

Earlier quoted context omitted.

>My last example was when I needed to batch sql inserts in an events database. In a normal language I would have needed a queue, the libraries for it, workers, new deployments and infrastructure to monitor, monitoring, supervision, etc... In Elixir, in 20 lines of code, it's done. Can you provide more details on this? AMQP is pretty recent and people have been batching SQL inserts for much longer than it has been aro…

A simple GenServer ( a OTP behaviour ) linked to an ETS ( erlang in memory data store ) table would do the trick. Basically, It receives by message the inserts, and once the counter reaches x or timer reaches y secs, it inserts in the db. Thinking about it, 20 lines of code is already a bit verbose for it :)

In Elixir, you can use GenStage.

(In fact, I'm writing a GenStage consumer right now.)

Post reply on HN