Have you read the code of the implementation 
<https://github.com/Qqwy/elixir_experimental_comparable/blob/master/lib/comparable.ex>
 
that was talked about earlier in this topic? It works in a way that is 
similar to the solution you propose, with the difference that dispatching 
does not work based on a pattern match, but based on the extracted struct 
names (and for the built-in types, guard-clause matches).

I do not think your solution (e.g. 'some macro' that outputs the code 
snippet you outlined)  is able to work across projects, where Project A 
defines a data type, Project B defines a data type, Project C defines a 
frequent way of comparing A and B, and A, B and C are used by some person 
in his personal project D, together with another custom data type D that 
should be able to compare to both A and B as well.
The only way for all of these data types to work together, is to make 
something that can be extended after its original definition was made. It 
is not possible to 'add more clauses to a function' after the module it is 
contained in is closed and compiled. This is the fundamental problem with 
and the fundamental difference in the solution you have proposed.


On Tuesday, August 30, 2016 at 12:52:49 AM UTC+2, OvermindDL1 wrote:
>
> On Monday, August 29, 2016 at 3:14:04 PM UTC-6, José Valim wrote:
>>
>>
>>> This could indeed be faster, however you'd have to get everything to 
>>> agree on a single representation (a special tuple format perhaps? but then 
>>> how would that rank with other tuples?).   
>>>
>>
>> You don't have to agree on a format though. Imagine Decimal defines its 
>> own format and Rational defines another, as long as at some point you 
>> implement each other protocols, anywhere, it will work just fine. That's 
>> the beauty of protocols after all! In the worst scenario, it will 
>> degenerate to the case we are talking about right now: (n * (n - 1) / 2) 
>> implementations?
>>
>
> They certainly could do that yep, but the code to compare their formats 
> still has to be somewhere, all my suggestion does is state where that 
> somewhere should be (a prolog'y style relationship description, which 
> erlang is awesome at and well optimized for), with only a single module 
> (but potentially a lot of matches, which if organized well will be *very* 
> efficient, log(N)).  :-)
>
>
> On Monday, August 29, 2016 at 3:35:51 PM UTC-6, Wiebe-Marten Wijnja wrote:
>>
>> What we miss when doing a pre-compile step, is things like:
>>
>> {A} should be comparable with {B}, {B} should be comparable with {C}, but 
>> {A} and {C} cannot be compared in a meaningful way.
>> I cannot think of a practical example right now, but I think it is a 
>> valid problem.
>>
>
> My suggested method does support this (it would throw some error if {A} 
> and {C} were compared).
>
>
> On Monday, August 29, 2016 at 3:35:51 PM UTC-6, Wiebe-Marten Wijnja wrote: 
>
>> Also, when a third data type needs to be added to an existing 
>> intermediate representation, how can this be done? There will be cases in 
>> which this existing intermediate representation is no longer valid, but 
>> you're unable to change the protocol implementations of those other types, 
>> so you're stuck.
>>
>
> Yeah just like with protocols, no real good way to update it without 
> hot-code swapping. 
>
>
> On Monday, August 29, 2016 at 3:35:51 PM UTC-6, Wiebe-Marten Wijnja wrote:
>
>> I also think that there are many cases in which it might be impossible to 
>> come up with a proper intermediate format. We have both Enum.sort_by (which 
>> uses a Schwarzian Transform, i.e. it first creates an intermediate 
>> representation for all data elements and then sorts based on these) and the 
>> normal Enum.sort. Although it usually is faster, there are cases where it 
>> is impractical or impossible to use Enum.sort_by.
>>
>> An example: What about cases like Rock, Paper Scissors? Rock < Paper, 
>> Paper < Scissors, Scissors < Rock? Although there is no *complete* order 
>> for these data structures, we *do* want to be able to compare individual 
>> pairs.
>>
>
> Which my suggestion also supports.  Would be an interesting trouble for a 
> fully typed system though...
>
>
> On Monday, August 29, 2016 at 3:35:51 PM UTC-6, Wiebe-Marten Wijnja wrote:
>
>> Another nice edge case that would go completely wrong with an 
>> intermediate-representation approach, would be NaN, which is unequal to 
>> everything else, including itself.
>>
>
> Which my suggestion could also support (perhaps by throwing an error, or 
> return a :non_comparable atom or something, whatever was wanted).
>
>
> On Monday, August 29, 2016 at 3:35:51 PM UTC-6, Wiebe-Marten Wijnja wrote:
>
>> So, I think it is paramount to create a multiprotocol or multimethod 
>> <http://clojure.org/reference/multimethods>-like approach that works on 
>> the *relationship or combination *of the two types being compared. On an 
>> *edge* of the graph, rather than on a node like normal protocols do. 
>> After all, a comparison is something that is about the relationship between 
>> two things. You cannot compare a single thing.
>>
>
> My suggestion follow a very prology way, which is precisely relationship 
> descriptions (which erlang is awesome at).
>
>

-- 
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/9061c22b-cfe6-4649-a6a1-83259489129d%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to