Swift - Function

Subscribe Send me a message home page


In this post, we will try to learn how functions work in Swift. The Swift language is kind of in the middle between Java and Python. On the one hand, Swift and Java are both compiled language and have type system. On the other hand, Swift and Python are more flexible and more friendly to functional programming. In this post, we will try to use Java and Python as a reference to understand functions in Swift.

Function Definition

Let's start with function definition. In Swift, there is a notion called external parameter name. In Java, there is no such notion and Java uses positional arguments. In Python, we do have named arguments but the external parameter name in Swift is a little bit different. With the external parameter name, we can indicate the name of parameter when we call a function, which makes the code easier to read but we still need to follow the order strictly.

Another difference between Swift and Python is that in Swift the external parameter name is used by default and it has the same value as the name of the argument in the function definition. When the function is called, we are forced to specify the variable name, which in Python is optional. Here is an example of Python named argument:
def f(x, y, z):
    print("x = {}, y = {}, z = {}".format(x, y, z))

f(1, 2, 3)
f(1, y = 2, z= 3)
f(1, z = 3, y = 2)
The output of the above program is
x = 1, y = 2, z = 3
x = 1, y = 2, z = 3
x = 1, y = 2, z = 3

Here is an example of function definition code in Swift
func f(x: Int, y: Int, z: Int) {
    print("x = \(x), y = \(y), z = \(z)")
}


// f(1, 2, 3)  // Compile error. The variable name is required
// f(x: 1, z: 3, y: 2) // Compile error. The order of the arguemtns is wrong
f(x: 1, y: 2, z: 3)
The output of above program is
x = 1, y = 2, z = 3

In order to disable the external parameter name feature, we could use the following syntax:
func g(_ x: Int, _ y: Int) {
    print("x = \(x), y = \(y)")
}

g(10, 20)
The output of above program is
x = 10, y = 20

Call by value or Call by refernece?

In Swift, we have the notion of reference types and value types. Classes are reference types and all other object types are value types. Roughly speaking, reference type is object in Java and value types are primitives in Java and call-by-value is used by default in Swfit.

Another difference between Swift and Java is that by default we cannot update the value of a passed argument in Swift. Therefore the following two function definitions are equivalent.

Swift function definition:
func myFunc(_ x: Int) {
    print(x)
}
Java function definition:
public static void myFunc(final int x) {
    System.out.println(x);
}

Really want to call by reference?

If we really want to do this, it means we want the function to have a side effect that changes the value of the passed variable. Therefore, the variable that will be passed as an argument to the function should be mutable itself. We also need to tell Swift compiler that we want to modify the argument in the function by using the keyword inout right before the argument type. When we call the function, we need to pass the address of the variable. Therefore, there are two extra steps if we call a function by reference.

Here is an example.
func setTrue(_ v: inout Bool) { 
    v = true 
}

var isModified = false
print("isModified before execution: \(isModified)")
setTrue(&isModified)
print("isModified after execution: \(isModified)")
Here is the output of the above program:
isModified before execution: false
isModified after execution: true

Lambda function (Anonymous function)

All three languages support lambda function. Python has the simpliest syntax.
f = lambda x : print(x)
Java is slightly more complicated:
final Consumer<Integer> r1 = x -> System.out.println(x);
final Consumer<Integer> r2 = (Integer x) -> {
    System.out.println(x);
};
As we can see here, the variable r1 and r2 are defined as Consumer. In Java, functions are not first class objects and they are always associated with a class.

In Swift, the most complete form is the following
let f = {
    (x: Int) in
    print(x)
}
(Note that Swift provides abbreviated syntax for anonymous function.)

----- END -----

Send me a message Subscribe to blog updates

Want some fun stuff?

/static/shopping_demo.png


Comments