> Le 24 janv. 2017 à 05:29, Gwendal Roué <[email protected]> a écrit :
> 
> 
>> Le 24 janv. 2017 à 04:31, Brent Royal-Gordon via swift-evolution 
>> <[email protected] <mailto:[email protected]>> a écrit :
>> 
>>>> The operands and sense of the comparison are kind of lost in all this 
>>>> garbage. You really want to see `foo < bar` in this code somewhere, but 
>>>> you don't.
>>> 
>>> Yeah, we thought about trying to build a DSL for that, but failed.  I think 
>>> the best possible option would be something like:
>>> 
>>>  foo.comparison(case: .insensitive, locale: .current) < bar
>>> 
>>> The biggest problem is that you can build things like
>>> 
>>>    fu = foo.comparison(case: .insensitive, locale: .current)
>>>    br = bar.comparison(case: .sensitive)
>>>    fu < br // what does this mean?
>>> 
>>> We could even prevent such nonsense from compiling, but the cost in library 
>>> API surface area is quite large.
>> 
>> Is it? I think we're talking, for each category of operation that can be 
>> localized like this:
>> 
>> * One type to carry an operand and its options.
>> * One method to construct this type.
>> * One alternate version of each operator which accepts an operand+options 
>> parameter. (I'm thinking it should always be the right-hand side, so the 
>> long stuff ends up at the end; Larry Wall noted this follows an "end-weight 
>> principle" in natural languages.)
>> 
>> I suspect that most solutions will at least require some sort of overload on 
>> the comparison operators, so this may be as parsimonious as we can get. 
> 
> SQL has the `collate` keyword:
> 
>       -- sort users by email, case insensitive
>       select * from users order by email collate nocase
>       -- look for a specific email, in a case insensitive way
>       select * from users where email = '[email protected] 
> <mailto:[email protected]>' collate nocase
> 
> It is used as a decorator that modifies an existing sql snippet (a sort 
> descriptor first, and a comparison last)
> 
> When designing an SQL building to Swift, I chose the 
> `nameColumn.collating(.nocase)` approach, because it allowed a common Swift 
> syntax for both use cases:
> 
>       // sort users by email, case insensitive
>       User.order(nameColumn.collating(.nocase))
>       // look for a specific email, in a case insensitive way
>       User.filter(nameColumn.collating(.nocase) == "[email protected] 
> <mailto:[email protected]>")
> 
> Yes, it comes with extra operators so that nonsensical comparison are avoided.
> 
> But it just works.

I should have explained more the sql approach:

The collation (a comparison function) is attached to a *value*. It is part of 
its type. You can attach a collation to a table column, or, when a column has 
no collation, add the collation at the "call site", as in the examples above.

The collation belongs to the type, and the value "knows" how it is supposed to 
be compared.

An example of string which fits well in such a frame is hexadecimal 
representations of UUIDs: they should inherently be compared in a 
case-insensitive way.

That's why attaching the comparison options to the value is not necessarily a 
bad idea, and has been used for years, with success, by SQL.

Gwendal

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to