Running the following in Xcode 7.2(7C68) Playground. OS X 10.10.5
Can you tell me why the following is not printing "Example"? It just prints "()"
As you can see in the comments it works in 7.1.
func printThis(xprint : Void -> Void) {
xprint()
}
printThis({ print("Example") })
Make sure to differ between output in the console and the value of an expression. Also note that Void is just a typealias for the empty tuple, (). Functions with no return type returns, by default, the value of an empty tuple, ().
func printThis(xprint : Void -> Void) {
xprint()
}
let a = printThis({ print("Example") })
/* the _value_ of this expression is ()
the side effect of this expression is that "Example" is
printed to the console output */
print(a) // prints '()'
The () value has nothing to do with your ()->() closure, but with the fact that printThis(..) is a void function, in the sense that it implicitly returns value () of type () (empty tuple).
As an example, consider the following case with a side effect of printing "Example" to the console, but with a integer value of 1.
func printThat(xprint : Void -> Void) -> Int {
xprint()
return 1
}
let b = printThat({ print("Example") }) // side effect: prints "Example"
print(b) // 1
What you see in the right side of your playground is the value of variables and expressions. Refer to the bottom to see console output.
Finally, regarding "void" functions, note that there is no difference between these two function signatures:
func myFunc(myVar: String) // implicitly returns _value_ '()' of _type_ ()
func myFunc(myVar: String) -> ()
Curiously enough, you can have an optional empty tuple type, so the function below differs from the two above:
func myFunc(myVar: String) -> ()? {
print(myVar)
return nil
}
var c = myFunc("Hello") /* side effect: prints 'Hello'
value: nil
type of c: ()? */
For details on the empty tuple () as type as well as value, see e.g.
https://stackoverflow.com/revisions/34561452/3
Related
I know the meaning of (void) in objective c but I want to know what is the meaning of this code:
(Void) -> (Void)
In Swift.
() -> () just means Void -> Void - a closure that accepts no parameters and has no return value.
In Swift, Void is an typealias for an empty tuple, ().
typealias Void = ()
The empty tuple type.
This is the default return type of functions for which no explicit return type is specified.
For an example
let what1: Void->Void = {}
or
let what2: Int->Int = { i in return i }
are both valid expressions with different types. So print has the type ()->() (aka Void->Void). Strictly speaking, printThat has type (() -> ()) -> () (aka (Void->Void)->Void
Void function doesn't has a lot of sense as Int function etc ... Every function in Swift has a type, consisting of the function’s parameter types and return type.
Finally, regarding "void" functions, note that there is no difference between these two function signatures:
func myFunc(myVar: String) // implicitly returns _value_ '()' of _type_ ()
func myFunc(myVar: String) -> ()
Curiously enough, you can have an optional empty tuple type, so the function below differs from the two above:
func myFunc(myVar: String) -> ()? {
print(myVar)
return nil
}
var c = myFunc("Hello") /* side effect: prints 'Hello'
value: nil
type of c: ()? */
Same as Swift mean.No parameter no return value.
Precedence rules for same name and signature function & closure
When defining a closure and a function with same name (say, foo) and signature, it seems as if the closure takes precedence when calling said (seemingly ambiguous) foo.
// Int -> () function
func foo(num: Int) { print("function \(num)")}
// Int -> () closure
let foo: (Int) -> () = { print("closure \($0)")}
/* or...
let foo = { (num: Int) in print("closure \(num)")} */
foo(1) // closure 1
If I option-click the two declarations, they point at each other under the label Related declarations, differing in how they are referred to as:
Declaration: func foo(num: Int)
Related Declarations: foo
...
Declaration: let foo: (Int) -> ()
Related Declarations: foo(_:)
If we attempt to define the same double-foo definitions for a zero-argument function & closure, we get a compile time error prompting invalid redeclaration
// () -> () function
func foo() { print("function")}
// () -> () closure
let foo: () -> () = { print("closure")}
/* or...
let foo = { () in print("closure")} */
/* error: invalid redeclaration of 'foo' */
Question: Why is it that the first case above is considered non-ambiguous, and why does the closure take precedence over the function when calling foo(..) (i.e., in the overload resolution of foo(...)?
I haven't been able to find any official docs (or existing SO thread) explaining this.
Tested for Swift 2.2/Xcode 7.3 and Swift 3.0-dev/IBM Sandbox (with function signature modified to func foo(_ num: Int) { ... }).
In Swift, you cannot name a variable and a function or closure the same thing if no parameters are passed. Although we call them in different ways (foo for a variable and foo() for a function. we will get an invalid redeclaration of foo. The compiler treats the variable as if it has no parameters like the function does. Consider some of these cases:
class X {
var value : Int = 0
func value() -> Int { return 1 } // Invalid redeclaration of 'value()'
}
let x = X()
What is x.value in this case? Is it Int or is it () -> Int? It's legal and useful to treat the methods of classes as if they were closures.
What if we're even more tricky, and do this:
class X {
let value: () -> Int = { 2 }
func value() -> Int { return 1 } // Invalid redeclaration of 'value()'
}
let x = X()
let v = x.value() // ????
Should Swift use the property value and then call it? Or should it call the method value()? Closures are completely legal as properties.
However, using parameters, you can name a function and a variable/Closure the same thing, although I would advise you not to. In this case you should try to name the variable and the function something that describes what they are and/or what they do to make your code more readable by others. I would suggest naming the variable something like
class X {
// Int -> () function
func foo(number num: Int) { print("function \(num)")}
// Int -> () closure
let foo: (Int) -> () = { print("closure \($0)")}
}
because by naming the function it will allow user to know exactly which function your are calling when your method and variable names are same. user can know what parameter is for they are passing. by naming when you call the methods like below.
let x = X()
x.foo(number: 2)
x.foo(3)
and you CMD + click it will point you to the exact method or variable/closure you have written for.
consider previous example:
class X {
// Int -> () function
func foo(number num: Int) { print("function \(num)")}
// Int -> () closure
let foo: (Int) -> () = { print("closure \($0)")}
}
let x = X()
x.foo(2) // x.foo(num: Int)
x.foo(3) // x.foo
Despite you called the correct method or closure. by cmd + click it will point you to the closure only.
I am bit confused on declaring parameter and return type in Swift.
does these parameter and return type have the same meaning? What is the use of those parentheses ()?
func myFunction() -> (()-> Int)
func myFunction() -> (Void-> Int)
func myFunction() -> Void-> Int
First... () and Void are the same thing you have two different ways of writing the same thing.
Second... The -> is right associative. So using parens as you have in your examples are meaningless, much like they are with an expression such as a + (b * c). That expression is identical to a + b * c.
Basically, the three examples in your question all define a function that takes no parameters and returns a closure that takes no parameters and returns an Int.
Some more examples to help:
func myFuncA() -> () -> Int -> String {
return { () -> Int -> String in return { (i: Int) -> String in String(i) } }
}
func myFuncB() -> () -> (Int -> String) {
return { () -> Int -> String in return { (i: Int) -> String in String(i) } }
}
func myFuncC() -> (() -> Int) -> String {
return { (f: () -> Int) in String(f()) }
}
In the above, myFuncA is identical to myFuncB, and they are both different than myFuncC.
myFuncA (and B) takes no parameters, and returns a closure. The closure it returns takes no parameters and returns another closure. This second closure takes an Int and returns a String.
myFuncC takes no parameters and returns a closure. The closure it returns takes a closure as a parameter and returns a String. The second closure takes no parameters and returns an Int.
Hopefully, writing it in Prose hasn't made it even more confusing.
In Swift headers, the isSeparator: argument accepts a closure
public func split(maxSplit: Int = default, allowEmptySlices: Bool = default, #noescape isSeparator: (Self.Generator.Element) throws -> Bool) rethrows -> [Self.SubSequence]
But in the documentation, it lists closure syntax differently
{ (parameters) -> return type in
statements
}
How are you supposed to know that (Self.Generator.Element) throws -> Bool rethrows refers to a closure / requires a closure? Are there other ways that the headers/docs might list argument as meaning a closure?
The "thing" giving away that this is a closure is the ->. The full type is
(Self.Generator.Element) throws -> Bool
It means that the closure takes a variable of type Self.Generator.Element and has to return a Bool upon some calculation based on the input. It may additionally throw some error while doing so - that is what the throws is for.
What you then write
{ (parameters) -> return type in
statements
}
would be an actual implementation, a value of some generic closure type.
The type of a closure is for example (someInt:Int, someDouble:Double) -> String:
var a : ((someInt:Int, someDouble:Double) -> String)
Once again the thing giving away that a is actually a closure is the -> in the type declaration.
Then you assign something to a via some code snippet following your second code block:
a = { (integer, floating) -> String in
return "\(integer) \(floating)"
}
You can tell by the argument's type. Everything in Swift has a type, including functions and closures.
For example, this function...
func add(a: Int, to b: Int) -> Int { return a + b }
...has type (Int, Int) -> Int. (It takes two Ints as parameters, and returns an Int.)
And this closure...
let identity: Int -> Int = { $0 }
...has type Int -> Int.
Every function and closure has a type, and in the type signature there is always a -> that separates the parameters from the return value. So anytime you see a parameter (like isSeparator) that has a -> in it, you know that the parameter expects a closure.
the isSeparator definition means (Self.Generator.Element) throws -> Bool that you will be given an Element and you should return a Bool. When you will call split, you then can do the following :
[1,2,3].split(…, isSeparator : { element -> Bool in
return false
})
This is a pure silly example but that illustrates the second part of your question
I have a curried function in Swift:
func counter(var val: Int)() -> () {
val++
println(val)
}
According to this answer it should be equivalent to this:
func counter(var val: Int) -> (() -> ()) {
func curryFunc() {
val++
println(val)
}
return curryFunc
}
However, when I run the following code:
let x = counter(3)
x()
x()
with the first one, I get 4, 4; whereas with the second one, I get 4, 5.
I am using the release Xcode 6.0.1.
The difference is that in the first version the body of the curried function is a normal function implementation, whereas in the 2nd case there's a closure. As stated in the documentation:
Closures can capture and store references to any constants and variables from the context in which they are defined.
In your case, val is captured, and retained among consecutive calls.
Addendum - if you want to have your 2nd function to behave like the curried one, you should store the parameter in a variable declared inside the function body:
func counter(val: Int) -> (() -> ()) {
func curryFunc() {
var unretainedVal = val
unretainedVal++
println(unretainedVal)
}
return curryFunc
}
The captured value val doesn't change, so the function keeps a reference to its original value.