[swift-evolution] Brainstorming: Optional sugar inferred map

Paul Ossenbruggen possen at gmail.com
Sat Jan 30 11:02:14 CST 2016

This is all still in the brainstorming realm. The issue is that doSomething looks like it should always be called. I think that the nil coalescing operator works here:

func doSomething(value: Int) -> Int {
    return value
let pf : Int? = 5
let py : Int? = nil

// the following is:
let gf = pf ?? doSomething(pf!) 
let gy = py ?? doSomething(py!)

gf -> 5
gy -> nil

// is the equivalent of:
let ff = pf.map { doSomething($0) }
let fy = py.map { doSomething($0) }

ff -> 5
fy -> nil

This works with the language as it stands today but I don’t like the forced unwrap. However, with the rest of the proposal this would work because  pf? would give you the unwrapped value, which would not be nil at that point.

let gf = pf ?? doSomething(pf?) 
let gy = py ?? doSomething(py?)

But one outstanding issue is that gf and gy would not be optional unless you explicitly write out the type like this.

let gf : Int? = pf ?? doSomething(pf?) 
let gy : Int? = py ?? doSomething(py?)

I think this is in line with the language as it is today. Unless we want to add a new sugar to upgrade an optional 

let gf? = pf ?? doSomething(pf?) 
let gy? = py ?? doSomething(py?)

where if there is a let or var assignment with a question mark the type is upgraded to an optional.


Moving back to the more complex example. The more complex example would require another construct. We would need to have a way to add a block.for nil coalescing but pretty sure that would not be approved and it probably creates other problems. Assuming that doSomething else is a void function. 

  let dd  = n ?? { manager.doSomething(data: data, count: n!); doSomethingElse( n! ) }

So without adding more constructs you would have to do this for the more complex example:

   let dd  = n ??  manager.doSomething(data: data, count: n?)
   if let n = n {
   	doSomethingElse( n ) 

In which case you might as well do this:

   let dd : Int? = nil
   if let n = n {
	 dd = manager.doSomething(data: data, count: n)
   	 doSomethingElse( n ) 

But I think the more complex example will be rare and the last example is fine should you have a complex situation

> Another conundrum: are the optional-pattern arguments evaluated before any other arguments? After?

> I think the two statements would behave separately (as if you had used map twice).
> If you want them to act together, you could do this: 
> { manager.doSomething(data: data, count: $0); doSomethingElse($0) }(n?)
> Another aspect worth considering is whether this syntax should work with multiple optionals used in the same expression. (e.g. if they are all non-nil, the expression is evaluated.)

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

More information about the swift-evolution mailing list