`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.

Reply via email to