Sent from my iPad

> On Jan 22, 2017, at 11:25 AM, Karim Nassar <[email protected]> wrote:
> 
>> From: Dave Abrahams <[email protected]>
>> To: Brent Royal-Gordon <[email protected]>
>> 
>>> While it's great that `compared(to:case:etc.)` is parallel to 
>>> `compared(to:)`, you don't actually want to *use* anything like 
>>> `compared(to:)` if you can help it. Think about the clarity at the use site:
>>> 
>>>   if foo.compared(to: bar, case: .insensitive, locale: .current) == .before 
>>> { … }
>> 
>> Right.  We intend to keep the usual comparison operators.
>> 
>> Poor readability of "foo <=> bar == .before" is another reason we think that 
>> giving up on "<=>" is no great loss.
>> 
>>> 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.
>> 
>>> I'm struggling a little with the naming and syntax, but as a general 
>>> approach, I think we want people to use something more like this:
>>> 
>>>   if StringOptions(case: .insensitive, locale: .current).compare(foo < bar) 
>>> { … }
>> 
>> Yeah, we can't do that without making 
>> 
>>      let a = foo < bar
>> 
>> ambiguous
> 
> 
> So, cue crazy idea #1, but what about something like this?
> 
> struct StringComparison {
> 
>       let leftHand: String
>       let rightHand: String
>       let comparison: SortOrder
> 
>       var insensitive: Bool {
>               ...
>       }
>       // … etc
> }
> 
> func <(lhs: String, rhs: String) -> StringComparison { // similar for ==, >, 
> etc.
>       return StringComparison(leftHand: lhs, rightHand: rhs, comparison: 
> .before)
> }
> 
> Then:
> 
>       if (a < b).insensitive {
>               ...
>       }
> 
> This would fix the ambiguity of:
> 
>       let a = foo < bar // ‘a' is StringComparison
>       if a.insensitive {
> 
>       }
> 
> IMHO, the big problem with this is that the most obvious default case really 
> should fall-through to a boolean value for the comparison struct:
> 
>       if a < b { // case-sensitive, non-localized compare
>               ...
>       }
> 
> ...but I can’t figure out how to make that work without the old BooleanType 
> protocol, maybe someone smarter than I could…

Yeah... IMO this is the language telling us "don't do that."  for my part, I'm 
not really in the market for ideas about how to do this that cut against the 
grain of the language.  I'd settle for a slightly less expressive API if it 
means avoiding surprising corner case behaviors.  And there's so much more to 
discuss here than how to clean up this syntax. If someone comes up with an 
expressive notation that's free of issues, we can always implement it as an 
add-on later.

-Dave

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

Reply via email to