A JavaScript Developer’s Take on Apple’s Swift

Stan Bershadskiy

June 24, 2014
swift-hero_2x

This year Apple succeeded in making their 2014 WWDC one of the key talking points throughout their entire developer community. The event’s keynote contained what many analysts predicted, a new point release of OS X (10.10) as well as a new major release of iOS (8). However, Apple decided to treat developers to a brand new programming language that they hope will supplant Objective-C, Swift.

Hello, World Swift

Apple wanted a language that would be modern, fast and safe. To anyone who has done a bit of Objective-C in the past, hearing the term “modern” should be music to his or her ears. Apple has delivered in that regard, with adding plenty of syntactic sugar onto the language. It is evident that they were inspired by modern scripting languages such as Ruby, Python, Groovy and of course JavaScript.

I’m now going to put my JavaScript goggles on and give you my first reactions of things I like, hate, and don’t care too much about when it comes to Swift. Disclaimer: I am by no means an expert in Swift. I do not think anyone outside of those who worked on the project is at this point, so I may draw some invalid conclusions. Please feel to correct and/or debate me on them in the comments below.

The Good

Syntax

One of my biggest pet peeves with Objective C is that any kind of source code written in the language looks like a tornado of non-alphanumeric symbols (reminds me of Perl & PHP).

In contrast, Swift looks very elegant and minimalistic, like the modern scripting language it’s trying to be. Just the little simple things like invoking functions with (), or declaring a string variable using “” is a pleasant sight.

Strings

One of my favorite features of Swift is “String Interpolation” (a.k.a templating). Using () you can build a string using constants, variables located in scope as well as the results of expressions.

let constantString = "Hello";
let intValue = 1;

var helloWorld = "\(constantString) World; 1+1 = \(intValue + 1)";

Simple definitions of Arrays and Dictionaries

Now you can define arrays and dictionaries (key/value maps) using shorthand operators ([], [:]).

// Arrays
var emptyArray = String[]();
var emptyArrayAlt:String[] = [];
var myArray = ["foo","bar","baz"];
        
println(myArray[1]); // returns bar

// Dictionaries
var emptyDictionary = Dictionary();
var carMakesModels = [
    "Honda"  : ["Civic", "Accord", "S2000"],
    "Toyota" : ["Corolla", "Camry"]
];
        
println(carMakesModels["Toyota"]); // returns [Corolla, Camry]

Iteration

Looping an array or dictionary has become greatly simplified compared to Objective-C. Especially for dictionaries you no longer need to call the objectForKey method as you now specify a tuple for your key and value in the iteration statement.

// Looping an array
for value in myArray {
    println("Value is: \(value)");
}

// Looping a dictionary
for (key,value) in carMakesModels {
    println("Make: \(key) and Model: \(value)");
}

Functions

In Swift you can now write functions as you would a function expression in JavaScript. One of my other favorites is that now your function can return a tuple. You no longer need the overhead of defining an array, dictionary or some sort of data structure when you want to return multiple values. It is similar to returning a plain JavaScript object, and you can interact with it as one.

func getValues(input:String) -> (result:String, count:Int, valid:Bool) {
    var result = input;
    var count  = countElements(result);
    var valid  = true;
    return (result, count, valid);
}

var values = getValues("Hello World");
println("\(values.result) \(values.count) \(values.valid)");

Classes

Defining classes is vastly improved in Swift. It is now far simpler and more intuitive, especially when extending other classes.

class Car {
    let make:String;
    let model:String;
    let price:Int;

    init(make: String, model: String, price:Int) {
        self.make = make;
        self.model = model;
        self.price = price;
    }
    
    func drive() {
        println("Driving");
    }
}

class SportsCar: Car {
    let isExotic:Bool;
    
    init(make: String, model: String, price:Int, isExotic: Bool) {
        self.isExotic = isExotic;
        super.init(make: make, model: model, price: price);
    }
    
    override func drive() {
        println("Driving fast");
    }
}

var toyotaCamry = Car(make:"Toyota", model:"Camry", price:20000);
toyotaCamry.drive(); // prints "Driving"

var ferrari458 = SportsCar(make:"Ferrari", model:"F458", price:200000, isExotic: true);
ferrari458.drive();  // prints "Driving Fast"

REPL and Playgrounds

For any developer working with a scripting language a REPL is invaluable, especially when toying with ideas. The conventional compile & run cycle does not allow for rapid experimentation, thus the addition of a REPL and live-reload Playgrounds are great things to have.

The Bad

Can not change type after variable assignment

Swift allows you the privilege of not having to define the type of a variable. However, once you assign a value, the variable is locked in to that type. This is unnecessarily confining in my opinion.

var myValue = "FOO";

myValue = 5; // Compile-time error

Conditional Statements do not evaluate expressions

A great thing about JavaScript is that it will evaluate objects and literals as booleans inside a conditional statement. In Swift, these expressions must explicitly return a boolean value. For those who used to writing JavaScript will find this cumbersome.

var intValue = 5;

// Works
if(intValue > 0) {
    println("Hello World");
}
        
//Fails
if(intValue) {
    println("Hello World");
}

Optional semicolons and parenthesis in conditional statements

Call me old school but I like to explicitly end my statements. This is also a topic of contention in the JavaScript community. I also like to put parenthesis around if conditionals. I believe it helps readability and can lead to a lack of uniformity across code bases.

Optional Values

The Swift programming guide did a poor job describing this feature; this link does a much better job of it. I do not like the fact that you cannot assign nil (null) to a non-optional value (most of the variables that will be created).

var optionalValue: String? = "FOO";
println(optionalValue); // FOO
optionalValue = nil;
println(optionalValue); // nil
optionalValue = "ABC";
println(optionalValue); // ABC

var nonOptionalValue = "FOO";
nonOptionalValue = nil; // Error

The Superfluous

Parameter name aliases in functions

In Swift you can write an alias to a parameter that will be used inside the function. This alias is different than the parameter name used when invoking the function. Why not just pick one correct name? This is a code smell in my book.

func calculate(arbitraryValue value:Int) -> Int {
    return value * 2;
}

Typealias

I understand the reasoning behind this, but I believe this could have been implemented in a much simpler fashion. Why not do it as you would in JavaScript and assign a reference to a variable (or constant in this case)?

typealias UnsignedInt = UInt16;

Summary

From a JavaScript developer’s perspective Swift is a leap in the right direction coming from Objective-C. Like with any first impression of a new language, there are some things that just do not sit right. I feel the language is in an identity crisis caused by its own fundamentals. It tries to be modern but many of the features are strained by its desire to be safe for the developer. In trying so hard to be modern it makes some great deviations from the beaten path of procedural programming, but even those moves are hindered by its overbearing protection and inflexibility. I see Swift as a complete replacement of Objective-C and do look forward to seeing many existing libraries (primarily Cordova) being rewritten in Swift in the not-too-distant future. With only four years of development Swift is still immature. However with Apple’s full support as well as an emerging developer community we should expect promising improvements in the coming months and years.

Further Reading


  • Chris

    “Can not change type after variable assignment” and “Conditional Statements do not evaluate expressions” are the result of a strong-type system. You may as well argue against C# or Java at those points…

  • amezghal abdelilah

    for parameter name alias in function, you can use

    func calculate(#arbitraryValue :Int) -> Int {
    return value * 2;
    }
    if you add # before the param name, the name will be used for both…

    Ah and you forgot to mention the perfect operators overloading implementation in the “The good” section…

  • Peter

    I will call you Old School! :)

    After many years of writing a lot of JS and Lua code I can tell you that there is no added value for code readability in having mandatory parenthesis in if statements and semicolons at the end of statements.

    In fact code I find code without parenthesis and semicolons much more readable.


What We Do

We’ll work closely with your team to instill Lean practices for ideation, strategy, design and delivery — practices that are adaptable to every part of your business.

See what Modus can do for you.

We're Hiring!

Join our awesome team of dedicated engineers.

Loading...