[swift-evolution] ternary operator ?: suggestion
Thorsten Seitz
tseitz42 at icloud.com
Fri Jan 8 07:34:30 CST 2016
> Am 08.01.2016 um 14:09 schrieb Craig Cruden <ccruden at novafore.com>:
>
> 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`
My take is that the „=>“ after „case“ in Scala corresponds to the colon after „case" in Swift but the waters are a bit muddy here as the „case <pattern>“ takes the role of a function parameter as well.
I wouldn’t want to have two different „case“ expressions in Swift, though. Either both should use the colon or both should use „in“.
-Thorsten
>> On 2016-01-08, at 19:58:45, Thorsten Seitz <tseitz42 at icloud.com <mailto: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 <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/e975f513/attachment.html>
More information about the swift-evolution
mailing list