Nil coalescing operator (?) and function vars


(Peter Eddy) #1

Hello,

I'd like to understand why I'm unable to use the nil coalescing operator
with functions.

For example, I'd like to write a function that takes an optional function
as a parameter and that uses the nil coalescing operator to select a
default function if the function's function parameter is nil, e.g:

    func test(x: ((String) -> String)? = nil) {

      let qq = { (p:String) -> String in return "..." }

      let fn: String -> String = x ?? qq

      fn("test")
    }

When I do this the compiler complains that:

  Binary operator '??' cannot be applied to operands of type '((String) ->
String)?' and '(String) -> String:

In the Swift 2.2 Language Guide (
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/BasicOperators.html)
it states:

The nil coalescing operator is shorthand for the code below:

   1. a != nil ? a! : b

If I use the longhand option then the complier's fine:

    func test(x: ((String) -> String)? = nil) {

        let qq = { (p:String) -> String in return "..." }

        let fn = x != nil ? x! : qq

        fn("test")
    }

So why doesn't the nil coalescing operator work for function vars?

thanks!


(David Sweeris) #2

Looks like a bug to me.

You can work around it either by substituting the long version:
let fn:(String) -> String = x != nil ? x! : qq
or by declaring qq & fn like this:
let qq:(String -> String)? = { _ in return "..." }
let fn:String -> String = (x ?? qq)!
or like this:
let qq:(String -> String)! = { _ in return "..." }
let fn:String -> String = x ?? qq

Hope that helps.

- Dave Sweeris

···

On Apr 18, 2016, at 1:42 PM, Peter Eddy via swift-users <swift-users@swift.org> wrote:

Hello,

I'd like to understand why I'm unable to use the nil coalescing operator with functions.

For example, I'd like to write a function that takes an optional function as a parameter and that uses the nil coalescing operator to select a default function if the function's function parameter is nil, e.g:

    func test(x: ((String) -> String)? = nil) {

      let qq = { (p:String) -> String in return "..." }

      let fn: String -> String = x ?? qq

      fn("test")
    }

When I do this the compiler complains that:

  Binary operator '??' cannot be applied to operands of type '((String) -> String)?' and '(String) -> String:

In the Swift 2.2 Language Guide (https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/BasicOperators.html) it states:

The nil coalescing operator is shorthand for the code below:

a != nil ? a! : b
If I use the longhand option then the complier's fine:

    func test(x: ((String) -> String)? = nil) {
  
        let qq = { (p:String) -> String in return "..." }
  
        let fn = x != nil ? x! : qq

        fn("test")
    }

So why doesn't the nil coalescing operator work for function vars?

thanks!
_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Chris Lattner) #3

This is a bug, which has already been fixed in master. The fix will go out with Swift 3.

-Chris

···

On Apr 18, 2016, at 11:42 AM, Peter Eddy via swift-users <swift-users@swift.org> wrote:

Hello,

I'd like to understand why I'm unable to use the nil coalescing operator with functions.

For example, I'd like to write a function that takes an optional function as a parameter and that uses the nil coalescing operator to select a default function if the function's function parameter is nil, e.g:

    func test(x: ((String) -> String)? = nil) {

      let qq = { (p:String) -> String in return "..." }

      let fn: String -> String = x ?? qq

      fn("test")
    }

When I do this the compiler complains that:

  Binary operator '??' cannot be applied to operands of type '((String) -> String)?' and '(String) -> String:

In the Swift 2.2 Language Guide (https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/BasicOperators.html) it states: