[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