binarypaladin
Why doesn't Elixir support standard operator overloading?
I’m working on a project right now that makes heavy, heavy use of Decimal. I just hit bug today where >= was used instead of Decimal.compare/2 and it’s not the first time I’ve seen this happen.
Additionally, Decimal has some nice convenience methods (as Java-esque as they are) such as eq?/2 and gt?/2. This is nicer than having to drop into compare/2.
It seems like protocols could totally make operator overloading a thing. I would obviously really like to just be able to do %Decimal{} + %Decimal{} and have it work like Decimal.add/2. And, coming from a Ruby background, I’m, used to overloading a lot.
These are just functions, yes? I can pipe with Kernel.+/2 and Kernel.==/2.
Having said all that, this seems quite deliberate and I feel like with as much as I have read I would have come across the answer but… I don’t know. And either my Googling skills are poor or I’m asking the wrong question.
Why doesn’t Elixir support standard operator overloading?
Marked As Solved
billylanchantin
If you want to go down the rabbit hole of why Elixir has made the choices it has, I suggest the following elixir-lang-core discussions:
- https://groups.google.com/g/elixir-lang-core/c/eE_mMWKdVYY (2016)
- https://groups.google.com/g/elixir-lang-core/c/W2TeQm5r1H4 (2022)
It’s a lot of back and forth, but it was pretty eye opening for me. In particular, I think this comment from José sums up the situation well:
There’s even an experimental implementation of a comparable protocol in that thread:
But the consensus seemed to be that such an implementation would be unwieldy in practice.
Also Liked
binarypaladin
Yeah, the reasons have been spelled out well in this thread. I honestly asked because if there is something I have come to expect from this language, it’s that the decisions always seem to have really solid reasoning, even where it doesn’t jive with my personal tastes. I figured from the start there were legit philosophical and technical reasons for it and looking through the mailing lists made that clear enough.
Yeah. Honestly, I kinda wish I hadn’t even brought that up. It was just me talking about how I like the way Ruby can be written, especially for a non-programmer. I don’t think Elixir would be better for it, but I also think it’s still fine to appreciate what other languages can do. It turned into… a fixation I didn’t intend in the conversation.
I think anyone who has been programming for very long knows how important precision is with dates. We all have horror stories, lol. The system I am working on right now is a real beast if you’re not extremely careful about bloody time zones!
This was the main thing I came for because that was the bug I hit. No warning. No nothing. And I know why it’s that way.
And hey, since I have you here… I love Elixir! It’s what I use professionally. I was a long time Rubyist (about 12 years) and I made the move. I still miss some bits but there’s no going back. You and your team have done such a good job with both the language and community. I can’t tell you how much it’s improved my work and me as a programmer.
I am continuously humbled by your ability to address even hostile comments with incredible wisdom and humility. I appreciate you taking the time to comment. Seriously.
josevalim
We don’t have the concept of primitives, as in those languages, but integer and float are built-in types and decimal is a custom one. So there is a clear demarcation here. In any case, if I could, I would support decimal + integer, but we can’t do it today without making it slower for all cases and without breaking guard semantics. The shortest way around this is to have decimal as a native VM type.
Other than that, I am very glad to not have date + 1.days, because there isn’t anything arithmetic about it. For example, it is not guaranteed that (date + duration) - duration == date. I do like 1.days though, as a mechanism to express durations, but I would be 90% as a happy if we had Date.shift(date, months: 1, days: 10) in Elixir (PRs are welcome, I consider this to be the last calendar feature missing in Elixir).
Finally, the hope is that once we have the type system, we will warn if you give a struct to any >, >=, <, and <=. It is pretty much a language pitfall that I hope we can address more reliably.
sodapopcan
You could do something like this:
defmodule MyDecimal do
defmacro __using__(_) do
quote do
import Kernel, except: [+: 2, -: 2, ...]
def left + right do
Decimal.add(left, right)
end
def left - right do
Decimal.sub(left, right)
end
# ...
end
end
end
For me, the lack of operator overloading is part of what makes Elixir a good dynamic language as it still cares about types. It’s also part of (all of?) what is enabling the possibility of strong arrows (if we get some static typing). If you looked at a language like OCaml it goes even further. + only adds ints, you need to use +. to add floats! And you must explicitly cast one side if you want to add a float to and int.
I don’t know if this is the exact reason Elixir doesn’t overload, though.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance










