[swift-evolution] Proposal: Pattern Matching Partial Function (#111)

Dany St-Amant dsa.mls at icloud.com
Tue Feb 9 07:47:31 CST 2016


> Le 9 févr. 2016 à 01:00, Thorsten Seitz <tseitz42 at icloud.com> a écrit :
> 
> 
> 
> Am 09.02.2016 um 01:51 schrieb Dany St-Amant via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>>:
> 
>> 
>>> Le 8 févr. 2016 à 10:54, Thorsten Seitz <tseitz42 at icloud.com <mailto:tseitz42 at icloud.com>> a écrit :
>>> 
>>> 
>>> 
>>> Am 07.02.2016 um 16:47 schrieb Dany St-Amant via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>>:
>>> 
>>>> Assuming this implicit return part of this proposal get generalized, could we instead of the dedicated match function have a generic way to feed the parameters to the closure at the start, where it would make sense for the desired switch usage.
>>>> 
>>>> let str:String = (state) -> { switch $0 { case .Cold: "Too Cold"; case .Hot: "Too Hot"; default: "Just right" } }
>>> 
>>> That's easy, just use the match() function from the proposal:
>>> 
>>> let str:String = match(state) { switch $0 { case .Cold: "Too Cold"; case .Hot: "Too Hot"; default: "Just right" } }
>>> 
>>> No new syntax needed for that.
>> 
>> As/if the implicit returns is generalized, I feel that match is bit out of place in the for nested if. I should have provided an example to clarify my thought. Here’s one, where the :? do a better job, but this thread has its origin in came people not liking this sometime cryptic operator (which I like to use)
> 
> I like :? too, btw.
> 
>>     str = major > 0 ? "Major" : minor > 0 ? "Minor" : "None"
>> 
>> which is ill suited for switch case but doable.
> 
> No need to press something into switch which does not fit.
> The proposal is not about using switch for everything and it is not about replacing the ternary operator. It is more about making a switch expression available.

Of course, it’s not about what should remain unmentioned (saying it out loud three time may cause that thread to come back and haunt us).
But while the proposal can be mainly read as:

- provide a special case-list closure (aka pattern matching partial function dedicated to switch) and expand implicit returns support for this closure type only.

it could also be read as

- expand the implicit returns support for all closure, allow such closure to skip the switch keyword; be the case list (aka pattern matching partial function).

I do think that safely expanding the implicit returns support in either the dedicated closure or the general closure would be roughly the same.

I’m not sure where I stand on the switch-less case-list closure, but I am afraid that providing such dedicated closure syntax may set a precedent and cause others to want yet another dedicated closure syntax for their own goal; how do we consider a special closure syntax as acceptable, how many of them are too many. This is why, I’m looking at it from a wide angle view; an expanded implicit returns support safely done could benefit other general cases. Doing this as a first step, will miss 50% of this proposal (still need to use switch ($0)), but the overall use case goal will still be achieved; being able to do something like; let something = condition ? data1 : data2; for more complex scenarios.

I’m having trouble following my own train of thought, but I think it’s leading me toward  having the "safely expanded implicit returns » portion extracted as its own proposal for general purpose, which this proposal can then rely on.

> 
>>     switch (major,minor) {
>>         case (_, _) where major > 0: str="Major"
>>         case (_, _) where minor > 0: str="Minor"
>>         default: str="None"
>>     }
> 
> Rewriting a little bit I don't think switch looks that bad even for your example:
> 
> switch (major,minor) {
> case _ where major > 0: "Major"
> case _ where minor > 0: "Minor"
> default: "None"
> }
> 
> 
>> Assuming that the implicit returns is generalized to all closures (and even functions like getter), of course only for the one matching my safety rule (in short single statement/function call/exhaustive if or switch). The if  can be express as, using the new global match function:
>> 
>>     str = match(major,minor){ if $0 > 0 { "Major" } else if $1 > 0 { "Minor" } else { "None" } }
>> 
> 
> Making `if` into an expression (which would be a requirementbhere) has been more or less ruled out by Chris Lattner. 

I recall some oppositions early on, but I do not recall if it was before the thread move into closure territory.
Don’t forget my example here as two big if:
- if we generalized the implicit return done safely to any closure.
- if we try to call the closure passing the parameters with the only (to be) available prefix syntax

Dany

> 
>> 
>> or using normal inline closure calls:
>> 
>>     str = { if $0 > 0 { "Major" } else if $1 > 0 { "Minor" } else { "None" } }(major,minor)
>> 
>> versus the feeding I wonder about:
>> 
>>     str = (major,minor) -> { if $0 > 0 { "Major" } else if $1 > 0 { "Minor" } else { "None" } }
>> 
>> Maybe it’s just me, but the match function feels a bit weird, in the first version.
> 
> I agree. That's why it is accompanied by the partial function closure syntax which effectively results in a switch or rather match expression.
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160209/4fc6063b/attachment.html>


More information about the swift-evolution mailing list