[swift-evolution] ternary operator ?: suggestion

Craig Cruden ccruden at novafore.com
Fri Jan 8 07:09:19 CST 2016


Interesting, I have to take more time digging down.  

BTW, would it not be `case .Red in “0xFF0000” ` not case .Red: “0xFF0000” since `=>` in Swiftese is `in` 


> On 2016-01-08, at 19:58:45, Thorsten Seitz <tseitz42 at icloud.com> wrote:
> 
> 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 <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 <mailto: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 <mailto: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/1dda3c1c/attachment.html>


More information about the swift-evolution mailing list