Someone recently asked “What feature would you most like removed from your language?”
And, for me, it has to be structs or the way Elixir currently handles them.
In my job, we do a lot of deployments on distributed clusters, either pushing hot code updates against running servers for small changes or running multiple versions of our code side-by-side in the cluster as we do rolling deployments for large changes.
Thus far, we’ve had zero downtime running with a cluster of roughly 30 servers (knock hard on wood) over the last year and a half (since we went into production).
Our biggest difficulty (and danger) has been Elixir’s structs. While Erlang was designed for our kind of environment, it feels like Elixir broke away from it with its struct implementation.
To explain, functions that handle structs don’t happily duck-type them. If you make changes to a struct definition and move it between nodes, you can’t match on it unless all the fields are in perfect agreement. So there’s no easy way to update them in the running system.
We don’t let any data that moves between nodes contain them.
And this is where it gets really ugly. A lot of Elixir’s base data types are implemented as structs, such as Range and DateTime.
So, what seems like a simple non-breaking change for the language, as when the recent version of Elixir added step
to Range, could actually cause catastrophic chaos on our distributed system.
I would propose that Elixir consider making structs act as duck-typed maps in the future as I love the language, but I hate to see it limiting the power of the original VM and ecosystem.