Defining operations using protocols

I need to define a protocol for a scientific application based on quantities of various types. I want to use protocols since they abstract my code nicely. Is there a valid way to re-define math operators in protocols, e.g.

defprotocol PhysQuant do
@doc “Compute arithmetic operations”
def qa + qb
def qa - qb
def qa * qb
def qa / qb
def qa ^ qb
def exp(quantity)
def sin(quantity)
def cos(quantity)
def tan(quantity)
end

Thanks in advance.

Please use triple backtick blocks to format code: Markdown cheat sheet.

And no, Erlang and Elixir do not allow overriding of operators per se. You are much better off using function names like add, sub, mul, div, mod etc.

It’s possible. You can un-import from Kernel and re-import. For example:

However, it’s somewhat discouraged.

3 Likes

Agreed. Another approach is to limit operator overrides to a macro call so that outside of it things continue to work as usual. Here’s a proof-of-concept I did for Decimal [1] a while ago:

iex> require DecimalEval
iex> a = 1
iex> b = 2
iex> DecimalEval.eval (a + b) * "3.0"
#Decimal<9.0>

[1] https://github.com/wojtekmach/decimal_eval

3 Likes

Thank you. The code in your link clarified many other questions I already had.

1 Like

just keep in mind that 1) the changes are lexically scoped. That’s a good thing ™ since it contains the statefulness of potentially confusing conventions and 2) the changes are strictly opt-in, you can’t enforce it globally (AFAIK) and 3) they’re not composable. If someone else has a library that does that you can’t use it in the same code block as yours.