Alex headshot

AlBlue’s Blog

Macs, Modularity and More

Swift - functions

2014 Swift Mac

In this episode of the Swift introduction series we’ll be looking at functions in Swift.

Defining functions

Swift is an object oriented language that builds upon Objective-C and C++, but it also blends functions and functional programming techniques. It’s a little bit like Scala, except that Swift will become massively successful.

Swift functions can be created and assigned to variables, as they can in JavaScript. Unlike JavaScript, Swift uses the func keyword to introduce a function.

```sh Defining and calling functions $ swift Welcome to Swift! Type :help for assistance. 1> func helloWorld() {

  1. println(“Hello World”)
  2. } 4> helloWorld() Hello World ```

As with other programming languages, variables defined within the block of a function live for the lifetime of that function:

```sh Variables live for lifetime of a function 5> func helloWorld() {

  1. let name = “World”
  2. println(“Hello (name)”)
  3. } 9> helloWorld() Hello World 10> name error: use of unresolved identifier ‘name’ ```

Swift has positional, named and default arguments. These are specified within the parentheses and are comma separated. Unlike variables (which use type inference to determine what the right type is) function arguments must be typed.

```sh Positional arguments in functions 11> func hello(name:String) {

  1. println(“Hello, (name)”)
  2. } 14> hello(“World”) Hello, World ```

Default arguments can be declared by placing a default value afterwards:

```sh Default arguments 15> func greet(name:String, greeting:String = “Hello”) {

  1. println(“(greeting), (name)”)
  2. } 18> greet(“World”) Hello, World 19> greet(“World”, “Hi”) error: missing argument label ‘greeting:’ in call ```

This error occurs because default arguments are implicitly named arguments. A named argument is one that must be called with a name instead of its position. Names are specified with the same label as the function name:

```sh Calling named arguments 20> greet(“World”, greeting:”Hi”) Hi, World

Named arguments don't have to have a default value though. They can be
declared as named arguments by placing a label in front of the
argument. Named arguments are said to have an ''external name'', which is
the name callers must use to supply the function, and an ''internal name'',
which is used in the implementation of the body itself. This allows
functions to be refactored without affecting their API:

```sh External named arguments
 21> func greet(name:String, greeting salutation:String = "Hi") {
 22.     println("\(salutation), \(name)")
 23. }
 24> greet("World", greeting:"Yello")
Yello, World

As a special short-cut, it is possible to declare that an argument be named with the same name as the argument name using the # symbol.

```sh Named arguments 25> func greet(#name:String, #greeting:String) {

  1. println(“(greeting), (name)”)
  2. } 28> greet(name:”World”, greeting:”Hello”) ```

Note that even though the arguments are named, they have an implied order. It is not possible to miss out the arguments or re-order them, as is possible in other languages with named arguments:

```sh Named arguments out-of-order 29> greet(greeting:”Hello”, name:”World”) error: argument ‘name’ must precede argument ‘greeting’ greet(greeting:”Hello”, name:”World”) ~~~~~~~~~~~~~~~~ ^ ~~~~~~~

[Side note: Error reporting in Swift is really great. The ASCII graphics at the
bottom highlight the erroneous expression (the bit in the parentheses) and the
caret shows where the error was found. This is especially useful in a REPL
where there isn't a defined source file or line numbers.]

Named arguments are a throwback to Objective-C, and to allow Swift to
interoperate with Objective-C classes (which we'll look at in a future post).
In a few cases they can make an API clearer, but in a lot of cases they add
extra noise where none is really required.

Finally, return types and values. As with other languages, the `return`
keyword is used to return from a function and pass a value back. As with
arguments, the return type of the function must be specified (it defaults
to no return type if not) except that instead of using the : syntax, it
invents a new -> syntax instead. This is one of the several annoyances
in the language where consistency goes out of the window because not enough
code has been written to find out these edge cases.

```sh Adding two numbers
 29> func add(i:Int, j:Int) -> Int {
 30.     return i+j
 31. }
 32> add(1,2)
$R0: Int = 3

In next week’s episode, we’ll look at how to create classes in Swift. To subscribe to this series, add the Swift tag feed to your reader.