I am back after a week of vacation.

A week ago, I discussed this in the Internet Relay Chat group with Jose 
Valim, Ben Wilson and Michał Muskała.

The conclusion was that the approach I made to defining a Comparable 
multiprotocol worked well, but would mean n(n+1)/2 Modules being created, 
if there are *n* custom types that all want to be compared to each other 
(including themselves). This is the sequence of triangular numbers 
<http://oeis.org/A000217>; If we have a single type that compares to 
itself, we'd need only the *1* implementation. If we have two types, we 
would need the implementation of comparing each of these types to 
themselves, as well as the comparison between them: *3*. For three types, 
we'd need *6* implementations, for four types *10*, etc.

Now while comparing all built-in Elixir types with themselves can happen 
without any new comparison-implementations (as Erlang's built-in 
comparisons work fine for this), this does mean that, when using custom 
data types, quite a few modules might be added. The only example I could 
think of was between four types of things (comparing integers, floats, 
Decimals <https://hex.pm/packages/decimal> and Rationals 
<https://hex.pm/packages/ratio> -- two of which are actually built in 
types), there might be cases where there are more types that want to be 
comparable.

If I remember correctly, the amount of modules that is being created was 
something that Jose and Michał disliked, and it sounded to me like it was 
some kind of deal-breaker that made this solution 'unsuitable'. 
As far as I can see, however, there is no way to reduce the amount of 
comparison-implementations, because the sequence of triangular numbers 
simply describes the total of amount of nodes in a fully-connected 
(undirected) graph.

As modules are the atomic compile-able unit on the BEAM, it makes the most 
sense to use one per comparison-implementation. Of course it is possible to 
do fancy stuff similar to protocol consolidation and smash multiple modules 
together, but I don't see what problem is solved by that.



So, I would like to know: 
- Why is it a 'bad' thing to define multiple modules?
- Are there any other things about this implementation that you do not 
like, and why?

Have a nice evening,

~Wiebe-Marten Wijnja

On Thursday, August 11, 2016 at 1:12:47 PM UTC+2, Wiebe-Marten Wijnja wrote:
>
> I discussed with Thomas Depierre (@di4na) today about this, and he 
> convinced me that atoms are indeed more explicit than integers, because 
> during debugging something that crashed, instead of seeing 'a number' as 
> result of the comparison function, you see 'a name' which is 
> self-describing.
>
> Instead of going with :lt, :eq and :gt, which do not follow Erlang's term 
> ordering, I came up with using :<, := and :>, which do, and are also the 
> mathematical symbols used when describing inequality.
> The experimental example implementation 
> <https://github.com/Qqwy/elixir_experimental_comparable> I posted before 
> has been updated to reflect this change.
>
>
> On Sunday, August 7, 2016 at 10:13:45 PM UTC+2, Michał Muskała wrote:
>>
>> Hello everybody, 
>>
>> Today I’d like to address one of annoyances of working with elixir - 
>> comparing structs. It’s a problem because of two reasons: 
>> - it’s not widely known that the regular comparison operators do not work 
>> correctly with structs 
>> - there’s no standard way of providing custom comparison function. 
>> This issue is especially apparent in couple libraries, most notably Ecto 
>> (with calendar types), decimal and with the new standard calendar types. 
>>
>> I propose adding a Kernel.compare/2 function with signature: 
>> compare(term, term) :: :lt | :eq | :gt 
>>
>> I would propose following properties of the function: 
>> - inlined implementation for built-in types, only for both arguments of 
>> the same type 
>> - for structs the function calls the Comparable.compare/2 protocol 
>> function 
>> - implementation for structs are allowed to return value for two 
>> different types when it makes sense 
>> - the protocol is also implemented for built-in types 
>> - the protocol does not fallback to Any 
>>
>> I’m convinced this will allow for much easier experience when comparing 
>> structs, even though the VM does not allow to extend the regular comparison 
>> operators. 
>>
>> Michał. 
>>
>>

-- 
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/e758e9bd-f9ba-4e4c-9d20-ed80dc1a8ca9%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to