# Functions

### Declarations

Functions in Swift are nothing special. We start them with the keyword `func` followed by the function name and then the arguments enclosed in parenthesis: `func (args)`.&#x20;

Parameters should be formatted (name: type). When arguments are assigned to parameters, they become constants. We can get around this within the function by assigning the parameter to another variable–just be conscious of this if you're getting mutating-constant errors.

Finally, if there is a return type, you should put `-> <return type>` after the parameters. If there is no return type, you either leave out the arrow or write `void` for the return type–this will be more important when we talk about closures, otherwise, you can basically forget about `Void.`

`func <name>(parameter1: type1, ... parameterN: typeN) -> <return type> { body }`

Alright let's start with some basic functions!

First, a function that returns the string "Hello World!":

```swift
func helloWorld() -> String {
    return "Hello World"
}
// helloWorld: () -> String
```

Fun little side note, you have a one-line function, you can omit the `return` statement because the compiler will just assume that the expression is being returned.

```swift
func helloWorld() -> String {
    "Hello World"
}
// helloWorld: () -> String
```

Okay, let's spice things up by adding some arguments. We'll add a function that prints out someone's name (given their name).

```swift
func greeting(name: String) {
    print("Hello \(name), have a nice day :)")
    // We can use \() to insert information into string
    // It's equivalent to doing "Hello " + name + ", have a nice day :)"
    // This works for all data types.
}
// greeting: (name: String) -> Void
```

### Calling Functions

Calling a function is pretty easy. All you have to do is `<function name>(parameter: value...)`

Let's call our previous functions

```
helloWorld()
// "Hello World": String
greeting(name: "Noah")
// "Hello Noah, have a nice day :)"
// Thank you I will :)
```

### Anonymous Arguments

You may have noticed that Swift is different than some other languages because you **need** to include the parameter name. We can change this, per parameter, by making them anonymous. You do this by adding a wildcard (`_`)  in front of the parameter name in the function header:

```swift
func iDontNeedLabels(_ no: String, _ labels: String, _ here: String) -> String {
    no + " " + labels + " " + here
}
//iDontNeedLabels : (_: String, _: String, _:String) -> String
iDontNeedLabels("time", "to", "nap")
// "time to nap" : String
```

### Functions as Values

Swift functions are higher order meaning that they can be passed and stored as values! You may have noticed the type annotations in the previous code samples... And to store a function in a variable you're gonna need to understand their types... time to get comfortable with them! Side note, the notation I use above is actually slightly different because it acknowledges parameter names.

These types are not hard. For the arguments we write a tuple of the argument types. This is then followed by an arrow `->` and then the return type (you need void here if there is no return type). For example, `helloWorld`, which is `helloWorld() -> String` can be stored in a variable like

`let aGreeting: () -> String = helloWorld`&#x20;

Similarly, greeting, which was `greeting(name: String) -> Void` can be stored like:

`let anotherGreeting: (String) -> Void = greeting`

Now that we have these functions in variables, we can call them by enclosing their arguments in parenthesis, separated by commas and ignoring parameter names:

```swift
aGreeting()
// "Hello World" : String
anotherGreeting("Aaron")
// "Hello Aaron, have a nice day :)"
```

### Exception Handling

If a function has a possibility of raising an exception directly (not an assertion error, fatal error, or runtime error) we must state this in the function, so that callers can handle the error. To do this, we write `throws` before the arrow pointing to the return type: `func someFunction() throws -> Void`.&#x20;

If a function takes a function as an argument that has the potential of throwing an error, this new function must deal with it. If we are just going to throw the error again, we use the `rethrows` tag instead.

`func someFunction(anotherFunctionThatThrows: () throws -> Void) rethrows -> Void`

This is very rare, so you don't really need to worry about it.

### Closures

We can also create functions directly as anonymous functions. You will need to store it somewhere, and if it is going into a variable, you will need an explicit type. If it is directly into a function as an argument, your type will already be specified.&#x20;

Arguments are given names by default–they are named `$` + whatever their index is in the arguments, so the first is `$0`, the second is `$1` and so on. But these are not pretty, so sometimes you may choose to rename them. To do this, at the beginning of your closure write your names separated by commas followed by the keyword `in`. It's like your saying "these variables are in the rest of the code".

```swift
// returns if [$0] < [$1]
let lessThan: (Int, Int) -> Bool {
    $0 < $1
}

// returns if [$0] < [$1]
let namedLessThan(Int, Int) -> Bool { left, right in
    left < right
}
```

### Escaping

This is an advanced concept (you also don't need to understand it until the end of the course).&#x20;

If a function (the main function) takes a function (the inner function) as an argument, and if the inner function is not done resolving by the time the main function returns, then we have a problem. The inner function is being stored in the main function, so if we erase the main function (because it is done being executed), then we cannot execute the inner function because it will be gone! To fix this, we change the type declaration of the inner function to be tagged `@escaping`. This will handle this problem for us. I think the compiler will tell you when you mess this up, but I won't guarantee that, so if you're playing with higher-order functions keep it in mind.

```swift
func mainFunction(innerFunction: @escaping () -> Void) {}
```

### Partial Application

Partial application is a method of creating new functions by applying some arguments to a previous function. Partial application in Swift is somewhat manufactured–the experience is not as wonderful, magical, amazing... etc. as in OCaml. In many functional langauges, you can just apply a few arguments and it will automatically apply it for you. In Swift, we have to be more intentional. To curry, in Swift, you have to write a new function that applies it for you. Let me show you what I mean. Let's say we have some function `curry` of type`(Int, Double, String) -> String`. Let's say we want to do partial application with an `Int` of 3 and a `String` of "Martha". We create a new function that takes in the remaining arguments, applies them, but also applies 3 and "Martha".

```swift
let curriedFunction: (String) -> String = { text in
    return curry(3, text, "Martha")
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ios-course.cornellappdev.com/resources/swift-foundations/functions.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
