Quickly read over, but why not just enforce that comparables must compare the same types only. So you could do `compare(some_date, Timex.now |> Time.add(4, :days))` or so, helper functions make that simple and keeps things explicit.
And yes, atoms should definitely be used, that is the erlangy way as well. On Monday, August 29, 2016 at 11:40:29 AM UTC-6, Wiebe-Marten Wijnja wrote: > > 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/ed92625c-7beb-48c6-ad6c-fb0cfd5b9925%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.
