Passing functions with default parameters

Hello Swift evolution community!

Developing in Swift, I have many times found myself being frustrated that a function with default parameters can’t be passed to another function.

For example:

// sorts a string alphabetically
func sort(string: String, descending: Bool = false) -> String {
  return String(string.sorted { descending ? $1 < $0 : $0 < $1 })
}

let strings = [”swift", ”apple”, ”ios”]

If I wanted to map over the strings and sort each one, I would expect this to work:

strings.map(sort(string:)) // expected output: [”fistw", ”aelpp”, ”ios”]

However, this produces the error: use of unresolved identifier 'sort(string:)’

Instead, I have to write:

strings.map { sort(string: $0) }

Anybody else that would appreciate this possibility?

1 Like

Hi Oskar,

This is actually something we’ve spoken about in the core team meetings in the past as a known thing that ideally would work but doesn’t. The one that hits me a often is that I wish .forEach(print) worked, as it’s very useful as a quick debugging command.

I don’t know if we’re tracking it on bugs.swift.org though, so it’d be good to see if you can find an SR for it there and if not, put your very clear explanation of the issue in a new SR.

Thanks,
Ben

···

On Jun 17, 2017, at 5:14 PM, Oskar Ek via swift-evolution <swift-evolution@swift.org> wrote:

Hello Swift evolution community!

Developing in Swift, I have many times found myself being frustrated that a function with default parameters can’t be passed to another function.

For example:

// sorts a string alphabetically
func sort(string: String, descending: Bool = false) -> String {
  return String(string.sorted { descending ? $1 < $0 : $0 < $1 })
}

let strings = [”swift", ”apple”, ”ios”]

If I wanted to map over the strings and sort each one, I would expect this to work:

strings.map(sort(string:)) // expected output: [”fistw", ”aelpp”, ”ios”]

However, this produces the error: use of unresolved identifier 'sort(string:)’

Instead, I have to write:

strings.map { sort(string: $0) }

Anybody else that would appreciate this possibility?
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

1 Like

I think this is [SR-504] Functions with default values cannot be called as parameters · Issue #43121 · apple/swift · GitHub and is something I run in to fairly frequently.

What would the next steps be to having this supported?

May be it is because the sort func takes 2 arguments and it can not conform to needed map argument.

This should be easier to implement now that unbound reference to a function foo is lowered to a closure { foo($0, $1, …) } by the type checker, instead of SILGen knowing how to emit this construct directly. The closure would take fewer arguments based on its contextual type, with the constructed call inside the closure passing these default arguments.

3 Likes

That's currently the issue, but what's being proposed is that Swift supports using the function in this context because it can be called with a single argument.

If the ease of implementation has improved since this was initially brought up then that's great!

Making this change is out of the realm of my knowledge, so I was hoping to learn what I can do to advocate for having this feature added.