Thursday, 18 September 2014

Swift Functions and Tuples

I mentioned in a previous post that it really helped reading about Swift Closures to understand some of the concepts and approaches that are programming patterns in the language. This post isn't about closures, but some notes on functions and tuples that I cleared up in my mind reading about them,

The first thing to grapple with (for a C-sharp/Java programmer) is the Swift style function definitions. We're used to the C heritage of showing the return type first and then the function name and parameters. Initially the syntax just seemed odd, but after reading around this I gradually got an appreciation for the style and although still not natural it has a good logic to it and makes sense. The definition is a more traditional maths/function way of looking at things, you have a set of inputs that have some function operate on them to generate some output:

(inputs) -> (output)

Which is a pretty neat and understandable function definition. Now, if you've been programming for a while you'll soon fall into the dilemma that you've written your fantastic function, got a set of input parameters and the usual return value to indicate success/error conditions or you've been extra clever and all the error conditions are considered as exceptions and you're returning some important result value (note, this can be an abuse of exceptions as they are truly intended to be exceptional cases, rather than error conditions which may be legitimate returns, but not exceptions), then a change or extension of needs means you need to return multiple values.

Usually what happens is you either end up changing the function to have some return parameter - in C-sharp this is an 'out' parameter of the function or bundling the outputs into a class, creating an object, setting the attributes, returning it and then checking the values. Hmmm, either lots more code or a messy function parameter. Neither is ideal.

Tuples
Now, in Swift, there is a relatively simple conceptual extension, why not, given the above syntax definition for a function not just allow multiple parameters in both the input and output parts of the function. Neat!! This is where Tuples come in. It took me a while to understand the linkage of the two first of all, but in C-sharp speak the one you're probably most used to is the Tuple for Dictionary KeyValuePair, which is sort of snuck in to resolve this dilemma. In the case of Swift, it's a commonplace approach seemingly.

So, back to our Swift function example, we can define something like this:

func modify(freq:Float, amp:Float) -> (freq:Float, amp:Float)

In this case (I know it's not a good example) we're putting a freq and amp and getting out a modified freq and amp. The function has a type definition like this:

(Float, Float) -> (Float, Float)

Using the inferred syntax for the result (where the type is not explicitly given), it can then be easily called as follows:

let result = modify(freq:2.0, amp:1.0)

Nice! Now the values in result can each be accessed by qualifying the variable: result.amp or result.freq. It's also possible to create inferred tuples (unnamed tuples in Swift-speak) as general variables as follows:

let freqandamp = (2.0, 1.2)

which does not qualify the two values explicitly, but just orders them. The qualification can be easily specified below which is called a 'named tuple'.

let anotherfreqandamp = (freq:1.0, amp:1.2)

or using an explicit syntax:

let yetanotherfreqandamp(freq:Double, amp:Double) = (2,0,1.2)





No comments:

Post a Comment