A Javascript developer’s guide to Swift  

This year’s WWDC was a big surprise for anyone following Apple. But the biggest surprise was the new language called Swift. Apple has managed to create a whole new language that borrows heavily from many other languages but eventually is something unlike anything out there. The syntax may be similar but there unique characteristics to the language that are not out there in any other language. One of these is the fact that Swift is completely compatible with Objective-C. It uses the same APIs and in fact you can use both languages in the same project. It is then but natural for lots of people to directly compare Swift with Objective-C. Others have also compared Swift to Go, Scala, F#, C# etc.

I’m here to compare it to Javascript. Going over the language, I see the many similarities. And even in places where the languages are very different, there are ways where Swift can be written in a way that makes it more like Javascript. Given the depth of both languages this will probably become a series of blog posts. Right now, I’ll focus on the basics. Variables, Arrays, Functions, and Hashes (Objects in Javascript, Dictionaries in Swift).

 Variables

var x = 1

Well, that’s it. Really the way you define a variable is identical in both languages. The semicolon is optional in both languages too. But what really happens behind the scenes is a little more nuanced.

Take this code for example:

var x = 2
x = "Something"

This is valid Javascript code but in Swift, it will throw an error. See, Swift is strongly typed language. The compiler is actually adding code for you. The above code becomes this before it runs:

var x:Int = 2
x = "Something"

If you have any experience with a language like C, you know Int means an integer. When we assigned x=2, the compiler assumed we want to store integers in x.

Notice that this would be an error too:

var x = 2
x = 2.5

But this would work fine

var x = 2.0
x = 2.5

Though the two code block look similar, in the first example the compiler will assume you want to store integers, since 2 is an integer. But in the second example, but putting the decimal point, you’ve made your intent clear that you want to store floating point numbers. The ‘type inference’ is a convenience feature in Swift, but you can also define the type yourself. And so if you wanted to store floats in a variable and initialize it with a value of 2, you could also do this:

var x:Float = 2
x = 2.5

This time the compiler makes no assumptions since you told it that you want x to store Floating point numbers.

Obviously this is a more limited compared to Javascript’s variables where you can pretty much store ANY value in a variable. But this limitation, can also help you in many ways. Swift will make sure that a variable with the type Int always has an Integer value. In fact, if there’s even a chance that may not happen, the Xcode will complain at compile time. This way, it can help you avoid a whole set of problems.

But we’re used to javascript. If we want that power, it’s really not that hard. All you have to do is assign a variable the type of Any:

var x:Any = 2
x = "String"
x = true

And just like that, x can now store any value. This includes any Integers, Strings, Booleans, or nil (Swift’s alternative to Javascript’s undefined and null). These variables can also store objects created from class or struct (we will get to them later).

 Strings

Before we get to arrays and dictionaries, there should be a short note on Strings in swift. They are very similar to strings in Javascript. But you always use double quotes. The various escape sequences remain the same such as \n. The one cool feature of Swift is how to do string interpolation. For example, in javascript you may do something like this:

var x = 5, y = 6
var str = x + " times " + y + " is " + (5*6)

As we are well aware, this can get quite annoying. As a result, ES6 has borrowed a feature from CoffeeScript that let’s you type this:

var str = "#{x} times #{y} is #{x*5}";

Swift has a very similar ability with a slightly different syntax:

var str = "\(x) times \(y) is \(x*y)"

Another important thing to note is that just like Javascript, the saying ‘everything is an object’ mostly holds true. Primitive types such as Int and String can have methods on them. For example:

var upperCaseStr = "hello world".uppercaseString
// => "HELLO WORLD"

 Constants

There are times when we don’t want certain values to be immutable. Let’s say we’re using some variables for configuration, and we never want to them to change at runtime. Swift let’s us ensure that with constants. Anytime you define a value with the let keyword instead of the var keyword, you get a value that can only be assigned a value once, and trying to reassign a value will throw an error. You can achieve the same thing in Javascript with the const keyword.

Note: The let keyword in ES6 enables block-scoped variables, not constants, so don’t get confused. Also, since all variables in Swift are block-scoped anyway, that’s not an issue.

 converting back from Any

The one loss of using the any keyword is the fact that the Swift compiler forgets what type of value it is. As a result you can’t call any methods on the value anymore. Let’s say we have two variables:

var a = "Hello World"      // inferred as var a:String
var b:Any = "Hello Again"
a.uppercaseString
// => "HELLO WORLD"
b.uppercaseString
// !! ERROR !!

See the thing is that for Swift, b isn’t a string. It’s just a variable that could be anything. The only way to get around it it convert the value back to a string:

let str = b as String
str.uppercaseString
// => "HELLO WORLD"

This will work if you’re sure that b is a string. (You shouldn’t be using the type any to begin with in such a case) But if it’s not, it’ll throw a run-time error. What do you do if you don’t know what type of value b stores. You can test it:

if b as? String {
    let str = b as String
    str.uppercaseString
    // => "HELLO WORLD"
}

Notice the Question Mark after the as, this returns a boolean. Also notice how there are no parenthesis around the condition. (The syntax of an if construct is identical other than that small detail).

But we can actually make this code slightly more concise, as this is a common pattern:

if let str = b as? String {
    str.uppercaseString
    // => "HELLO WORLD"
}

This code is identical to one previous to it. It just tests and assigns the value all in a single line.

 Arrays

Just like variables, Arrays are a Strongly typed by default.

var arr = ["alpha", "beta", "gamma"]

is inferred by the compiler to be

var arr:String[] = ["alpha", "beta", "gamma"]

Hence, arr is an array of Strings, all you can ever store in it are strings. It’s pretty much the same as Javascript in all other ways.

So, how do you get an array where you can store any sort of values. Firstly, this will work:

var arr:Any = [1, 2, 3]

But now, Swift doesn’t even know that arr is an Array. And so to anything meaningful with the array you will first have to cast it as an Array:

if let a = arr as? Int[] {
    // do something with a
}

It would be much better to just store values in something that Swift knows is an array. Easy:

var arr:Any[] = [1, "string", true]

And now you have an array that can store anything. And we can read and reassign values at various indexes:

arr[0] = false
arr[1] = "some other string"

But one of the nicer things about Swift’s arrays is how you can push values to the end of the array:

Instead of doing something like arr.push(10). You can just do this:

arr += 10

When, Swift knows the variable is an array it automatically understand the plus sign as concatenation.

Another neat thing is the for-in loop.

for val in arr {
    // do something with the value
}

Arrays in Swift also have the various functions we’re used to such, filter, map and reduce. But we’ll revisit those after we cover functions.

 Dictionaries (objects in javascript)

Dictionaries are probably the first things that’ll look different. Instead of using curly braces, you continue to use square brackets:

var occupations = [
    "Malcolm": "Captain",
    "Kaylee": "Mechanic",
]
occupations["Jayne"] = "Public Relations

Again, type inference will cast the type to of dictionary that maps String to String. Again using Any will leave us with a something that would need to be checked every time. So, when you need arbitrary values in Dictionaries you need to define it like this:

var obj:Dictionary<String, Any> = [
    "key" : 600,
    "another key" : 600,
]

Notice, that we have to type the word dictionary there. Also notice that the types are mentioned in angle-brackets (That deals with an advanced topic talked generics, will come to that later)

The interesting thing is that unlike javascript you can actually have dictionaries with non-String keys. For example you could have integer keys or even booleans.

Another thing to note is that you cannot use dot notation:

obj.key // BAD
obj["key"] // GOOD

The For-In loops work just as nicely with Dictionaries:

for (key, value) in obj {
    // do something with key and value
}

Now that is a step above what we can even do in Javascript!

(In the examples above, storing a function in an Any typed variable or storing a function in an array crashed Xcode. So I’m not yet sure if that is possible.)

 Conclusion

That completes our first dive into Swift from the angle of Javascript. We’ve barely scratched the surface, and we’ve not even started to talk about objects or even functions, but I think that was probably a lot to take in.

I want to stress the fact that though I’ve shown how you can use the ‘Any’ type to give you the flexibility you’re used to in javascript, you should by no means consider it to be a good practice. I’m doing this purely for academic purposes to explore how Swift can be used just like Javascript, even though that’s a bad idea. There is a reason Apple wanted Swift to be a strongly typed language, and it help you eliminate a whole class of errors.

Next time, we’ll take a short detour and look into optionals (Int? type anyone) and functions. Until then, show your support by leaving a kudos over there in the bottom right.

 
168
Kudos
 
168
Kudos

Now read this

The Next Step in the Life of Grunge.js

Grunge.js is what I can call my first major Open Source project. It launched without much fanfare. And it’s been stagnant ever since. It has seen little activity on Github, and almost no one has actually used it on a real project. Hell,... Continue →