Similarities between Swift and Scala

Similarities between Swift and Scala

Since its first public release at WWDC’14 many developers have been pointing out some obvious similarities between Swift (Apple’s new programming language for the development of Mac OS X and iOS applications) and Scala, the increasingly popular functional alternative to Java. While the former was announced as “Objective-C without the C”, its main developer Chris Lattner admits that Swift drew from ideas of several languages like Rust, Haskell, Ruby, Python, or C#, among others. Thinking he may have forgotten a little bit about its common points with Scala, some developers have thoroughly gathered the parallels between both, i.e.: here or here.

Working in a fairly Scala-loving environment (but being far from an expert) I thought that it’d be nice to have an introduction to several key points that Swift clearly has learnt from languages like Scala, Haskell, Python, Ruby and others. I hope that it will be useful for developers using these languages to get a list of common elements that may serve as a foundation to start developing on Apple’s platforms; and also for programmers with not-so-much experience in those languages (like me) that have interest in applying functional patterns in their iOS or Mac development.

So without further ado let’s take a look at some cool common functionalities (and in some cases really close syntaxes) of Swift and Scala, and how we can take advantage of them to find new ways to face our daily coding challenges! (You can also download this article as an interactive playground -we’ll talk about Playgrounds in a moment-).

The REPL

Our first connection between Swift and Scala is the existence of a REPL (Read-Eval-Print Loop). This simply means that we now have at our disposal an interactive shell to input short programming expressions and receive an evaluated response. This allows us to test and debug code much faster than having to compile, run and debug code in a project. To start a REPL session, go to your nearest Terminal session and execute the swift command (or xcrun swift under OS X Mavericks). Then you only need to write Swift statements and they’ll get evaluated one by one. It even detects incomplete code and indents it for you like if you were working in Xcode. It’s a great tool to prototype and test small pieces of code without needing to resort to having a hundred TestFoo-like projects on your hard drive!

For a good reference there are two great posts in the official Swift blog to help you start doing cool stuff with the REPL, and go a little bit deeper with it. Once you become comfortable with it, try to write :help (left colon intended) to see a list of all the commands available inside the REPL. This allows us to set breakpoints, debug processes, or directly manipulate memory values inside the debug session. It’s like being Dr. Manhattan on steroids!

Playgrounds

Going even further with coding interactivity, Swift borrows from Scala’s (and other languages’) worksheets, and brands them as Playgrounds. A Playground is basically a set of Swift scripts that are evaluated top-to-bottom, showing the results in a timeline. Each time you modify the code inside a Playground, every sentence inside of it is compiled and evaluated, so you can watch the whole thing change live! It’s a really great way of prototyping algorithms: imagine you’re modifying a value inside a for-loop, you can see step by step how it increases with each iteration and you even get a cool chart with that data.

For example, let’s try this out while dusting off our old high-school math books. With Swift’s playgrounds we can create mathematic functions and see their corresponding graphs. Open a new playground (Xcode > File > New > Playground) and paste the following code under the import statements:

func quadraticFunction(x: Double, a: Double, b: Double, c: Double) -> Double {
    // f(x) = ax2 + bx + c
    return a * pow(x, 2) + b * x + c
}

func cubicFunction(x: Double, a: Double) -> Double {
    // f(x) = x3 + a
    return pow(x, 3) + a
}

func sinFunction(angle: Double) -> Double {
    let radians = angle / 180.0 * M_PI
    return sin(radians)
}

for var i = -10.0; i < 10.0; i++ {
    let quadraticResult = quadraticFunction(i, 2, 2, 1)
    let cubicResult = cubicFunction(i, 1)
}

for var i : Double = 0; i <= 360; i += 10 {
    let sinResult = sinFunction(i)
}

In this piece of code, we’re implementing algorithms to calculate some of math’s good-old classics: a quadratic function, a cubic function and a sin function. You may think that this is a little “meh”, but try to click on the “eye” icon next to the right side of each of the results declarations (inside both for-loops). Voilà! What you see now is the timeline view of each of the results’ declarations in each of execution of the loops. Try to modify the parameters on our calls to see almost instantly how the graphs change. Cool, huh?

Math: the stuff nightmares are made of :D

Why don’t you try to implement a couple more functions (i.e.: a cosine function, a square-root, you name it!), and see how they look?

Another cool thing about Swift playgrounds is that you can create pretty complex documentation with them, using some html and css. In fact, when Apple launched the language, they released an interactive tour with a cool playground you can experiment with. And there are even open-source tools like this one that allows us to create complex playgrounds like Apple’s with ease.

There’s also a Swift module called XCPlayground that allows us to create custom views displayable in a Playground. And Apple seems to have improved them further on Xcode 6.3 (as of Beta 2) with even cooler stuff. As you can see there’s a lot to do, play (pun not intended), and research with Playgrounds.

Tuples

Do you remember the old and dark ages when you wanted to perform a calculation on several values in a function and needed to send it pointer references to do so? Do you feel the same shivering feeling thinking about that as I do? Those times are at last (mostly) over, as Swift introduces tuples (really common in Scala, Haskell, Python…) to Apple’s platforms. A tuple is a set of values packed together, even if they’re from different types. Tuples are first-class types, so you can use them as parameters or return them in a function. This allows us, for example, to return multiple values in a single function call. Tuple syntax in Swift closely matches Scala’s:

// This is a tuple in Scala:
// val tuple = ("Hello", 42)
// And this is a tuple in Swift:
let tuple = ("Hello", 42)

// This is a named tuple in Scala:
// val(string, number) = ("Hello", 42)
// And this is a named tuple in Swift:
let namedTuple = (string: "Hello", number: 42)
let anotherString = namedTuple.string	// "Hello"
let anotherNumber = namedTuple.number	// 42

Close, isn’t it?

Optionals

Another pattern usually repeated in the not-so-ancient times of Objective-C is the nil check. i.e.:

NSURL *dangerousUrl = [NSURL urlWithString:@"troll://not an url"];
if (dangerousUrl) {
	NSString *dangerousString = [dangerousUrl absoluteString];
	if (dangerousString) {
		NSLog([dangerousString uppercaseString])
	}
}

A lot of times we’ve found in our code house of cards-like structures made of nested nil checks. Swift introduces us to the Optional type, which again already existed in other languages like Scala, Haskell… Optionals are enums with two cases: None and Some(value), and they’re used to represent the possibility of nilness. Let’s see how we can rewrite the previous example using an optional:

let potentiallyDangerousUrl = NSURL(string: "troll://not an url")
let niceUrl = NSURL(string: "https://www.47deg.com")

var result : String

func upperCaseStringFromUrl(url: NSURL?) -> String? {
    if let safeUrl = url {
        if let safeUrlString = safeUrl.absoluteString {
            return safeUrlString.uppercaseString
        }
    }
    return nil
}

let aNilResult = upperCaseStringFromUrl(potentiallyDangerousUrl)	// nil
let aNiceResult = upperCaseStringFromUrl(niceUrl)   				// "https://www.47deg.com"

This looks almost the same, doesn’t it? We’re unwrapping the potentially nil values and doing stuff with them. Hold on, we can shortten this out quite a bit:

potentiallyDangerousUrl?.absoluteString?.uppercaseString	// nil
niceUrl?.absoluteString?.uppercaseString					// "https://www.47deg.com"

These lines use optional chaining to unwrap the values in the expressions: if the Swift runtime finds a nil value in the chain it will just stop and return a nil as a result for both expressions. We can also do a lot more with optionals using the next new tool in our arsenal.

Pattern matching

Before Swift, we poor Objective-C programmers had a limited switch statement, that only allowed us to check a scalar value or an enum against a set of values. It’s not my intention to berate the good-old C switch blocks, but Swift has beefed them up to allow complex pattern matching in our day-to-day programming. Again this is nothing new to our functional languages, Scala and friends! With pattern matching you can match a given value against a series of conditions to return a specific result. This, combined with other elements of the language like tuples, optionals, and wildcards, gives us some powerful possibilities.

For example, let’s discriminate between numbers. The next piece of code uses pattern matching to distinguish between small, medium and large numbers. That alone could have been done with a simple if-else block, but things can get a little more complicated if we add more conditions. We really want to know if our numbers are cool, because as Yoda says: size matters not (at least with numbers!). With pattern matching it is easy to check for classic coolness factors like being a prime number:

func isPrime(x: Int) -> Bool {
    let sqr : Int = Int(sqrt(Double(x))) + 1
    for i in 2...sqr {
        if x % i == 0 {
            return false
        }
    }
    return true;
}

func discriminateNumber(x: Int) -> String {
    switch (x, isPrime(x)) {
    case (0..<10, false): return "This is a really small number"
    case (42, _): return "Meaning of life!"
    case (47, _): return "Best number EVER"
    case (0..<10, true): return "This is a small but cool prime number"
    case (10..<1000, _): return "This is a middle-class number"
    case (_, false): return "This is a big big number, not to mess with"
    default: return "You can't beat Optimus prime!"
    }
}

discriminateNumber(1)     // "This is a small but cool prime number"
discriminateNumber(9)     // "This is a really small number"
discriminateNumber(20)    // "This is a middle-class number"
discriminateNumber(1000)  // "This is a big big number, not to mess with"
discriminateNumber(3571)  // "You can't beat Optimus prime!"

Why don’t you give it a try? Paste this code in a new Playground (or use our interactive playground), and add another known number coolness factor: being even! But remember there are great odd numbers like 47, keep them cool!

We mentioned earlier that Swift’s pattern matching is really useful when combined with optional values. For example, we can check if a couple of optional values are nil or not, unwrap them and do stuff with them:

func joinOptionalStrings(stringA: String?, stringB: String?) -> String {
    switch (stringA, stringB) {
    case let(.Some(a), .Some(b)):
        return a + b
    case let(.Some(a), _):
        return a
    case let(_, .Some(b)):
        return b
    default: return "The artist previously known as Prince"
    }
}

joinOptionalStrings("John", " Lennon")	// "John Lennon"
joinOptionalStrings("Chayanne", nil)	// "Chayanne"
joinOptionalStrings(nil, "Shakira")		// "Shakira"
joinOptionalStrings(nil, nil)			// "The artist previously known as Prince"

Here we’re using pattern matching to unwrap several optional values at the same time, something that until Swift 1.2 (which allows to have several optional values in a single if-let block) wasn’t possible.

We can also check perform class-checking, downcast instances (using the “is” and “as”), apply guard conditions (using the “where” clause), and lots of other powerful stuff! You can (and should) take a look at these possibilities in the documentation. The sad part is that switch blocks in Swift can’t return an expression (yet), so we can’t do great things like creating a constant from a pattern matching result like lucky Scala programmers can. But Swift is in its infancy so we hope it will feature this in a near future…

Functions as first-class types

A great feature of Swift that’s new to us Objective-C programmers is that functions are considered a first-class type - that is, you can pass them around to functions as parameters, have a function return another function, or even nest functions. We did have blocks in Objective-C, and they were OK (even if their syntax wasn’t too obvious), but functions in Swift are completely free from constraints of the past! Let’s see some examples of this by rewriting our number discrimination function even further:

func discriminateNumberByFunction(x: Int, functionDescription: String, function: (Int) -> Bool) -> String {
    switch x {
    case 0..<10 where !function(x): return "This is a really small number"
    case 0..<10: return "This is a small but cool \(functionDescription) number"
    case 42: return "Meaning of life!"
    case 47: return "Best number EVER"
    case 10..<1000 where !function(x): return "This is a middle-class number"
    case 10..<1000: return "\(functionDescription) class hero is something to be..."
    case _ where !function(x): return "A great number indeed, shame that it's not \(functionDescription)!"
    default: return "Big \(functionDescription) numbers sure are some wonder to behold!"
    }
}

What we’ve done here is to add a new parameter function that, as you may imagine, takes a function. Specifically one that takes one Int as an argument and returns a Bool. That way we can easily pass further math properties to our function without having to rewrite it each time:

discriminateNumberByFunction(8, "prime", isPrime)   // "This is a really small number"
discriminateNumberByFunction(5, "prime", isPrime)   // "This is a small but cool prime number"

Do you remember the isPrime function we wrote earlier? As it took an Int and returned a Bool, we just have to pass it to our improved function and it just works right out the box! We can complicate things a little bit more:

func isPerfectNumber(x: Int) -> Bool {
    let max = Int(sqrt(Double(x))) + 1
    var total = 1

    func acumulator(x: Int, i: Int) {
        if x % i == 0 {
            total += i
            let q = x / i
            if q > i {
                total += q
            }
        }
    }

    for i in 2..<max {
        acumulator(x, i)
    }	    
    return total == x
}

discriminateNumberByFunction(6, "perfect", isPerfectNumber)     // "This is a small but cool perfect number"
discriminateNumberByFunction(28, "Perfect", isPerfectNumber)    // "Perfect class hero is something to be..."
discriminateNumberByFunction(47, "perfect", isPerfectNumber)    // "Best number EVER"

The function above calculates if a value is a perfect number (a positive number which is the sum of all of its positive divisors excluding itself, the definition of coolness itself!). The code above uses some of the powerful things we can do now with functions in Swift. First: we have a function acumulator nested inside, something rather cool by itself until we notice the fact that it’s modifying the scope outside of its boundaries… (notice how it’s accumulating values on total, which exists outside of it). Nested functions have access to their outside scope, and their container functions can even return them so they can be accessed by other functions. Now that’s versatility!

(As a nerdy side note, until 2013 there were 47 known perfect numbers. Since 2014 there are 48, I guess they got mainstream now… :P)

In Objective-C, by using the infamously cumbersome block syntax, we could create pieces of executable code that worked as anonymous methods. Swift allows us to do the same with closures:

discriminateNumberByFunction(8, "Even", { (value: Int) -> Bool in return value % 2 == 0})	// "This is a small but cool Even number"
discriminateNumberByFunction(8, "Even", {$0 % 2 == 0})										// "This is a small but cool Even number"
discriminateNumberByFunction(8, "Even") {$0 % 2 == 0}										// "This is a small but cool Even number"

So if we have a function that takes a function as a parameter, we can pass it directly a piece of code with the same signature. Swift allows us to write closures in many different ways, more or less verbosely depending on our needs. Above you can see three ways to pass a closure to our function so we can discriminate even and odd numbers. Notice how if we have a closure as the final parameter in a function call, we can write it as a trailing closure by having the curly braces outside of the call itself! Also notice how we can omit the return statements (they’re implied for the last line of the closure), and we can also use shorthand for our closure input parameters ($0, $1,… $n).

Again this is really close to the way Scala and other languages handle closures, and even the syntax is almost the same:

// Scala:
val maxNumber: (Int, Int) => Int = (m: Int, n: Int) => if(m > n) m else n

// Swift:
let maxNumber = { (m: Int, n: Int) -> (Int) in m > n ? m : n }
maxNumber(3, 5)	// 5

Partially applied functions

Partially applied functions (or curried functions) are the bread and butter of functional languages like Scala, but at least for me (and I guess many programmers with almost no experience in functional programming) is a rather new concept. Imagine you have a function that takes two Strings and joins them together to form a new String, like the following trivial example:

func sayHelloToPerson(greeting: String, name: String) -> String {
    return greeting + ", " + name
}

sayHelloToPerson("Hello", "Dolly")	// "Hello, Dolly"

But what if we needed to greet in different languages, or use a more informal tone? Should we be writing different calls with “Hi” or “Hola” every time? It’d be great to be able to define a default value for the first parameter at run-time, so we only need to provide the name of the person to be greeted. We can do this with what’s called a curried function: instead of taking two Strings and an Int, we’re going to rewrite it so the function now takes a String as a parameter (the greeting), and returns a function that takes another String as a parameter (the name), and subsequently returns a String (the final greeting):

func greetPerson(greeting: String)(name: String) -> String {
    return greeting + ", " + name
}

let informallyGreet = greetPerson("Hi")
informallyGreet(name: "Dolly")  // "Hi, Dolly"

let japaneseGreet = greetPerson("こんにちは")
japaneseGreet(name: "Dollyさん")  // "こんにちは, Dollyさん"

This may not seem like a big deal: we’re just setting up default values. But currying allows us to have functions that don’t need all of their input parameters at a certain moment to build their results (they’ll be stored until all of them are available). And it’s really easy to create curried functions from existing ones should we need it:

func curriedlyDiscriminateNumberByFunction(functionDescription: String, function: (Int) -> Bool)(x: Int) -> String {
    return discriminateNumberByFunction(x, functionDescription, function)
}

let discriminateByPrimes = curriedlyDiscriminateNumberByFunction("prime", isPrime)
discriminateByPrimes(x: 3)  // "This is a small but cool prime number"

Higher-order functions

Having closures around sure helps to fix a big hole in Objective-C’s collection types: the lack of 3 basic higher-order sequence functions that are supported by many other languages: map, filter and reduce. These address common operations on collections and allow us to do some powerful stuff with just a few lines of code. Let’s take a closer look at each one of them:

map: allows us to take every item in a collection, apply a function to it, and return a new collection with the transformed values. We have done it so many times in the past it’s almost automatic to start writing a for-each loop… Not anymore!

let beatles = ["John", "Paul", "George", "Ringo"]

// The old way:
var temp = [String]()
for beatle in beatles {
    temp.append("Good morning, \(beatle)")
}

// The brand-new-best way:
let beatGreetings = beatles.map({"Good morning, \($0)"})
// Good morning, John
// Good morning, Paul
// Good morning, George
// Good morning, Ringo

As you see, Swift’s brief closure syntax is really handy here, specially the use of shorthand values (i.e. “$0”). Map (and the other higher-order functions) also make a good partnership with curried functions:

let beatInformalGreetings = beatles.map(greetPerson("Good morning"))
// Good morning, John
// Good morning, Paul
// Good morning, George
// Good morning, Ringo

filter: allows us to, well, filter a collection by applying a condition to each element. Shorthand syntax makes it really easy to apply conditions to our elements in the closure:

let coolestBeatle = beatles.filter({$0 == "Ringo"})   // Everybody loves Ringo...
println(coolestBeatle)	// ["Ringo"]

reduce: reduce won’t return a collection but a single value containing the result of applying a function to all elements of the collection. We need to pass two parameters to it (as opposed to map and filter that only take one), the first being the initial value for the calculation and the latter being the function to apply. An easy to imagine example of this would be a summatory function applied to an array of Int (with an initial value of 0). But we can use reduce with all kind of elements:

let beatleMath = beatles.map({ $0.utf16Count }).reduce(0, combine: +)   // 19
let beatleGreetings = beatInformalGreetings.reduce("", combine: {$0 + "\n" + $1 })
// Good morning, John
// Good morning, Paul
// Good morning, George
// Good morning, Ringo

In the first example we create an array containing the lengths of each Beatle name (using map), and then calculating the sum of them all with reduce. In this case we don’t need any fancy logic, so we can just pass the operator and forget about writing a closure. In the second example we’re getting the informal greetings we crafted earlier, and concatenating them with a line-break between each; so we will be needing a closure now. Again, the syntax for these higher-order functions is almost exact to Scala’s (but the latter uses “_” as a shorthand operator, instead of Swift’s $0, $1…).

Why don’t you give it a try and experiment a little bit with these functions in a Playground?

let fullBeatles = ["John Lennon", "Paul McCartney", "George Harrison", "Ringo Starr", "Brian Epstein", "Stuart Sutcliffe", "Pete Best"]
// Get a list of all former Beatles' surnames!
// Hint: use the map function to return a substring, you can use the find function to get the index of the separator...

let queenMembers = ["Mercury", "May", "Deacon", "Taylor"]
// Try to concatenate all Queen members surnames that start with an "M". Notice that in Swift there's a handy startsWith function!
// You can use filter and reduce, or use reduce alone itself.

These higher-order functions give us so many different approaches to solving problems! In fact, both filter and map are actually based on reduce. Once you get the hang of them, you’ll find yourself improving their use in your code really quickly!

###An application with all of this: Functional Life

Life is a game we're playing...

I thought it’d be great to create a little app that would use some of these new functionalities. So I remembered Conway’s Game of Life: a nice little algorithm that sparked my imagination when I was a child and tried it on my brother’s MSX computer (and it created a frenzy among micro-computer users in the 1970s and 80s). In “Game of Life” there’s a field populated with living and dead cells. The player creates a seed of life (made of several living cells), and then sees how it evolves generation by generation. Besides being a problem really fun to work on and having very visual results, I didn’t notice that it’s a pure functional problem: each generation is the result of applying the algorithm on its predecessor. It’s like being the god of your own little universe, and not just some god but a functional one!

The project itself is an iOS universal app, and the graphics and game loop are done using SpriteKit. You can find the game algorithm in the class FLGameAlgorithm, which you’ll see is really short and succinct. During the development I’ve tried to use the features I’ve introduced in the rest of the article, but as a newbie myself in the functional arena, I’m sure there’s a lot of room for improvement here. Advice and suggestions would be really appreciated! :). Feel free to download it from this repository

###Conclusion (at last!) In this article I’ve tried to share a little bit of my experience applying my basic knowledge of functional programming and patterns to my day-to-day Swift development. I’d like to clarify that by no means am I trying to say that Swift is a functional language: while some of its features allow functional programming to be possible in Mac OS X and iOS development, there are really good arguments against this reasoning. I think that one of the best is made by @cocoaphony in an article with the clear and succinct title of “Swift Is Not Functional”. He approaches this question not discussing too much about functional features that Swift may lack, while figuring out what does it mean conceptually that Swift wasn’t designed with them in the first place. I think it’s a good read that not only brings the message home, but gives an interesting point of view on how functional programming can make us better developers (even if we’re not developing in a purely functional language). I highly recommend it.

So while accepting that Swift is an OOP language with a big focus on generic development (and not a functional or multi-paradigm language), I believe that it shouldn’t discourage us to try to apply more functional patterns into our iOS/Mac development. Yes, there are also many features from Scala, Haskell and all the other members of the functional family that are missing from Swift. But that’s something I’m sure the open-source community, and ourselves, are willing to help with! I hope that this text helps some of our fellow iOS/Mac developers to put a little of functional adventure into their routine, imperative lives!

blog comments powered by Disqus

Ensure the success of your project

47 Degrees can work with you to help manage the risks of technology evolution, develop a team of top-tier engaged developers, improve productivity, lower maintenance cost, increase hardware utilization, and improve product quality; all while using the best technologies.