What learning Swift looks like: Arrays

I’ve spent the last few months working on a new iOS application in Swift, Apple’s new language for Mac and iOS development.

I was constantly jumping into an Xcode Playground to play, test and break specific parts of the syntax. Going back through those snippet, while adding some commentary, was a good opportunity to show my learning process as I moved from scripting languages (JS and Python in particular) to type safe compiled language.

So for part one in this series I give you, Arrays.

Arrays, or lists or something..

Digging into how a language handles it’s built in Array type has always been interesting to me. It’s such an important part of a language that it often impacts what becomes idiomatic idiomatic code in language. Swift takes a relatively classical approach to the Array, but there were some interesting tricks to be found.

let x = [1, 2, 3]  
x.append(4)  
$ Immutable value of type ‘[Int]’ only has mutating members named ‘append’
let y = x.removeAtIndex(0)  
$ Immutable value of type ‘[Int]’ only has mutating members named ‘removeAtIndex’

Okay, I can’t add or remove from this array because Swift x is immutable (the let part). Immutable variables are at the core of the language so there aren’t MutableArray and ImmutableArray types like many languages have. I love this. The more that I use Swift the more I fall in love with immutable variables as such a core concept. I am so very glad that it has made it into the ES6 specification.

var x = [1,2,3]  
let y = x.removeAtIndex(0)  
$ 1
x  
$ [2,3]

There we go.

let t = [1,2,3,4] + [5,6,7,8]  
t  
$ [1,2,3,4,5,6,7,8]

Very happy that + is used for concatenation and not some horrible mess like JavaScript or a boring type error.

let z = [1, 2, 3, 4]  
z[0…2]  
$ [1, 2, 3]

Okay, that’s the syntax for an array slice. I’m glad there is some sugar for this. Let’s play some more.

let t = [1,2,3,4,5,6,7,8]  
t[0…20]  
$ bork

Hmm, there aren’t 20 items so it doesn’t want to give me anything. Strangely, Xcode doesn’t like this at all. It won’t give an error but it’s an Array Index error when you attempt to compile it.

let max = t.count < 5 ? t.count - 1 : 5  
t[0…max]  

Meh. It’s long, but it works. I haven’t found anything better yet either.

let z = [1,2,3]  
z.last  
$ 3
z  
$ [1,2,3]
z.pop()  
! ‘[Int]’ does not have a member named ‘pop’

Wait, I can get the last element but I can’t remove it? Not without supplying an index? That’s annoying. I wonder if I can fix that…

extension Array {  
    mutating func pop() -> T {
        return self.removeAtIndex(self.count - 1)
    }
}

One of the nicest features in Swift is the ability to extend any class with properties or methods using the extension syntax. In this case I also added mutating to the func declaration so that it’s only usable on mutable instances. The rest is easy, pull the last index off and return it.

Let’s try that new pop function we added to all Arrays

let z = [1, 2, 3, 4]  
z.pop()  
$ Immutable value of type ‘[Int]’ only has mutating members named ‘pop’

Ugh, I forgot.

var z = [1, 2, 3, 4]  
z.pop()  
$ 4

Nailed it.

Hopefully that code gives you a taste of what the Array can do. Next round is going to cover the static typing parts of Swift in a lot more detail.

The holistic view

The one area that is consistently lacking in node web application code is the organisation of internal dependencies.

I read a lot of code. Code reviews, research to find solutions to bugs and (sadly all to often) to simply understand a project that has confusing or incorrect documentation. Since moving my web application stack to Node I've spent more time than ever reading other developer's code.

Node applications, by virture of its require system, take a very modular and minimalist approach. The community likes to focus on many small, singular-focus, modules that are well tested (ahem). Applications join them together to create a Megazord. That’s great. The problem is the how of joining is not very well directed by popular frameworks.

I use express as the base for my web projects. Over the last few years I've often dug into web application projcets to see how they're structured. With that research, and a few live applications under my belt, I've found where the most common patterns are lacking as well as some helpful solutions.

From the bottom to the top

At the core of every express app you have your application instance. This object is used to add route listeners, configure template modules and listen for requests.

// index.js
var express = require('express');  
var app = express();  
app.listen(3000);  

This code is found within the index.js of nearly every single express application I've come across. Next to this is where they diverge: the configuration of your application's routes which are called to generate the responses to user requests. Adding a route requires access to the app instance. Route configuration is done by calling HTTP verbs (e.g. get and post) with a URL expression (e.g. /page/:slug) and a handler method. The two most common approaches I see follow on from eachother:

The "Don't worry about it" pattern

This "pattern" has you place all routes within an index.js file. There's a good chance that all the controller logic is there too.

// index.js
var express = require('express');  
var app = express();  
app.get('/', function (req, res) {  
    res.send('Hello world!');
});
app.listen(3000);  

There is no seperation of routes from the app, nor controllers from the routes. It works and it's easy to see everything when small in scope, but this file will get massive as the application scales and there is no clear organization of routes for developers to work with. Debugging is a nightmare, and testing is next to impossible. Luckily most applications do better, without much work.

The "My First Rodeo" pattern

We know that nodejs is all about modules so it's often that applications create a seperate route file (i.e. module) which is passed an application object to generate route listeners. Taken one step further each controller (or route method) is placed into it's own own file to keep our project structured and easier to read, test and maintain.

// index.js
var express = require('express');  
var app = express();  
var routes = require('./routes')(app);  
app.listen(3000);  
// routes/index.js
var hello_route = require('./hello'); // contains a single route per files  
module.exports = function (app) {  
    app.get('/', hello_route);
};
// routes/hello.js
module.exports = function (req, res) {  
    res.send('Hello world');
};

This approach is much better. Each route is clearly defined and seperated from any others and your routes are attached in isolation of your application runner. Here, you can "read" the structure of an application without having to dig into it's code: a massive plus for increasing developer maintainence effeciency. You can also change and test individual components.

I'm happy with this setup, it's the most common I see however it requires that the application dependency (app) is manually passed to every single module that requires it. This is more painful than it might appear. If it was just your route/index.js module, fine. What happens when you need to set environment configuration that the databse needs?

var db = require('./lib/db')(app);  

You now have a dependency on your app instance in every single module that requires your db...

Apply this to your logger module, your foursquare library and you will be forced to manually move that singleton around every part of your application. Not to mention the pain when 3 months into development a module that never required it now does. 148 files referencing it? Ouch. Pain point.

Why don't we modularize our application?

The "nailed it" pattern

This approach creates an application singleton which isn't passed, but requested, where needed. Exactly like you would with any external module.

// index.js
var express = require('express');  
var app = express();

module.exports = exports = app; // nailed it

app.set('routes', require('./routes'));  
app.listen(3000);  
// routes/index.js
var app = require('../');  
var hello_route = require('./hello');  
app.get('/', hello_route);  

The application doesn't need to know anything about where it might be used, nor does a module need to be restructured when it does require your app instance. You follow the standard require pattern! This has huge benefits for configuration and modularizing your code. You can now write code like this throughout your application:

// lib/database.js
var app = require('../');  
var mongo = require('mongo');  
mongo.connect(app.get('db-url'));  
module.exports = exports = mongo;  

The single biggest improvement is allowing environment configuration to be easily managed and used anywhere in your application. There are good examples you can check out implementing this pattern in real projects.

In practice, when using this pattern (as those examples do) you often see the express intance wrapped within a custom application instance. This allows the abstraction of express from your application code to decrease your dependency on the framework and its internal systems. It should nearly always make sense to do so within your own project.

If you're not following this pattern, I highly recomend given it a try to see where it can simplify your applications internal dependency management.