`coerce` reminds me of Ruby's `coerce`, which serves the purpose of upgrading values, but can also swap the arguments. So, for example, if you had `1 + obj`, `obj` could have a method called `coerce` that took `1` and returned `[obj, 1]`. Then, ruby would treat that as `obj + 1` and use the `+` method from `obj` instead of `1`. The swapping of arguments are only useful as long as the operations are commutative, though.
Anyways, thought I'd mention the prior art in case it's useful. Allen Madsen http://www.allenmadsen.com On Wed, Dec 14, 2016 at 6:49 AM, Wiebe-Marten Wijnja < [email protected]> wrote: > I have been thinking longer about this. > > I think that the across-type implementation is overkill; I have a lot of > trouble to come up with cases where this would be useful: Cases that I can > think of can readily be solved by wrapping the inner structure in a > containing struct, which is obviously more clear/explicit than providing a > two-typed frankenprotocol. > > > I have been working on Numbers, which is basically dispatches arithmetic > operations to any structs that implements its standardized Numeric > behaviour. In this case, this means that functions/modules/structs can be > written that wrap *any* kind of thing that implements the behaviour, > which means that e.g. my Tensor library allows addition/multiplication to > performed regardless of if the contents of the vectors/matrices/tensors are > `Integer`s, `Float`s, `Decimal`s, `Ratio`nals or even `ComplexNum`bers. > > I think that such a *standardized* way constructing something still is > very important in the core language, because a standardized API means that > modules consuming the API can use any modules(/data types) that are > exposing the API. > > I now envision the following, much simpler and less 'new language > feature'-heavy than my original proposal: > > --------------------- > > There is a *normal* protocol called Comparable, exposing two functions > that can be overridden: > > - *compare(a, b)* compares the two structs `a` and `b` of the same > type. This function should return `:lt`, `:gt`, or `:eq` (keeping with the > specification that DateTime.compare and Time.compare already follow). If > there is no sensible way to compare the two types, a > *Comparable.CannotCompareError* should be raised, with a describing > error message. The *Any* implementation always raises this error. > - *coerce(some_builtin_value)*. Can optionally(!) be implemented to > allow certain standard data types (e.g. numbers, or strings) to be > automatically converted to the type of the thing we want to compare it > with, to allow shorter notation for things like `compare(Decimal.new(2), > 3)`. The *Any* implementation always raises > *Comparable.CannotCompareError*. > > There is a new function in the Kernel function *Kernel.compare(a, b)* has > the following variants: > > # struct <=> struct > Kernel.compare(a = %someStruct{}, b = %someStruct{}), do: Comparable. > compare(a, b) > # struct <=> differentStruct > Kernel.compare(a = %someStruct{}, b = %someDifferentStruct{}), do: raise > Comparable.CannotCompareError, message: "Cannot compare #{inspect(a)} > with #{inspect(b)}." > # struct <=> builtin > Kernel.compare(a = %someStruct{}, b), do: Comparable.compare(a, Comparable > .coerce(b)) > # builtin <=> struct > Kernel.compare(a, b = %someStruct{}), do: Comparable.compare(Comparable. > coerce(a), b) > # builtin <=> builtin, use Erlang's built-in term ordering. > Kernel.compare(a, b) when a == b, do: :eq > Kernel.compare(a, b) when a < b, do: :lt > Kernel.compare(a, b), do: :gt > > > > > > > > > -- > You received this message because you are subscribed to the Google Groups > "elixir-lang-core" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > To view this discussion on the web visit https://groups.google.com/d/ > msgid/elixir-lang-core/a7e59ba9-699b-42db-a81f- > cbda00179fc8%40googlegroups.com > <https://groups.google.com/d/msgid/elixir-lang-core/a7e59ba9-699b-42db-a81f-cbda00179fc8%40googlegroups.com?utm_medium=email&utm_source=footer> > . > > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "elixir-lang-core" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/CAK-y3CvyN4SjtVjo%2BYmXTwwGfqy%3D0nV5E%2BENFoDznXOMcMEz9g%40mail.gmail.com. For more options, visit https://groups.google.com/d/optout.
