In the past years, mobile applications took the world by storm and already changed the way we use the internet for work or leisure. Various technologies emerged to create mobile apps and development processes start to consider mobile as first class citizens. But even though mobile already seems to be omnipresent, the future is just about to start. We're facing new generations of mobile devices like wearables or lots of mobile gadgets that make up the Internet of Things. We will be confronted with new types of user interfaces for displaying data as well as accepting commands. And we will recognize more and more companies going real mobile first. All this will influence the way we design, develop and test software in the coming years.
This InfoQ article is part of a series on the fast-changing world of Mobile technology. You can subscribe to notifications about new articles in the series here.
Apple recently promoted Swift - a new programming language for iOS and OSX development, to version 1.0. Apple’s Swift is not to be mistaken with the older parallel scripting language. Swift comes to make iOS and OSX development simpler and more fun. In this article, I will explain what I think are the top 5 killer features of Swift; and why - while it is still in beta - it’s absolutely worth checking out.
Apple already had a programming language, Objective-C. So why introduce yet another programming language? Well, while Objective-C might have been quite different and modern when it was created, it does not convey today’s taste for languages. On the consumer side for example, scripting languages like Ruby have been highly adopted to a large extent thanks to the clean syntax that the language offers. In the enterprise world, strongly typed (type safe) languages with type inference seem to be preferred and big efforts have been seen in languages like C# and Java (or Scala) to bring concepts typically found in functional languages like functions as objects and Lambdas. Objective-C is lacking some of these things like a clean syntax (and Syntactic sugar) and type inference. Swift tries to fill this gap.
This is not to say that Objective-C is not a good programming language. As a matter of fact, it is a great language. But I do see clear signals of enough room for alternatives to Objective-C to succeed. To take things even further, and thanks to how good Swift is, I wouldn’t be surprised if the adoption of Swift s spreads like wildfire.
Now let’s focus on what Swift has to offer. From a language perspective, Swift is awesome. Apple took note of modern languages like Scala or C# and built a super simple and yet powerful language. It provides a super sweet mix between object-oriented and functional programming paradigms - saying that Swift is a functional language is a big stretch though. Let’s move on to the top 5 killer features of Swift.
#1: Syntax Goodies
Syntactically speaking, Swift is superb. It is an extremely simple and clean language with an awesome readability even by today’s standards. You can see right away that simplicity was key when designing the language. Take for instance, the famous semi-colon at the end of statements. Apple decided to make it optional. While it may not seem extremely relevant, it conveys the effort they did to keep the syntax as clean as possible.
Other examples of this are string interpolation, and the language support for dealing with arrays and loops.
String interpolation
var message = "Hello World" "The message is \(message)" //The message is Hello world var a = 1, b = 2 "The sum is \(a + b)" //The sum is 3
Loops
var length = 10 for i in 0..<length { //Do something with i }
Arrays
var list = ["a", "b"] list += ["c", "d"]
These are just a handful of examples of how Swift has language support for doing these types of things. Notice, for example, that concatenating arrays can also be done with the “append” method on the Array class, but the fact that Apple went the extra mile to build this as part of the language demonstrates what their goal is with Swift.
If you want to learn Swift, and test some of these sample codes, I couldn’t stress enough how cool the new Playground in Xcode 6 is. The Playground allows you to test your code as you are typing it in real-time. It will execute everything you type in the Playground, and give detailed information about the values of the variables, the returned values of function calls, and how many times specific code blocks were executed. Opening the Playground in Xcode 6 is very simple:
(Click on the image to enlarge it)
And here is how the Playground looks:
(Click on the image to enlarge it)
#2: Functions are First-Class Objects
Functions as first-class objects and higher-order functions, can be found in more and more languages. For example, Java 8 recently introduced Lambdas. The concept is simple, let functions take other functions as parameters, and/or return functions as well. In it’s simplicity lays the power of this concept, since it allows for greater abstractions. Take a “filter” function applied to an array as an example. A filter function allows you to filter a given array based on which of those items meet a certain criteria passed as a parameter. The key for having a super generic method, is to be able to receive a function as a parameter. Let’s go through the syntax for defining functions.
Swift has a syntax for defining Functions that somewhat resembles those from typically functional languages like Haskell (it’s not exactly the same, but similar). On the left side of an arrow (->) you have the parameters and on the right side of the arrow you have the return Type. In our example, we want to filter a list of numbers, so based on a given number we want to return a Bool. In this case, the type of the function will be:
(Item:Int) -> Bool
Meaning you receive an Int, and return a Bool. Obviously, you could have multiple parameters, but less obviously, you can also return multiple values without having to create a container object. In the latter case, the function will return a tuple.
The definition of a function for filtering integers could be:
funct bigNumbersOnly (item:Int) -> Bool { return item > 3 }
Now that we have our function, let’s take a look at the “filter” function which takes a function as parameter.
var numbers = [1, 2, 3, 4, 5] var bigOnes = numbers.filter(bigNumbersOnly)
In this example, filter is a higher order function, because it takes a function as a parameter. In Swift functions are also objects, which means that we can define the function inline…
var numbers = [1, 2, 3, 4, 5] var bigOnes = numbers.filter({(item:Int) -> Bool in return item > 3})
… or we can also assign the function to a variable and use it later.
//define two variables of type function var biggies = {(item:Int) -> Bool in return item > 3 } var threes = {(item:Int) -> Bool in return item == 3 } //decide which one to apply at runtime var result = numbers.filter(onlyThrees ? threes : biggies)
Treating functions as objects you can reference and pass them as parameters is pretty standard nowadays. But again, you can tell by the simplicity of how this is done in Swift, that it’s a core concept that gets even better with type inference.
#3: Strongly-Typed with Type Inference
In the enterprise world, we are very much accustomed to working on top of our strongly typed (or type safe) safety net. While strongly typed languages can give you that extra bit of confidence that (usually) things won’t break if they compile, it is typically a better experience when these languages also do type inference. So for example, I could do:
//Without Type inference var x:String = "bar" //With Type inference var y = "bar"
Notice, the lack of a type in the second statement. Because Swift knows that “bar” is a string, I don’t have to explicitly define it that way (although I could, like in the first statement). This might not seem a huge deal, but it certainly becomes more interesting when it is the Type of functions that is inferred.
So how can we define the functions from our previous examples, without defining the type? Let’s see how Swift pulls this one off.
//$0 will map to the first parameter, $1 to the second... var result = numbers.filter({ return $0 == 3})
Doesn’t get much cleaner than that! If you had more than one parameter and would like to reference parameters by name instead, you could do it like this:
{a, b in return a > b }
#4 Generics
Another feature available in the language, which can be extremely handy, is generics. In the enterprise world, generics were first introduced in C#, and later made it to Java after gaining a lot of traction. Using generics you can sometimes get rid of type casts. They allow the compiler to run certain type checks usually not available in languages without generics (it’s also true that generics did generate some controversy when introduced in C#, but it was overall accepted in the C# and Java communities).
Generics provide a way to defer the definition of a type, usually (but not limited to) of parameters and return types. While it sounds complex, it’s actually pretty simple to understand with a simple example.
//At the moment of creating this function //I am not defining what T is. The actual //Type of T will be deferred to the call //of the doNothing function. func doNothing<T> (item:T) -> T { return item } //When I call doNothing, I am implicitly //setting the type of T to the Type of the//parameter I am sending. In this case, //an Array. //Notice how the compiler knows, that the //return type is an Array. doNothing([1, 2, 3]).count
While it’s not a very realistic example, you can see the convenience of knowing the type of the object inside the Array at compile time. For a simpler example, notice how the compiler knows that the Array contains Strings:
var list = ["hello", "world"] list[0].uppercaseString //HELLO
Generics are not limited to parameters, you can define generic classes, enumerations and structures. As a matter of fact, in the previous example, the type of list is Array<String>.
You might think generics in Swift are like protocols in Objective-C, however despite the similarities in the syntax, the concepts are quite different. Objective-C does not support generics. Protocols provide a way to declare that a certain implementation conforms to a messaging contract, but the contract has to be specified in advance. For example, you can't enforce that every item in an array be of the same type (no matter which type) with protocols, but can you can do that with generics. Apart from the fact that these two concepts are different, Swift does support protocols in pretty much the same way to how Objective-C does.
#5 Tuples
Tuples is a very simple concept, you can define an ordered group of values. Tuples can be very useful when having to pass more than one value around - as a parameter or as the result of invoking a function. Tuples don’t require you to define any types for its values, everything gets inferred and type checked at compile time. The syntax for defining a tuple is the following:
(1, "Two", ["Three"])
In this case, we have a tuple with three values, the first being an integer, the second a String, and the third one is an Array of Strings. At first glance this might look very similar to Arrays, however the concept is different. You can’t append or remove an item from a Tuple, and notice how the compiler knows the exact types of every value:
You can reference the different values of a tuple either by it’s location inside of the Tuple, like the image suggests, or you can give names to each of these values. This is very handy when a function needs to return several values, and it might be an overkill to define a Class or Struct just for that function. Let’s see an example of such case.
func info(items:[Int]) -> (avg:Int, min:Int, max:Int) { var sum = items.reduce(0, { $0 + $1 }) var min = items.reduce(Int.max, { $0 > $1 ? $1 : $0}) var max = items.reduce(Int.min, { $0 < $1 ? $1 : $0}) return (sum / items.count, min, max) } var result = info([1, 2, 3, 4, 5, 6]) result.avg //3 result.min //1 result.max //6
Tuples provide a very simple way to work with multiple values without having the extra work of defining a class or struct.
And there’s more…
The language comes with some other great features worth checking out, such as property observers, optional chaining, and extensions.
I believe Swift has all the necessary conditions to quickly become a popular programming language for iOS and OSX in both the enterprise and consumer worlds. The strongly-typed with type inference characteristic of the language will make it specially suitable for the enterprise, while the simple and clean syntax will attract those on consumer projects.
About the Author
Gustavo Machado is the Vice President of Engineering at KidoZen, where he leads the execution of the company’s next-generation enterprise mobile platform. He has vast experience developing highly distributed systems with different technologies and using Agile practices. He keeps an active blog and twitter account @machadogj.
In the past years, mobile applications took the world by storm and already changed the way we use the internet for work or leisure. Various technologies emerged to create mobile apps and development processes start to consider mobile as first class citizens. But even though mobile already seems to be omnipresent, the future is just about to start. We're facing new generations of mobile devices like wearables or lots of mobile gadgets that make up the Internet of Things. We will be confronted with new types of user interfaces for displaying data as well as accepting commands. And we will recognize more and more companies going real mobile first. All this will influence the way we design, develop and test software in the coming years.
This InfoQ article is part of a series on the fast-changing world of Mobile technology. You can subscribe to notifications about new articles in the series here.