[swift-evolution] Strings in Swift 4

Karim Nassar karim at karimnassar.com
Sun Jan 22 13:25:26 CST 2017


> From: Dave Abrahams <dabrahams at apple.com>
> To: Brent Royal-Gordon <brent at architechies.com>
> 
>> 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…

—Karim


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170122/7676675e/attachment.html>


More information about the swift-evolution mailing list