Function types as return types

func oneStepForward(_ input: Int) -> Int {

 return input + 1

}

func oneStepBackward(_ input: Int) -> Int {

 return input - 1

}

func chooseStepFunction(backward: Bool) -> (Int) -> Int {

 return backward ? oneStepBackward : oneStepForward

//Error. type of expression is ambiguous without a type annotation

}

Why am I getting this error ?

If I change this function to the following it works and will compile.

func chooseStepFunction(backward: Bool) -> (Int) -> Int {

if backward {

   return oneStepBackward

} else {

return oneStepForward

}

}

// Why am I getting the error in the previous version while it works in the second version ?

Thx in advance.

Answered by DTS Engineer in 855058022

Yeah, this is definitely bugworthy. Dinisan, I’d appreciate you filing a bug about this, and then posting the bug number here, just for the record.

Given these:

func stepForward(_ input: Int) -> Int {
	input + 1
}
 
func stepBackward(_ input: Int) -> Int {
	input - 1
}

then these two fail:

func chooseStepFunctionNG1(backward: Bool) -> (Int) -> Int {
    backward ? stepBackward : stepForward
}

func chooseStepFunctionNG2(backward: Bool) -> (Int) -> Int {
    backward ? stepBackward(_:) : stepForward(_:)
}

but these three succeed:

func chooseStepFunctionOK1(backward: Bool) -> (Int) -> Int {
	if backward {
		stepBackward
	} else {
		stepForward
	}
}

func chooseStepFunctionOK2(backward: Bool) -> (Int) -> Int {
    backward ? (stepBackward as (Int) -> Int) : (stepForward as (Int) -> Int)
}

func chooseStepFunctionOK3(backward: Bool) -> (Int) -> Int {
    let result = backward ? stepBackward : stepForward
    return result
}

The gating factor seems to be type resolution with function types between the function result and the ?: operator. Fun times.

It works in iOS playground, but not in macOS playground

FWIW, I’m seeing it in both playground types, and also in a macOS > Command Line Tool target, which is by far the best way to test weird stuff like this (Playgrounds have all sorts of sharp edges). And yeah, in both Xcode 16.4 and Xcode 26.0b6.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Which Xcode version do you test with ? Do you test in playground or in app, or SwiftUI App ?

I tested in Xcode 16.4, with the following call:

print(chooseStepFunction(backward: true) (10))

And got 9 as expected.

I tested also in Xcode 26 ß6, works as expected.

How do you use chooseStepFunction? please give more context.

Thx for your reply .

I am using Xcode version 16.4 and running in a playground. Just by typing these functions in the IDE (without any calls to the functions) I get the error message in the Code Review Pane. It is a blank macOS playground running on a Mac Studio M1. The code is from Apple's Swift Programming Language (5.7). Section Functions - Function types as return types.

Accepted Answer

It works in iOS playground, but not in MacOS playground, either Xcode 16.4 or 26.0ß6.

So, that's definitely a bug you should report.

You got the answer in your SO post: https://forums.swift.org/t/why-is-there-a-type-of-expression-is-ambiguous-without-a-type-annotation-error-when-using-a-ternary-operator-on-inferred-function-types-in-swift/77306/2

As said, this works:

func chooseStepFunction(backward: Bool) -> (Int) -> Int {
    let res = oneStepBackward ? stepBackward : oneStepForward
    return res
}

Yeah, this is definitely bugworthy. Dinisan, I’d appreciate you filing a bug about this, and then posting the bug number here, just for the record.

Given these:

func stepForward(_ input: Int) -> Int {
	input + 1
}
 
func stepBackward(_ input: Int) -> Int {
	input - 1
}

then these two fail:

func chooseStepFunctionNG1(backward: Bool) -> (Int) -> Int {
    backward ? stepBackward : stepForward
}

func chooseStepFunctionNG2(backward: Bool) -> (Int) -> Int {
    backward ? stepBackward(_:) : stepForward(_:)
}

but these three succeed:

func chooseStepFunctionOK1(backward: Bool) -> (Int) -> Int {
	if backward {
		stepBackward
	} else {
		stepForward
	}
}

func chooseStepFunctionOK2(backward: Bool) -> (Int) -> Int {
    backward ? (stepBackward as (Int) -> Int) : (stepForward as (Int) -> Int)
}

func chooseStepFunctionOK3(backward: Bool) -> (Int) -> Int {
    let result = backward ? stepBackward : stepForward
    return result
}

The gating factor seems to be type resolution with function types between the function result and the ?: operator. Fun times.

It works in iOS playground, but not in macOS playground

FWIW, I’m seeing it in both playground types, and also in a macOS > Command Line Tool target, which is by far the best way to test weird stuff like this (Playgrounds have all sorts of sharp edges). And yeah, in both Xcode 16.4 and Xcode 26.0b6.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Thank you all for your time. I have reported the bug to Apple. The bug number is FB19843883

@DTS Engineer

Hi Quinn, I double checked, in an iOS playground, this time with an older Xcode (13.2) on an older Mac.

And it does work, as it did with Xcode 16.4, as shown by the screenshot.

Function types as return types
 
 
Q