[swift-evolution] ternary operator ?: suggestion

Thorsten Seitz tseitz42 at icloud.com
Fri Jan 8 06:58:45 CST 2016


That is not a feature of Scala’s map or filter functions.

Writing { case (x, y) => x + y } just defines an anonymous unary function, more specifically a partially defined function or PartialFunction (http://www.scala-lang.org/api/current/index.html#scala.PartialFunction).

Btw: partial functions are quite cool as they can be chained, e.g. by „orElse“ if the first function is not defined for a given input. This allows quite nice abstractions (I’m thinking or error handler functions, for example).

So the question is whether we would want something like that in Swift, too, i.e.

{ case <pattern1>: <expr1> [case <pattern2>: <expr2>]* [default: <expr>] } 
would define a unary function which matches its input against the case patterns and returns value of the matching expression.

(It would probably make sense to introduce partial functions as well on top of that, i.e. make this a partial function which might even statically know that it is defined everywhere in case the compiler can check the exhaustiveness of the patterns.)

Then we could simply define the following function

func match<T,U>(x: T, f: T -> U) {
	return f(x)
}

which would allow us to write a switch-expression without any further syntax extensions:

let value = match(color) { 
	case .Red: "0xFF0000“
	case .Green: "0x00FF00“
	case .Blue: "0x0000FF“
}

And we could also just write the map example Craig gave with no magic in the definition of map required:

num.map {
	case x where x < 5: x + 1
	case x: x - 1
}


For comparison: with my proposal of a ternary-like switch-expression this would look like follows instead:

num.map { elem in elem?
	case x where x < 5: x + 1
	case x: x - 1
}

where we are using the switch-expression

elem?
	case x where x < 5: x + 1
	case x: x - 1


But then the question arises: shouldn’t { case <pattern>: <expr> … } allow statements, too?
I would think so.
In Scala this is allowed, e.g. I can write
val f: PartialFunction[Any, Int] = { case x: Int => { println(x); x + 1 } }

-Thorsten



> Am 08.01.2016 um 06:11 schrieb Craig Cruden via swift-evolution <swift-evolution at swift.org>:
> 
> I was thinking about this a bit, and was thinking that maybe we would not need a new keyword at all but just use `map` with pattern matching `case` clauses.  It would mean adding `map` to individual values — or anything that we might want to use as input for matching.  
> 
> Reference scala (section 8.5) pattern matching: http://www.scala-lang.org/docu/files/ScalaReference.pdf <http://www.scala-lang.org/docu/files/ScalaReference.pdf>
> 
> In scala inside `map` and `filter` (unfortunately not on things like `reduceLeft` or `foldLeft` you can specify pattern matching anonymous functions as such:
> 
> val num = List(1, 5, 7)
> 
> num.map {
>   case x if x < 5 => x + 1
>   case x => x - 1
> }
> 
> output: List(2, 4, 6)
> 
> So if the pattern matching was added (I don’t believe Swift currently allows case classes in maps - but then I am rather junior in the language) Swift would not need a `match expression` it would simply be part of map and become something like:
> 
> let commission = trade.map {
> 	case .Buy(let quantity, let price) where Double(quantity) * price > 10000 in
>     		Double(quantity) * price * vipCommissionRate / 100
> 	case .Buy(let quantity, let price):
>     		Double(quantity) * price * commissionRate / 100
> 	case .Sell(let quantity, let price) where Double(quantity) * price > 10000:
>     		Double(quantity) * price * vipCommissionRate / 100
> 	case .Sell(let quantity, let price):
>     		Double(quantity) * price * commissionRate / 100
> }
> 
> 
> 
> 
>> 
>> But if we go with brackets then I would recommend something like this: 
>> 
>> let commission = match (trade) {
>> case .Buy(let quantity, let price) where Double(quantity) * price > 10000:
>>     Double(quantity) * price * vipCommissionRate / 100
>> case .Buy(let quantity, let price):
>>     Double(quantity) * price * commissionRate / 100
>> case .Sell(let quantity, let price) where Double(quantity) * price > 10000:
>>     Double(quantity) * price * vipCommissionRate / 100
>> case .Sell(let quantity, let price):
>>     Double(quantity) * price * commissionRate / 100
>> }
> 
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


More information about the swift-evolution mailing list