Swift 3 closure overload resolution - swift

I'm confused by function overload resolution with closures in Swift 3.
For example, in the code:
func f<T>(_ a: T) {
print("Wide")
}
func f(_ a: (Int)->(Int)) {
print("Narrow")
}
f({(a: Int) -> Int in return a + 1})
I expect Narrow, not Wide, to be printed to the console. Can anyone explain why the more specific overload gets chosen for non-closure arguments but not for closures or is this a compiler bug?
Swift 2 exhibited the expected behavior.

This is probably due to the change in the default "escaping" behaviour for closure parameters.
If you change the specific function to:
func f(_ a:#escaping (Int)->Int)
{
print("Narrow")
}
it will print "Narrow" as expected (this is the same change that you probably had to make in several other places that were more obvious)

Related

Why use generics when you can just use types [duplicate]

This question already has answers here:
Generics type constraint vs inheritance
(1 answer)
What is the in-practice difference between generic and protocol-typed function parameters?
(2 answers)
Closed 5 years ago.
Let's say I have a protocol:
protocol Amazing {
func doAmazingStuff()
}
And then I have a function that takes that type to do things with it:
func doMoreCoolThings<T: Amazing>(awesome: T) -> T { ... }
What's the difference between that and just doing something like this?
func doMoreCoolThings(awesome: Amazing) -> Amazing { ... }
My question here is why do we even bother using generics when we can just put in the type like that?
UPDATE
So I can see the point in using genetics instead of the:
func doMoreCoolThings(awesome: Amazing) -> Amazing { ... }
However is there really any use to using that function or would it always be better to use generics?
This is just one benefit that I can immediately think of. I'm sure there are lots more.
Let's say We have two classes A and B that both conform to Amazing.
If we pass A() into this function:
func doMoreCoolThings<T: Amazing>(awesome: T) -> T { ... }
like this:
let val = doMoreCoolThings(awesome: A())
We are sure that val is of type A and the compiler knows that too. This means we can access A's members using val.
On the other hand if we pass A() into this function:
func doMoreCoolThings(awesome: Amazing) -> Amazing { ... }
like this:
let val = doMoreCoolThings(awesome: A())
val's compile time type is Amazing. The compiler does not know what type of Amazing it is. Is it A or is it B or is it something else? The compiler doesn't know. You will have to cast the result to A in order to access its members.
let a = val as! A
The cast is also not guaranteed to succeed.
If you put these casts everywhere your code will soon become very messy.
Your question contains the false premise that
func doMoreCoolThings(awesome: Amazing) -> Amazing { ... }
is equivalent to:
func doMoreCoolThings<T: Amazing>(awesome: T) -> T { ... }
This is not at all true. Say I have these conforming types to work with:
struct AmazingApple: Amazing {
func doAmazingStuff() { print("I'm an apple who talks!") }
}
struct AmazingBanana: Amazing {
func doAmazingStuff() { print("I'm a banana who talks!") }
}
Look at what the first piece of code let's me do:
func doMoreCoolThings(awesome: Amazing) -> Amazing {
return AmazingBanana()
}
let input = AmazingApple()
let result = doMoreCoolThings(awesome: input)
print("The input is of type \(type(of: input))")
print("The return is of type: \(type(of: result))")
The parameter type and return type are different, even though they're both subtypes of Amazing.
On the other hand, looks what happens when you try to do the same with the generic variant:
Generics are used to express relationships between types.
The non-generic code expresses:
"Let doMoreCoolThings(awesome:) be a function that takes some value whose type is a subtype of Awesome, and returns a value whose type is a subtype of Awesome."
The generic code expresses:
"Let doMoreCoolThings(awesome:) be a function that takes some value whose type is a subtype of some type, call it T, and returns a value those type is a subtype of T, where T itself is a subtype of Amazing."
Notice that the second quote expresses the requirement for the parameter and the return to be of the same type. It's not sufficient to just both have them be subtypes of Amazing.

How to use a variadic closure in swift?

Is there a proper way to use a variadic parameter list in a closure in Swift?
In swift I notice that I can declare a function which takes a variadic argument list like so
protocol NumberType: Comparable, IntegerLiteralConvertible, IntegerArithmeticType {}
extension Int: NumberType {}
extension SequenceType where Generator.Element: NumberType {
func satisfy(closure:(args: Generator.Element...) -> ()) {
// Do something
closure(args: 1, 2, 3)
}
}
Which builds just fine. When I try to use the function:
[1, 2].satisfy { (args) in
print (args)
}
Xcode manages to auto complete as I would expect, but immediately upon closing the parenthesis after args, all syntax highlighting in Xcode disappears and I see a message "Command failed due to signal: Segmentation Fault: 11", which appears to just mean Xcode is super confused.
For context, I had planned on seeing if Swift could write a function which could return answers based on a variable number of parameters (mapping to the number of for loops required to get a brute force answer). It would be a simple way of testing the answer to a question such as "Given an array of Ints, find all combinations which satisfy the equation a^3 + b^3 = c^3 + d^3" with
let answer = array.satisfy ({ return pow($0, 3) + pow($1, 3) == pow($2, 3) + pow($3, 3) })
against a more optimal solution.
"Return all the 2s" would just be
let answer = array.satisfy ({ return $0 == 2 })
A single for loop
Compiler limitation/bug with argument type inference for single-expression closures
I believe the source of this is a current limitation (/bug) in the compiler w.r.t. inferring the argument types in single-line closures using variadic parameters, see e.g. the following Q&A
Why can't I use .reduce() in a one-liner Swift closure with a variadic, anonymous argument?
A similar issue was also present for inout arguments in Swift 2.1 (but no longer in 2.2), as is explained in the following thread
Inline if statement mutating inout parameter in a void return closure, weird error (Error: type 'Int1' does not conform to protocol 'BooleanType')
Looking at thread 1. as well as attempting to find the described bug flagged in Swift JIRA, however, it seems as if the OP of thread 1. never filed a bug for this, after all. Possibly I just haven't found an existing bug report, but if none exists, one should possibly be filed.
Current workarounds
Possible workarounds, until the compiler's closure argument type inference catches up, are
Extend the closure beyond single-line body
// ...
[1, 2].satisfy { (args) in
() // dummy
print (args) // [1, 2, 3]
}
Or, explicitly include type of args, e.g.
[1, 2].satisfy { (args: Int...) in
print (args) // [1, 2, 3]
}
Note that Generator.Element resolves to Int in this example above.
Current status for Swift 3.0-dev
As mentioned briefly above, curiously enough, this bug
inout: is apparently no longer present in Swift 2.2 or Swift 3.0-dev for inout arguments, w.r.t. the issues described in Q&A 2. as linked to above
it was possibly fixed as bug [SR-7] was resolved (-> Swift 2.2)
however, seems to be regression 2.2->3.0-dev, w.r.t. type inference for inout arguments, as reported in bug report [SR-892]. E.g. the following snippet works in Swift 2.2, but not in 3.0-dev (minimally modified snipper from bug report [SR-7])
func f(inout a: Int) {}
let g = { x in f(&x) } // OK 2.2, crashes 3.0-dev
variadic: is still present in Swift 2.2 as well as Swift 3.0-dev for variadic arguments (this thread and Q&A 1. above).
a more condensed example of the bug:
let a: (Int...) -> () = { (args) in print(args) } // bug: crashes
let b: (Int...) -> () = { (args: Int...) in print(args) } // explicitly state argument type, OK
let c: (Int...) -> () = { (args) in (); print(args) } // extend to more than single line closure, OK
(For Swift 3.0-dev, tested using the IBM Swift Sandbox running Swift 3.0-dev.

Are there any possible explicit uses of instances (values) of empty tuples (), i.e., of instances of typealias 'Void'?

Question:
Are there any possible explicit uses for the empty tuple (), as a value (and not as a type) in Swift 2.x?
I know that these empty tuples can be used in the standard sense to define void functions. When I mistakenly defined a variable with a empty tuple value var a = () (of type ()), I started wondering if these empty tuple values can be used in some context. Does anyone know of such an application?
Example: possible application with array and optionals?
As an example, we can create an optional array of empty tuples that, naturally, can only hold either nil or ():
/* Optionals */
var foo: ()? = ()
print(foo.dynamicType) // Optional<()>
var arr : [()?] = [foo]
for i in 2...8 {
if i%2 == 0 {
arr.append(nil)
}
else {
arr.append(foo)
}
}
print(arr) // [Optional(()), nil, Optional(()), ... ]
With the small memory footprint of empty tuple, this could seem neat for micro-memory-management for a "boolean nil/not nil", but since type Bool have the same small footprint, I can't really see any direct use here, even in the (unlike) scenario that we really need to go bit-low optimization on our operations.
Perhaps I'm just chasing my own tail with some narrow unusable applications, but anyway: are there any possible explicit uses for these void () beings (as instances, not types)?
There are lots of places that () can be useful when playing around with "CS" problems, which often have the form "implement X using Y even though you really already have X." So for instance, I might say, implement Set using Dictionary. Well, a Dictionary is a Key/Value pair. What should the type of the Value be? I've actually seen this done in languages that have Dictionaries but not Sets, and people often use 1 or true as the value. But that's not really what you mean. That opens up ambiguity. What if the value is false? Is it in the set or not? The right way to implement Set in terms of Dictionary is as [Key: ()], and then you wind up with lines of code like:
set[key] = ()
There are other, equivalent versions, like your Optional<()>. I could also implement integers as [()] or Set<()>. It's a bit silly, but I've done things like that to explore number theory before.
That said, these are all almost intentionally impractical solutions. How about a practical one? Those usually show up when in generic programming. For example, imagine a function with this kind of form:
func doThingAndReturn<T>(retval: T, f: () -> Void) -> T {
f()
return retval
}
This isn't as silly as it sounds. Something along these lines could easily show up in a Command pattern. But what if there's no retval; I don't care about the return? Well, that's fine, just pass a () value.
func doThing(f: () -> Void) {
doThingAndReturn((), f: f)
}
Similarly, you might want a function like zipMap:
func zipMap<T, U>(funcs: [(T) -> U], vals: [T]) -> [U] {
return zip(funcs, vals).map { $0($1) }
}
This applies a series of functions that take T to values of type T. We could use that even if T happens to (), but we'd have to generate a bunch of () values to make that work. For example:
func gen<T>(funcs: [() -> T]) -> [T] {
return zipMap(funcs, vals: Array(count: funcs.count, repeatedValue: ()))
}
I wouldn't expect this to come up very often in Swift because Swift is mostly an imperative language and hides its Void in almost all cases. But you really do see things like this show up in functional languages like Scala when they bridge over into imperative programming.
Suppose you have two functions overloading the same name:
func foo()
func foo() -> Int
The first doesn't return anything, the second returns some kind of value. Attempting to call either of these will in most cases get you a compiler error about ambiguity.
foo()
let a = foo()
You'd think that the compiler would know that the first call unambiguously refers to the first function, because it assumes no return value. But in actuality, the return type of a function with no declared return type is Void, or (). So the first call is actually more like this:
let _ = foo()
And absent a type annotation for the discarded lvalue, the compiler can't infer which foo to call. You can use explicit type annotations to disambiguate:
let b: Void = foo()
let c: Int = foo()
Okay, it's not a very great or common use case for Void, because it's a situation you'd tend to avoid getting into in the first place. But you asked for a use... and it is a use of () as a value and not just a type, because you can retrieve it from b after assignment (for all the good that does you).
Just beware, when you look deeply into the Void, the Void also looks into you. Or something like that.

Type '()' does not conform to protocol 'IntegerLiteralConvertible'

func makeIncrementer() -> (Int -> Int) {
func addOne(number: Int) -> Int {
return 1 + number
}
return addOne
}
above is a simple example code for Function as first-class type in Swift
now, when i call the call the function in the following way:
var increment = makeIncrementer()
increment(7)
it perfectly gives the answer
But out of curiosity i tried the direct approach i.e.
makeIncrementer(7) // error
and it gives an error
why is it so???
P.S. I am a beginner in Swift
The call makeIncrementer() returns the function, so to call it you pass the parameter in a second set of parentheses:
makeIncrementer()(7)
The error message is given because Swift interprets makeIncrementer(7) as 7 being passed to makeIncrementer which doesn't take any parameters. Hopefully Swift error messages are made more friendly in the future. While technically correct, the error message given leads to a lot of confusion.

Accessing number of parameters in a closure in Swift

Suppose I have a function:
func test(closure: (closureArgs: Double ...) -> Double){
//some logic
}
Then later, I call it with:
test({$0 + $1 + $2 + $3})
Is it possible to get the number of closureArgs provided within test? The goal would be to do overloading. For example, test could include some code like:
func test(closure: (closureArgs: Double ...) -> Double){
//somehow get access to number of arguments in closureArgs within the closure that was passed.
}
To clarify - I mean I need to access closureArgs's length INSIDE test but OUTSIDE closure
Is it possible to get the number of closureArgs provided within test?
The Short Answer
No.
Slightly Longer Answer
No, it is not. Here's why:
The function is taking a closure as it's argument that by definition takes a variadic number of arguments. There's no possible way for someone calling the function to designate how many arguments the closure should take ahead of time. For example, if I were to call your function, it might look like this:
test() { (closureArgs: Double...) -> Double in
var n: Double = 0
for i in closureArgs {
n += i
}
return n
}
As you'll notice, I don't define the number of arguments anywhere because the number of arguments is only specified when the closure is called. Then the number can be determined inside, or possibly returned.
Basically, the closure is called within test, so only you the caller know how many arguments it takes. Anyone consuming this function has no control over it.
The only way I can think of is to have the closure return a tuple that contains the number of arguments and a function that gives the answer, like this:
func test(c: (Double...) -> (Int, (Double...) -> Double)) {
let (argCount, function): (Int, (Double...) -> Double) = { c($0) }()
switch argCount {
// do something with function here
}
}
func sum(a: Double...) -> (Int, ((Double...) -> Double)) {
return (a.count, { reduce(a, 0, +) })
}
Something like that might work, but I'm not in a place where I can test it.
Edit: I'm trying to test this now, and it's close, but it doesn't work yet...
Edit: Okay, this works, but maybe not in the way that you want...
func test(c: (Int, Double)) {
let (argCount, result) = c
switch argCount {
case 2:
println("2 args were passed")
println("The result was \(result)")
default:
println("nothing")
}
}
func sum(a: Double...) -> (Int, Double) {
return (a.count, reduce(a, 0, +))
}
Now test(sum(2, 4)) will print that the number of arguments was 2 and the result was 6.
The thing is, when you are passing a closure that already has arguments supplied (and it needs arguments to know how to calculate the count) then you're closure function already evaluates to a result. So have the closure return the number of arguments that it used to calculate the result along with the result. Then in test you can work with both the number of arguments and the result.
I don't know...it's hard to know exactly what you are after because I'm not sure what kind of logic you need to implement once you know the number of arguments...
Edit: Sorry I keep going on and on, but it seems like you know how many arguments are going to be included when you call test, right? I mean, in your example you supplied 4 arguments:
test({$0 + $1 + $2 + $3})
(Although, you really need to rewrite that as:
test({ return $0[0] + $0[1] + $0[2] + $0[3] })
...cuz remember, variadic parameters are passed as an array...)
So if you know how many arguments are going to be in the closure when you pass it to test, just include the number of arguments as a parameter in test, like this:
func test(count: Int, closure: (Double...) -> Double) {
switch count {
case 1:
// do what you want if there is only one argument
case 2:
// do what you want if there are two arguments...etc.
}
}
Now when you call test, you just pass the number of arguments as an Int:
test(4, { return $0[0] + $0[1] + $0[2] + $0[3] })
In other words, you always know how many arguments you are passing to the closure when you pass it. If you want test to know, just include that as a parameter.
The answer goes back to how Swift passes arguments to varargs functions, which is as an array. Generally speaking, the function definition:
func takesVarArgs(args: Double...)
Is syntactic sugar, providing for simpler invocation, for the declaration:
func takesVarArgs(args:[Double])
So, in your case, your closure will be invoked as:
func test(closure: (closureArgs:[Double]) -> Double)) -> Double
Then, within your closure you could get the number of arguments with:
closureArgs.count