Functions in Swift

Posted on 6/18/2014 @ 7:34 PM in #Swift by | Feedback | 1126 views

Functions – as you might have already guessed, are blocks of functionality that you can call, pass parameters to, return parameters from. They can also accept or return Tuples, which is a convenient way to return multiple values at once.

Here is you can you write and call a function in Swift

   1:  func GetADrink(drinkName:String) {
   2:      var test = drinkName
   3:  }
   4:   
   5:  GetADrink("Mango Juice")
 

Function Parameter Names -

One of the nice things about ObjectiveC, was/is self-documenting code when it comes to functions. When reading a function call (message pass) in ObjectiveC, you could immediately tell what parameter is what, because the parameter names were right there with the invocation statement. This is also available in Swift, using the following syntax,

   1:  func GetADrink(drinkType drinkName:String) {
   2:      var test = drinkName
   3:  }
   4:   
   5:  GetADrink(drinkType: "Mango Juice")
   6:   

Now, you can by just looking at the invocation of the function, immediately tell what parameter does what! Bye bye long confusing functions with crazy parameter lists confusing me.

But the above syntax has “drinkType” and “drinkName”, why can’t I just use “drinkName”? You can, like this -

   1:  func GetADrink(#drinkName:String) {
   2:      var test = drinkName
   3:  }
   4:   
   5:  GetADrink(drinkName: "Mango Juice")
   6:   


Function Parameter Default Values -

Function parameters can also have default values, and therefore optional parameters as follows.

   1:  func GetADrink(#drinkName:String = "Lassi") {
   2:      var test = drinkName
   3:  }
   4:   
   5:  GetADrink()
   6:  // GetADrink(drinkName: "Mango Juice")
   7:   

Variadic parameters, a.k.a. paramArray

Sometimes you want to send numerous input parameters, like paramArray in C#. This is how you do it in Swift,

   1:  func makeASentence(words:String...) -> String {
   2:      var toReturn:String = ""
   3:      for word in words {
   4:          toReturn = toReturn + " " + word
   5:      }
   6:      return toReturn
   7:  }
   8:   
   9:  var output = makeASentence("This","is","Fun","isnt","it?")

 

Input parameters are constants by default

In Swift, input parameters are unchangeable by default. In other words, you cannot set their value. If you wish to set their values, you must explicitly state your intention to do so, like this,

   1:  func sampleFunction(var youCanChangeMe:String, youCantChangeMe:String) {
   2:      youCanChangeMe = "I changed you"
   3:      //    youCantChangeMe = "I changed you" // This is not allowed
   4:  }
   5:   
   6:  var firstInput = "Flexible"
   7:  var secondInput = "Inflexible"
   8:   
   9:  sampleFunction(firstInput, secondInput)

Note that, just like C# or any other language, there is the concept of byRef and byVal. As a result, the string after the function call will remain unchanged outside the function. However, if you were to pass in an Object, and set a property of the object, that property value would change.

InOut parameters

As you can see, in the above example where I show input parameters being constants or not, the value of firstInput will still be “Flexible” outside the function call.

Sometimes you do want the value to change, and that is where you use inout parameters instead of vars, and you choose to pass a pointer to the ByVal by passing in &firstInput instead of firstInput (just like C++).

Here is how,

   1:  func sampleFunction(inout youCanChangeMe:String, youCantChangeMe:String) {
   2:      youCanChangeMe = "I changed you"
   3:      //    youCantChangeMe = "I changed you" // This is not allowed
   4:  }
   5:   
   6:  var firstInput = "Flexible"
   7:  var secondInput = "Inflexible"
   8:   
   9:  sampleFunction(&firstInput, secondInput)

At the end of this call, firstInput parameter would have changed outside the function call.

Functions as Types

C# has a concept of delegates. C++ has pointers to functions. In short, both of them allow you to treat functions as data. But delegates are safer, since you can’t point to the wrong location in memory with a delegate. Swift has a similar concept called Function Types, where I can represent the “signature” of a function as a datatype, and then declare a variable of that type and call the function using that variable. Like this -

   1:  func FlyToDestination(destinationname:String) -> String {
   2:      return "Crappy experience in airlines these days"
   3:  }
   4:   
   5:  func DriveToDestination(whereAreYouGoing:String) -> String {
   6:      return "Gas is so damn expensive these days"
   7:  }
   8:   
   9:  var genericTravelFunction : (String) -> String = FlyToDestination
  10:   
  11:  genericTravelFunction("Tahiti")

This is really cool because it lets you treat functions as input types to other functions, like this,

   1:  func FlyToDestination(destinationname:String) -> String {
   2:      return "Crappy experience in airlines these days"
   3:  }
   4:   
   5:  func DriveToDestination(whereAreYouGoing:String) -> String {
   6:      return "Gas is so damn expensive these days"
   7:  }
   8:   
   9:  func goSomeWhere(genericTravelFunction : (String) -> String, whereAreYouOffTo:String) ->String {
  10:      return genericTravelFunction(whereAreYouOffTo)
  11:  }
  12:   
  13:  goSomeWhere(FlyToDestination, "Tahiti")

 

The example I showed above uses a function as an input parameter. You can also use functions as return types.

Nested Functions

Best explained with a code example,

   1:  func Inception() {
   2:      var donkeyPoo = "LOL"
   3:      func InSheeptionwithinInception() {
   4:              // whoaa!
   5:          println(donkeyPoo) // outside variables are available here
   6:      }
   7:      InSheeptionwithinInception() // and I can call methods here
   8:  }
   9:   
  10:  // InSheeptionwithinInception() // but I can't do this
  11:  // Inception.InSheeptionwithinInception() // can't do this either

The above is quite similar to what you may see in JavaScript, which then brings me to the best part about Functions in SWIFT

Closures

Closures most frequently used in JavaScript, are self contained blocks of functionality that isolate you from the global namespace, and can be passed around as blocks. Closures are so cool, they deserve their own blogpost.

Sound off but keep it civil:

Older comments..