Unknown Swift syntax - swift

I was just going through this blog from Mikeash and found the following declaration:
private let f: AnyObject -> Parameters -> Void
I am not clear what this syntax means. I tried looking into Swift Programming Guide but was not able to find any answer.
Can someone please put some light on it, possibly some reference?

See the Swift Programming Language Reference, Chapter Types, title Function Types:
The function types of a curried function are grouped from right to left. For instance, the function type Int -> Int -> Int is understood as Int -> (Int -> Int) — that is, a function that takes an Int and returns another function that takes and return an Int. Curried function are described in Curried Functions.
(I formatted the code parts)
See here for an explanation about curried functions.

Basically the type of f is a function which takes AnyObject as its parameter and returns a function which type is Parameters -> Void(takes Parameters as parameter and returns Void). Perhaps this code below will help you understand it.
func makeIncre(n:Int) -> Int -> Int {
func addN(a:Int) -> Int{
return a + n
}
return addN
}
let addOne = makeIncre(1)
let addTwo = makeIncre(2)
addOne(6) // 7
addTwo(6) // 8

Related

What is the syntax for a closure argument in swift

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

Swift beginner needs elaboration on syntax - Passing and Returning Functions

I'm venturing into Swift and languages that differ in syntax that I'm used to. The learning curve. I was wondering if someone could help explain this to me.
I understand the following. I understand that the method returns multiple values in a tuple.
func getGasPrices() -> (Double, Double, Double) {
return (3.59, 3.69, 3.79)
}
I don't understand this though. Is makeIncrementer returning an Int? Is it returning a returned Int? What's being passed into the addOne method and how? If addOne is only returning a single value, then how is makeIncrementer able to return two values? Further, how can the var increment (assigned as the makeIncrementer method) be made to take values when the function does not? I'm also not sure how this can be referred to as passing and returning a function, when no function is passed (isn't it nested?)
// Passing and returning functions
func makeIncrementer() -> (Int -> Int) {
func addOne(number: Int) -> Int {
return 1 + number
}
return addOne
}
var increment = makeIncrementer()
increment(7)
If this question has been answered already, forgive me, I couldn't find it! I'm a beginner in C# and Java so this syntax is completely strange to me.
Thank you in advance!
makeIncrementeris returning a value that is a function. So what is returned is a function that takes a single Integer parameter.
func addOne(number: Int) -> Int
This function takes an integer and returns another. Swift uses the syntax (Int -> Int) to represent this. This is different that returning an integer directly, you may also see instances of functions that take functions as parameters. This may look like the following:
func doSomething(completion: ()->())

Translating Swift Into English

I'm attempting to teach myself to code in Swift but I'm having a difficult time translating what I'm reading into something that resembles English. Here's an example:
func createAdder(numberToAdd: Int) -> (Int) -> Int
{
func adder(number: Int) -> Int
{
return numberToAdd + number
}
return adder
}
var addTwo = createAdder(2)
addTwo(4)
How do I read that first line of code and can you explain how this function is executed?
createAdder is a function that returns a function. The placement of the parentheses is a little off-putting - it makes more sense like this:
func createAdder(numberToAdd: Int) -> (Int -> Int)
So it returns a function of type Int -> Int. What does that mean? Take a look at this function:
func addTwo(n: Int) -> Int {
return n + 2
}
That function takes an integer - n - and returns another integer. So the type of the function is:
Int -> Int
In this case, this function just adds two to whatever it was given. But say you wanted to generalise (it doesn't make much sense in this contrived example, but this kind of thing is very powerful in other scenarios). Say you wanted to have a bunch of functions, each of them adding a number to a number they were given. To do that, you'd need to write something like what you've written in your example:
func createAdder(numberToAdd: Int) -> (Int) -> Int
{
func adder(number: Int) -> Int
{
return numberToAdd + number
}
return adder
}
The createAdder function takes a number, and then defines a new function - adder - which it returns.
The final bit that might be confusing is the line
var addTwo = createAdder(2)
Usually, you define functions with the word func. However, that's just syntax. Functions are variables just like every other type in Swift, and they can be treated as such. That's why you're able to return a function, and that's why you're able to assign it using var.
So what does it do? Well, if you call createAdder(2), what you get back is equivalent to
func addTwo(n: Int) -> Int {
return n + 2
}
If you did something like:
var addThree = createAdder(3)
It would be equivalent to:
func addThree(n: Int) -> Int {
return n + 3
}
And in both cases, you'd use them just like normal functions:
addThree(1) // returns 4
So I said the example was a little contrived - and it is - so where would this kind of thing be useful? In general, functions that either take or return functions are called "higher-order" functions. They're massively useful, and if you go down the functional programming route they can get very powerful and a bit philosophical pretty quickly. Keeping it grounded, the first place most people come across them in Swift is with the function .map(). map() is a higher-order function - it takes a function as its parameter. However, it also takes something else - in this example, it's going to be an array. What it does is apply the function it's given to every element of the array. So, let's use the createAdder() to give us a function that adds 1 to a number:
let addOne = createAdder(1)
Right, then let's get an array of other numbers:
let nums = [1, 2, 3, 4]
Then, let's put it all together with map:
let mapped = nums.map(addOne) // [2, 3, 4, 5]
As you can see, that's a pretty powerful way to process and manage arrays. There's a whole host of functions like this - filter(), flatMap(), reduce() - and they all rely on this concept.
It reads: declare a function named "createAdder" that takes an Int as an argument, this function returns a function which itself takes an Int as an argument; and this function itself, what is returned from "createAdder", returns an Int.
-> (Int) -> Int
means "returns a function -taking an Int- which will return an Int".
The first line of code reads:
A function createAdder that takes as an argument a numberToAdd of type Integer and returns a function that receives an Integer as an argument and returns an Integer. In this case, the function that is returned is the adder function that is created within the createAdder.

Values accepted in a tuple in swift

I am a completely newbie in swift and in functional Programming.
My silly question is the following:
Can a tuple return a set of functions?
Is it a function like that accepted?
someFunction(param: Bool) -> ((Int) -> Int, (Float) ->Float) -> Double)
Thanks for your reply
You can have a tuple of any type, and functions are types, so you can have tuples of functions.
For example, here’s a 2-tuple of two functions, one that takes two Ints and returns an Int, and one that takes two Doubles and returns a Double:
// a 2-tuple of the addition functions for ints and doubles
let tupleOfFunctions: ((Int,Int)->Int, (Double,Double)->Double) = (+,+)
When you say, “can a tuple return a set of functions?”, I’m guessing you mean, “can a function return a tuple of functions?”. And the answer is also yes:
func returnTwoFunctions(param: Bool) -> ((Int,Int)->Int, (Double,Double)->Double) {
// use the argument to drive whether to return some addition
// or some subtraction functions
return param ? (+,+) : (-,-)
}
Your example, though, is a bit scrambled – if you added a func keyword to the front, it’d be a function declaration, but you’ve got mismatched parentheses. What it looks most like is a function (someFunction) that takes one boolean argument, and returns a function that itself takes two functions and returns a double:
func someFunction(param: Bool) -> (Int->Int, Float->Float) -> Double {
let i = param ? 1 : 2
// this declares and returns a function that itself takes two functions,
// and applies them to pre-determined number
return { f, g in Double(g(Float(f(i)))) }
}
// h is now a function that takes two functions and returns a double
let h = someFunction(false)
// ~ and + are two unary functions that operate on ints and floats
h(~,+) // returns -3.0 (which is +(~2) )
Whether this is what you were intending, and whether you have a use-case for this kind of function, I’m not sure...

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.