Proposal: Pattern Matching Partial Function (#111)

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).

Implicit return already does work for an expression (and it wouldn't make much sense elsewhere) and the case list should be an expression. Maybe this has to be stated more explicitly?

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 think type inference when using implicit return has to be improved. This might be a separate proposal.

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.

Fair enough.

-Thorsten

···

Am 09. Februar 2016 um 14:47 schrieb Dany St-Amant via swift-evolution swift-evolution@swift.org:

Le 9 févr. 2016 à 01:00, Thorsten Seitz tseitz42@icloud.com a écrit :
Am 09.02.2016 um 01:51 schrieb Dany St-Amant via swift-evolution swift-evolution@swift.org:

Le 8 févr. 2016 à 10:54, Thorsten Seitz tseitz42@icloud.com a écrit :
Am 07.02.2016 um 16:47 schrieb Dany St-Amant via swift-evolution swift-evolution@swift.org:

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.

The `case` inside a closure is not a new concept. Scala (among I think a few other functional languages) implements `case` as a partial function inside closures.

I actually use it quite widely, but not as often as I would use it if it were in Swift - since Scala also implements a match expression (which for the most part would be the same as the match function in Swift - with the exception that it does not need function brackets).

Given that at most we will get a match expression or the partial function `case` structure - I would prefer the `case` structure because it gives us both.

···

On 2016-02-09, at 22:08:16, Thorsten Seitz via swift-evolution <swift-evolution@swift.org> wrote:

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.

Fair enough.