Swift subtle difference between curried and higher order function - swift

NOTE: This question was asked while Swift 2.1 was the latest.
Given:
class IntWrapper {
var i: Int = 1
}
func add(inout m: Int, i: Int) {
m += i
}
And a higher order function
func apply() -> (inout i: Int) -> () -> () {
return { (inout i: Int) -> () -> () in
return {
add(&i, i: 1)
}
}
}
Application as so results in the member variable value never changing:
var intW = IntWrapper()
print(intW.i) // Prints '1'
apply()(i: &intW.i)()
print(intW.i) // Prints '1'
However, when changing the function to curried form
func apply()(inout i: Int)() -> () {
add(&i, i: 1)
}
Application results in the member variable value changing:
var intW = IntWrapper()
print(intW.i) // Prints '1'
apply()(i: &intW.i)()
print(intW.i) // Prints '2'
I'm curious to why this is. I always thought that curried syntax was sugar for the higher ordered form of the function, but apparently there are semantic differences.
Additionally this accepted proposal to remove curried syntax from swift seems to state this is merely sugar, and I'm concerned we're losing more than syntax by removing this from the language. Is there a way to get the same functionality from a higher order function?

Related

Why does use of closure shorthand-named variables has to be exhaustive in a singular return expression in Swift?

The following piece of code are erroneous in Swift.
func foo(closure: (Int, Int) -> Int) -> Int {
return closure(1, 2)
}
print(foo(closure: {$0}))
func foo(closure: (Int, Int) -> Int) -> Int {
return closure(1, 2)
}
print(foo(closure: {return $0}))
The error given by XCode playground is Cannot convert value of type '(Int, Int)' to closure result type 'Int'.
While the following pieces of code are completely fine.
func foo(closure: (Int, Int) -> Int) -> Int {
return closure(1, 2)
}
print(foo(closure: {$0 + $1}))
func foo(closure: (Int, Int) -> Int) -> Int {
return closure(1, 2)
}
print(foo(closure: {$1; return $0}))
func foo(closure: (Int, Int) -> Int) -> Int {
return closure(1, 2)
}
print(foo(closure: {a, b in a}))
It seems that in a situation where arguments to a closure are referred to by shorthand argument names, they must be used exhaustively if the the body of the closure only consists of the return expression. Why?
If you just use $0, the closure arguments are assumed to be a tuple instead of multiple variables $0, $1 etc. So you should be able to work around this by extracting the first value of that tuple:
print(foo(closure: {$0.0}))
Your "why" is like asking "why is an American football field 100 yards long?" It's because those are the rules. An anonymous function body that takes parameters must explicitly acknowledge all parameters. It can do this in any of three ways:
Represent them using $0, $1, ... notation.
Represent them using parameter names in an in line.
Explicitly discard them by using _ in an in line.
So, let's take a much simpler example than yours:
func f(_ ff:(Int)->(Void)) {}
As you can see, the function f takes one parameter, which is a function taking one parameter.
Well then, let's try handing some anonymous functions to f.
This is legal because we name the parameter in an in line:
f {
myParam in
}
And this is legal because we accept the parameter using $0 notation:
f {
$0
}
And this is legal because we explicitly throw away the parameter using _ in the in line:
f {
_ in
}
But this is not legal:
f {
1 // error: contextual type for closure argument list expects 1 argument,
// which cannot be implicitly ignored
}

Same name (and signature) closure & function: non-ambiguous for >0 arguments, giving closure precedence when calling

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.

“Functions are a first-class type” in swift?

the little knowledge , I have about first class function is that it supports passing functions as arguments and we can also return them as the values in another function ... I am very new in Swift programming language can anyone please elaborate it with an example.
A very simple example to demonstrate this behaviour:
func functionA() {
println("Hello by functionA")
}
func executeFunction(function: () -> ()) {
function()
}
executeFunction(functionA)
First-Class functions are functions that can return another functions.
For instance:
func operate( operand: String) -> ((Double, Double) -> Double)?{
func add(a: Double, b: Double) -> Double {
return a + b
}
func min(a: Double, b: Double) -> Double{
return a - b
}
func multi(a: Double, b: Double) -> Double {
return a * b
}
func div (a: Double, b: Double) -> Double{
return a / b
}
switch operand{
case "+":
return add
case "-":
return min
case "*":
return multi
case "/":
return div
default:
return nil
}
}
The function operate returns a function that takes two double as its arguments and returns one double.
The usage of this function is:
var function = operate("+")
print(" 3 + 4 = \(function!(3,4))")
function = operate("-")
print(" 3 - 4 = \(function!(3,4))")
function = operate("*")
print(" 3 * 4 = \(function!(3,4))")
function = operate("/")
print(" 3 / 4 = \(function!(3,4))")
When you don't care about the implementation of a function, using First-Class functions to return these functions become beneficials. Plus, sometimes, you are not responsible to develop (or not authorised ) of the functions like add, min. So someone would develop a First-Class function to you that returns these functions and it is your responsibility to continue ....
A function that returns a function while capturing a value from the lexical environment:
A function of an array of Comparables that returns a function of a test predicate that returns a function of a value that returns a Bool if the value is the extreme of the array under test. (Currying)
Any programming language is said to have first-class-functions, when functions are treated like normal variables. That means a function can be passed as parameter to any other function, can be returned by any function and also can be assigned to any variable.
i.e., (Referring apple's examples)
Passing function as parameter
func hasAnyMatches(list: [Int], condition: (Int) -> Bool) -> Bool {
for item in list {
if condition(item) {
return true
}
}
return false
}
Returning function
func makeIncrementer() -> ((Int) -> Int) {
func addOne(number: Int) -> Int {
return 1 + number
}
return addOne
}
Properties of First class function
A function is an instance of the Object type.
You can store the function in a variable.
You can pass the function as a parameter to
another function.
You can return the function from a function.
You can store them in data structures such as hash tables, lists, …
refer https://www.geeksforgeeks.org/first-class-functions-python/

Swift curried function behaves differently from expanded version

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.

Swift: why 'subscript(var digitIndex: Int) -> Int' is a valid function signature?

This piece of code comes from Swift documentation https://developer.apple.com/library/prerelease/mac/documentation/Swift/Conceptual/Swift_Programming_Language/Extensions.html
extension Int {
subscript(var digitIndex: Int) -> Int {
var decimalBase = 1
while digitIndex > 0 {
decimalBase *= 10
--digitIndex
}
return (self / decimalBase) % 10
}
}
Apparently var is a reserved word, so why it is legal to declare: subscript(var digitIndex: Int) -> Int?
If I change the signature to subscript(#digitIndex: Int) -> Int, I will get this compiler error:
My questions are:
1) why the signature is valid?
2) why my change causes an exception?
Declaring a function argument with var means that it can be modified, is not a constant. In your case, without using var, you had a constant argument but you attempted to decrement it. Thus the error.
Your two cases are:
func foo (x: int) { /* x is a constant, like `let x: int` */ }
func foo (var x: int) { /* x is not a constant */ }