Live data from Hacker News

Switching to Elixir

leemeichin.com

241–250 of 283 posts

Re: Switching to Elixir

#241

“In fact, I might go as far as saying that Elixir gives you a fun language (like Ruby) while leaving out the stateful footguns OOP languages give you. There are no classes, no instances, no inheritance…it's immutable and functional and you're not bogged down by a static type system.” I want this but with types. I’m convinced strongly typed is the way to go for larger code bases as it hides the magic of a lot of thing…

It's less of an issue with elixir than it is with ruby or python or any other dynamic lang (or static lang) with mutability. Because of pattern matching/unification in functions, you have a good idea what shape your data is as it's being passed around. if you still don't feel comfortable, there's always Dialyzer. Dialyzer is a static analysis tool for erlang/elixir. It's part of the standard Erlang Release and stands…

Big time this ^, I really need static typing in hobby projects (I like C#/Typescript) but at work we use Elixir and it doesn't end up being a problem because of pattern matching. It's partially because it ends up being run-time type checking, and partially because it makes the code _read_ like a statically typed language.

Re: Switching to Elixir

#242

> In Ruby it's common to use exceptions for control flow. I think this is just plain incorrect. The example given later in this paragraph is the Rails `update` method--but the approach used in all canonical Rails examples and generators is the non-exception version of `update`.

I do not find it incorrect at all, as a Ruby user since 2004. A lot of gems use exceptions for control flow and it is also common in apps or libraries I've written or maintained (just a data point).

> A lot of gems use exceptions for control flow

Do you happen to have an example of such control flow to link to? Not that I don't believe you but I wonder if there's a difference in what is meant by "control flow" between commenters.

  begin
    do_stuff!
  rescue MyFirstLibraryError => error
    # handle first
  rescue MySecondLibraryError => error
    # handle second
  end
That could be "control flow" to one person and "error handling" to another. Or even both to a third person.

Re: Switching to Elixir

#243
post #70

Earlier quoted context omitted.

> looking at the magic of LiveView (and LiveBook) What's the magic? I think it's pretty easy to get a correct mental model of everything in livebook maybe excepting exact details of how the diff calculation/data compression works. Even so, you can spy on the websocket messages and get a reasonable picture of what's going on in a pinch. Liveview is incredibly straightforward.

> Liveview is incredibly straightforward. I don't agree. One of the keynotes from the 2023 ElixirConf was Chris McCord (one of the principle developers of LiveView) describing how it is almost 1.0 [1]. One thing that made me laugh a bit was him emphasizing how much Javascript he's had to write (he was referencing the fact that there is an internal community meme that you can achieve such incredible behaviors without…

I think we have different definitions of straightforward. Liveview is straightforward to use because of Chris mccords effort and his good taste in software design and how a genserver is a good framework for state management.

Re: Switching to Elixir

#244
post #28
post #8

How do people switch programming languages? Established languages have massive ecosystems. Large set of libraries. For example, I cannot give up MS Entity Framework Core or Hot Chocolate graphql server for C#. Sure, there are alternatives, but nothing as feature complete. Perhaps it is possible for applications that have small set of requirements.

> For example, I cannot give up MS Entity Framework Core or Hot Chocolate graphql server for C#. What? Why? Also, what do you mean nothing is as feature complete as Entity Framework? What about ActiveRecord, Ecto, Django ORM, Knex, even Dapper in C# itself......

Do these replacements for Entity Framework Core offer first class support for Migrations, or temporal tables...

Many of EF Core replacements do a handful of things well. And after that, it is a cliff.

And now point me to a graphql server that is as feature rich and performant as Hot Chocolate.

Simpler applications will not have complex needs that require feature rich libraries. But, beyond a certain level of complexity, you are on your own. And large orgs do create their own tooling and libraries. But, smaller orgs probably should stick to languages that offer large number of libraries to handle a vast number of problems. Anything else would be putting yourself at a competitive disadvantage.

Re: Switching to Elixir

#245

Earlier quoted context omitted.

I mostly agree with you. Just wanted to add that in some languages, for example in Typescript, there are ways to say that you do not care about the type for prototyping. For example using :unknown or :any.

:unknown is great, but the problems come in the middle area; when you have lots of very tight types and are prototyping something that makes use of those things, :unknown doesn't work, and :any can be too expressive, even for your prototype.

Sorry, but that is moving the goalposts. Quick prototyping was mentioned, but now we seem to be talking about some undefined balance between typing and no typing for prototyping. It seems :any solves the problem.

Re: Switching to Elixir

#246
post #76

Earlier quoted context omitted.

You are overthinking some of it at least when it comes to concurrency. Look at what a process is and how send works. GenServer is a natural generalization of a pattern you’d write a thousand times. Knowledge of actors is transferable. Go has libraries which implement actor abstractions for example. Process mailboxes are just message queues like Go’s channels are. There are differences with respect to how the interpre…

I was gonna say the actor model stems from state machines I believe. It's a nice way to manage state and communication. It reminds me of supervisors and processes in general but not program language specific.

Erlang developed the way it did before people started calling it an Actor model.

The key characteristic is not a state machine, but that:

- first class processes send messages to each other

- messages are queued

- each process is single execution flow. If you want to reenter code, start another process and send messages to it

- process execution can be preempted

- values passed in messages are for the most part, immutable.

- first class support for “links”, where one process gets notified when another process crashes (basis for supervision trees)

The consequences of this design are:

- for the most part, you don’t need mutexs

- spin locks are cheap

- every process can be suspended indefinitely when nothing is in the message queue. This is better than an async reactor.

- processes don’t get “lost” (I am looking at you, Nodejs)

- processes can receive control messages to suspend or shutdown, restart, etc. Most other platforms have to externalize that to say, K8S and such controls are crude.

- errors don’t get “lost” (Nodejs again …)

- repl in production, can inspect the whole system live, under load

- overloaded systems degrades gracefully instead of locking up

Re: Switching to Elixir

#247
post #158

Earlier quoted context omitted.

Elixir is definitely a better Nodejs... that JS developers don't know about.

It took me months before it sank in that Nodejs async wasn't really async as I knew it from Elixir -- there's an implicit queue, and no true suspension of the execution flow. One justification for this was that it is supposed to make it easier to reason. It made it more difficult for me to reason -- maybe single-threaded async reactor is a poor substitute for immutability. Unhandled promise rejection is an example of…

> One justification for this was that it is supposed to make it easier to reason.

It’s a valid justification because it makes it substantially easier to reason compared to mutable multithreaded languages/runtimes such as C(++), Java and C#.

Eg a semaphore in JS doesn’t exist. It’s just a boolean. Interlocked Increment doesn’t exist. It’s just someVar++. And so on, it’s very nice.

That doesn’t mean that there aren’t other setups (such as immutable data with message passing) that are even easier to reason about. Every new tech compares itself to the current mainstream.

Re: Switching to Elixir

#248

And still 0 successful startup has been built on top of elixir.

Real talk. HN posts on anything OTP continue to be the same echo chamber of responses, with most readers just leaving them to it. Many people have been trying to nicely point out that "uses Elixir in some places" is not the same as "built on Elixir". ie It's exceedingly rare for any system to have a secret sauce called Elixir and none of them have sparked a race to use it. How many decades before someone points out i…

Thank you for posting this, it also sums up some of my feelings. I would also stress that the Windows story with Elixir/Erlang last I checked was quite miserable coming from .NET. It's not the easiest thing to just fire up and try out unless you are in the *nix world.

Sorry you are getting downvoted by the hive-mind.

Re: Switching to Elixir

#249
post #64

And still 0 successful startup has been built on top of elixir.

SumUp (8B valuation) uses Elixir and I'm sure there are more. https://www.crunchbase.com/organization/sumup https://www.sumup.com/careers/positions/berlin-germany/engin...

SumUp backend is built on Go. They use Elixir only for some hardware things. It seems more like a toy thing for them.

Ref: https://www.sumup.com/careers/positions/

Re: Switching to Elixir

#250
post #96
post #76

Earlier quoted context omitted.

You are overthinking some of it at least when it comes to concurrency. Look at what a process is and how send works. GenServer is a natural generalization of a pattern you’d write a thousand times. Knowledge of actors is transferable. Go has libraries which implement actor abstractions for example. Process mailboxes are just message queues like Go’s channels are. There are differences with respect to how the interpre…

Riak was pretty bad at ops. Leaving and joining nodes took ages and god forbid you tried to use any of the added features like solr search. If you settled on a very small subset of all features it worked nicely... it just wasn't very useful if anything went wrong due to app or user error.

I think that was before things like raft or paxos

I had some similar issues with rabbitmq

On the other hand, Phoenix channels were much more flexible about membership

Post reply on HN