Mining “Effective C++” for ideas on Swift

Effective C++ by Scott Meyers is an amazingly good book. For me, it is to programming books like Watchmen is to comics – everything else I read, I feel disappointed that it isn’t as good. If you program C++ and you haven’t read it yet, get on it!

There are also several articles in the book that apply to any language – Item 28: Avoid returning “handles” to object internals, Item 32: Make sure public inheritance models “is-a.”, Item 53: Pay attention to compiler warnings. Even if you aren’t ever planning to write C++, maybe grab a friend’s copy and give it a skim.

There is a fair amount of material in there that is also applicable to Swift. Many features of modern C++ programming have fed into Swift – which isn’t surprising given Swift was born out of the LLVM team, and LLVM is written in C++. Here are a few items from the book, and how they might also apply to Swift.

edit: for the completists amongst you, this article gives a full rundown of every item in Effective C++ and how it relates to Swift. Note that many of the items are warnings on the dangers of C++, and for the most part these are all avoided in Swift.

Item 1: View C++ as a federation of languages.

Well, federation is a kinder word than hodgepodge. While Swift has been written from the ground up, so is a lot cleaner, it’s still similar to C++ in that it blends several styles (OO, generic, functional) together in one language, and you should be aware that different styles follow different conventions.

Items 3: Use const whenver possible

A welcome feature of Swift is the explicit distinction between let (const) and var (non-const) variable declarations. Using let by default, and var only when needed, is probably a good policy.

Swift also has the mutating modifier that acts like the opposite of C++’s const member function qualifier (i.e. you must specify it if you want to be able to alter internal state, rather than if you are promising not to):

struct MyStruct {
    var val = 0
    mutating func touch() -> Int { return ++val }
    func look() -> Int { return val }
}

let s = MyStruct()  // s is a constant 
s.look()    // fine - read-only
s.touch()   // compiler error

Sadly, that breaks down with classes, which don’t get to use the mutable keyword, so this compiles just fine:

class MyClass {
    var val: Int = 0
    func touch() -> Int { return ++val }
}

struct MyStructWithClassProperty {
    var val = MyClass()
}

let s = MyStructWithClassProperty()
s.val.touch()

This rules out using this feature to implement const-correct behaviour for more complex types (user-defined container classes, for example). Maybe someday it’ll be extended to cover more cases.

Item 5: Know what functions C++ silently writes and calls

Swift, like C++, silently writes some class functions for you. For example, if you don’t write an init() function for a struct or base class, but you do give all its properties default values, it will write a default initializer for you that takes no parameters. But if you do write another initializer, that takes parameters, you have to write a default one as well.

Item 12: Copy all parts of an object

Beware the seductive struct. It’s a value type, they say. It gets copied when you assign it, they say.

Well, to a point. As we saw in item 3, when you include a class as a property of a struct you leave some of those struct guarantees behind, and copying is one of them. If you were to make two copies of MyStructWithClassProperty above, they will both end up pointing at the same instance of MyClass.

Unfortunately, unlike in C++, Swift structs don’t get to implement a copy constructor. When a copy is made, it’s a shallow bitwise copy and the author of the struct has no programmable hooks to find out it’s happening. Instead you have to implement a .copy() method of your own and hope users call it.1 Maybe someday struct copy constructors will be added as a feature.

Item 13: Use objects to manage resources

Classes in Swift can implement a deinit method, that executes when the class is destroyed after all references to it are deleted. And with ARC, when that happens is a lot more deterministic than it is in Java and garbage collection. Maybe you can get some of that sweet RAII action C++ programmers are so keen on.2 The Apple docs even encourage you to do this, with an example about putting gold coins back in a bank.

But be careful! Try typing the following into a playground:

class Person {
    init() {
        println("Object is being initialized")
    }
    deinit {
        println("Object is being deinitialized")
    }
}


func deinit_demo() {
    var reference1 = Person(name: "John Appleseed")
}
deinit_demo()

and watch as you see no deinitialization logged to the console. This is presumably because the playground grabs references to everything to keep them around for playground-purposes. Fair enough, don’t use this pattern in the playground then. But you also need to watch out for the variables being captured by any closures,3 which will keep them around just by touching them, not even needing to assign them to another variable. Remember this if you’re ever trying to debug some mystifyingly resource-leaking code.

“But what about structs?”, you ask. They’re created on the stack, surely they get destroyed as soon as they fall out of scope. Well, sure, except first they can’t have a deinit method (again, maybe someday), and second, they can still be captured, so that’s no help.4

And finally, from More Effective C++:

Item 7: Never overload &&, ||, or ,

Or, in Swift’s case, totally go ahead and overload them, but make sure you do it right.

In C++, overloading || is dangerous because of the short-circuiting feature programmers are used to. Suppose you write the following:

if(cheapOp() || superExpensiveOp()) {
  doSomething()
}

Say cheapOp() returns true. That means the whole if statement can never not be true, no matter what superExpensiveOp() returns. So what’s the point of executing it? None, so in C, C++, Swift and most other languages with a ||, it won’t even get executed. If cheapOp() is true most of the time, that could give you a big performance benefit.

Except in C++, when you implement your own || operator, it’s just a regular old function, and all its parameters are fully evaluated before they are passed

The same would happen in Swift – but Swift has a feature, @auto_closure, that can be used to avoid that problem. Putting @auto_closure before a parameter means that statement gets wrapped in a closure for later execution.

So this:

if(cheapOp() || superExpensiveOp()) {
  doSomething()
}

gets rewritten as this:

if(cheapOp() || { return superExpensiveOp() }) {
  doSomething()
}

and in your implementation of the || operator you do the following

func ||(lhs: LogicValue, rhs: @auto_closure () -> LogicValue) -> Bool {
  // only if the left-hand side is false...
  if(!lhs) {
    // ...do you then need to execute the closure that wraps the second half
    if(!rhs()) {
      return false
    }
  }
  return true
}

A lot of people are excited about @auto_closure, as it enables some interesting possibilities – for example, a conditional logger that only executes expensive to-string operations if the log-level is debug, or an implementation of the ruby ||= assignment-if-nil idiom (read this article for more on that one). One of the reasons I’m excited about Swift is there are probably more of these to come as the language continues to evolve through it’s beta period.


  1. You could always talk about this issue as if it’s a deliberate feature of your collection class, like Apple does in the documentation for Swift Arrays. 
  2. Course, RAII isn’t nearly as useful when there are no exceptions waiting to pounce and pull the rug from under you at any moment, but still. 
  3. And obviously getting explicitly assigned to another variable, or being passed out of the function, but I assume you realize that. 
  4. When they are presumably whisked off to heap-land to live with the other reference-counted animals. Is Swift performing some secret autoboxing for this under the hood? 

Using Any to Store Numbers in Swift

In the last post we implemented an accumulator using generics, so it could handle either integers or floating point types.

But how about handling both in the same accumulator? In Paul Graham’s guidelines for submitting an accumulator, he says it needs to work

for any numeric type – i.e. can take both ints and floats and returns functions that can take both ints and floats. (It is not enough simply to convert all input to floats. An accumulator that has only seen integers must return integers.)

He then gives some example usage: 1

E.g. if after the example, you added the following code (in a made-up language):
x = foo(1);
x(5);
foo(3);
print x(2.3)
It should print 8.3.

But if you try to do this with our generics implementation, you will get a error when you pass in the final number. “Cannot convert the expression’s type ‘Int’ to type ‘Int’”, the compiler will say, which is a little confusingly worded given it’s a Double that can’t be converted, but what it means is it can’t convert what you passed to it’s Int parameter into an Int.

So I guess our example still isn’t valid for submission. What behaviour do we need? In Ruby, you can do the following:

irb> n = 1
 => 1
2.1.0 :002 > n.class
 => Fixnum
2.1.0 :003 > n += 2.2
 => 3.2
2.1.0 :005 > n.class
 => Float

The value n silently gets upgraded to a float. How can we do this in Swift? Well, there is an Any type that can hold any kind of type. But it’s not as easy as that. Just trying the following:

  func foo(var n: Any) -> (Any) -> Any {
    return { n += $0; return n }
  }

gets you the familiar compiler error about there being no overloaded += operator. But unlike when we had this problem with generics, this can’t be fixed with type constraints. Any doesn’t implement +=.2 In fact, Any doesn’t let you do much of anything except store a value and pass it around. If you want to maniuplate what’s inside, you must use a switch statement:

let a: Any = 1
switch a {
case let i as Int:
  // do appropriate logic when it's an Int
...
}

If we revisit our incf implementation, but adapt it to take and return Any, and upgrade an Int to Double by switching to identify them, we get the following monstrocity:

func incf(inout lhs: Any, rhs: Any) -> Any {
    switch lhs {
    case let i as Int:
        switch rhs {
        case let j as Int:
            lhs = i + j
        case let d as Double:
            lhs = Double(i) + d
        default:
            // what to do here?
        }
    case let d as Double:
        switch rhs {
        case let e as Double:
            lhs = d + e
        case let i as Int:
            lhs = d + Double(i)
        default:
            // what to do here?
        }
    default:
            // what to do here?
    }
    return lhs
}

What to put in for those default cases, where one of the types isn’t supported. Maybe throw an exception? Hahaha only kidding, Swift doesn’t have exceptions.3 The Swift way of handling this would be to allow incf to return a nil type.4 Users of foo then have to account for the possibility of an error. Let’s do that, and add an implementation of foo with our new incf:

func incf(inout lhs: Any, rhs: Any) -> Any? {
    switch lhs {
    case let i as Int:
        switch rhs {
        case let j as Int:
            lhs = i + j
        case let d as Double:
            lhs = Double(i) + d
        default:
            lhs = nil
        }
    case let d as Double:
        switch rhs {
        case let e as Double:
            lhs = d + e
        case let i as Int:
            lhs = d + Double(i)
        default:
            lhs = nil
        }
    default:
        lhs = nil
    }
    return lhs
}

func foo(var n: Any) -> (Any) -> Any? {
    return { incf(&n, $0) }
}

There are many flaws in this approach, but it does at least work with the example above now – pass an Int and then a Double and you’ll get a Double.

Pass a Float in though and you get back a nil. But adding Float to the already nasty switch statement will make it even nastier. If we wanted to extend incf to cover even more types (maybe numeric classes like a Rational or Decimal) it gets even worse. And if we want to implement a decrement function we’d have to replicate the whole statement.

There’s one more way to write the switch statement. Swift’s pattern matching can operate on multiple values together, giving us the following alternative to having to nest multiple switch statements:

func incf(inout lhs: Any, rhs: Any) -> Any? {
    switch (lhs,rhs) {
    case let (i as Int, j as Int):
        lhs = i + j
    case let (d as Double, e as Double):
        lhs = d + e
    case let (i as Int, d as Double):
        lhs = Double(i) + d
    case let (d as Double, i as Int):
        lhs = Double(i) + d
    default:
        lhs = nil
    }
    return lhs
}

Unfortunately, while this code is a little more succinct, and possibly less error-prone, it still suffers from the same problems if you tried to extend it to more types.

The next post will be about ditching Any in favor of a more type-safe approach to this problem.


  1. Note, he calls foo a second time in his example. Presumably he got a lot of duff submissions where people were using global variables to accumulate. 
  2. And before you try it, no, you can’t extend Any to try and implement +=. Or anything else for that matter, it’s unextendable. 
  3. This is a good example of how removing exceptions forces you to find a perfectly valid alternative in many cases. Exceptions were always discouraged in Objective-C except for truly exceptional circumstances, Swift took this one step further and did away with them entirely. 
  4. If you think the right thing to do is not add the number, you’ll hit a different problem. That means the default action should do nothing, but Swift insists you have some code there. So you have to write something that doesn’t have any effect. Feel free to get creative. No, I’m afraid a comment saying “do nothing” doesn’t count as something. 

An Accumulator in Swift, Part 2 – Using Generics

In Part 1 of this post, we wrote an implementation of Paul Graham’s accumulator problem in Swift. Here’s one of the versions:

func foo(var n: Int) -> (Int) -> Int {
  return { n += $0; return n }
}

This looks pretty similar to the Ruby version he gives:

def foo (n)
  lambda {|i| n += i }
end

Except there’s a problem. On his page of guidelines for submitting an example in a new language1 he points out it needs to:

[work] for any numeric type – i.e. can take both ints and floats and returns functions that can take both ints and floats. (It is not enough simply to convert all input to floats. An accumulator that has only seen integers must return integers.)2

In Ruby, this isn’t an issue because of the duck typing. But in Swift, if you try to pass a Float to foo, you’ll get an error. We’re going to have to use another feature to fix this – generics.3

First let’s try implementing incf using generics, so it can take an Int or a Float. We do this by defining a type parameter T in angle brackets after the function name, and then using that instead of the explicit Ints:

func foo<T>(var n: T) -> (T) -> T {
  return { n += $0; return n }
}

Oops, more compiler errors. “Could not find an overload for ‘+=’ that accepts the supplied arguments” again.

This is because not all objects have a += operator, so if you tried to use it with one of those, it wouldn’t work. Unlike in C++ templates, where you wouldn’t get a compiler error4 unless you tried to use incf with a type that was missing a +=, Swift requires you to restrict your types up-front.

The way you ensure a type will support the necessary member functions is by using Type Constraints. These are protocols you append to your generic type. For example, if you wanted to write a generic less_than function, you could use the Comparable type:

func less_than<T: Comparable>(lhs: T, rhs: T) -> Bool {
    return lhs < rhs
}

Only classes that implement the Comparable protocol can be used with the less_than function, and because they impelement this protocol they’re guaranteed to have a < operator.

The Swift standard library only defines 3 protols so far – Equatable, Comparable and Printable.5 They don't cover what we need, so we'll define our own. Let's call it, uhmm, Addable.

protocol Addable {
    @assignment func += (inout left: Self, right: Self)
}

Then, we need to declare that Int and Float support Addable by extending them with the new protocol:

  extension Int: Addable { }
  extension Float: Addable { }

Finally, let's try our generic function with the new constraint:

func foo<T: Addable>(var n: T) -> (T) -> T {
  return { n += $0; return n }
}

Now, if you pass in a Float to foo, it works.6. In fact, if you tag any type that implements += it will work for that type too. Try it with String.

Anyway, with this requirement covered, hopefully we can add Swift to the pantheon of powerful languages. Maybe one day they'll take new submissions to the page!


  1. These pages tell a story. First he was all hey guys, let’s get all the examples, this is cool! Then he’s like, no you numbskulls, read the problem, that’s not what it says! Eventually he gives up and tells people to stop emailing him. 
  2. Strictly speaking what we’ll implement still doesn’t cover this requirement, because the quote and the example following it implies it needs to be able to switch dynamically between integers and floating point halfway through. Read the next part for a solution to this. 
  3. I love generics. But then the first language they taught me in college was Ada, and after that I spent years in the C++ mines, so it’s not surprising. 
  4. The compiler error will be about 10 lines long and will fill you with hopeless despair. Concepts, something similar to Swift’s protocol constraints, didn’t make it into C++11. 
  5. They don't define Assignable. I guess that's considered so fundamental you can take it as a given. Presumably they're going to add a lot more standard protocols to the library over time, so keep an eye on that page. There are several more implemented but not yet documented – to see them, type import Swift into playground, and command-click it. 
  6. I was pretty amazed when it did the first time I tried this. 

An Accumulator in Swift

In an appendix to his article Revenge of the Nerds, Paul Graham suggests a problem to solve in a programming language to see how “powerful” that language is.1

The problem: Write a function foo that takes a number n and returns a function that takes a number i, and returns n incremented by i.

Also note,

(That’s incremented by, not plus. An accumulator has to accumulate.)

Solving this problem is one of the first things I try when learning a new language. This article will implement various versions this function in Swift, as a way to explore some of Swift’s features.

Here’s a first attempt. It’s very similar to the makeIncremetor function in the Closure section of the Apple Swift book, except adapted to match Graham’s definition of the problem:2

func foo(n: Int) -> (Int) -> Int {
  var acc = n
  func inc(i: Int) -> Int {
    acc += i
    return acc
  }
  return inc
}

Read that first line defining foo as: it takes a parameter, n, and returns a function, which itself takes an Int as a parameter and returns an Int.3

That returned function is a closure – a self-contained combination of a function and an environment of variables (in this case, just one, acc). Each time you then call that returned function, it adds the value i you pass in to acc to keep a running total, and then returns the latest total.

In case you’re not familiar with closures, here’s a short explanation of what’s happening.4 When declared, the function inc “captures” the outer variable acc, so instead of acc being destroyed when it falls out of scope, it sticks around and continues to be useable by the inc function. Note that if you call foo again, it creates a brand new inc function/acc variable pairing, starting from whatever n you just passed in. Think of this as similar to creating a new instance of a class with a member variable acc, initialized with n.

So, people have been enjoying comparing swift to other languages. I like Ruby, so let’s take the Ruby example from Graham’s list of canonical solutions to his problem.

def foo (n)
  lambda {|i| n += i }
end

Well that’s a lot more compact!5 Let’s look at why, and get our Swift example closer.

The Ruby example just captures and uses the input parameter n for its state variable. We can do this in Swift too, with the addition of the var keyword in front to allow it to vary (without those changes affecting the caller’s passed-in variable):

func foo(var n: Int) -> (Int) -> Int {
  func inc(i: Int) -> Int {
    n += i
    return n
  }
  return inc
}

Next, the inner function is anonymous, and returned directly. We can do that in Swift too. Unlike in Ruby, we don’t need to use a lambda keyword to declare an anonymous function:

func foo(var n: Int) -> (Int) -> Int {
  return { (i: Int) -> Int in
    n += i
    return n
  }
}

Now let’s look at all those type declarations cluttering up the place. Ruby doesn’t have them because it is duck typed. Swift on the other hand is strongly typed.6 But there is hope – some of them can be eliminated by Swift’s type inference. In the inner function, we already know the types of everything being passed in or returned, so we can leave them off and the compiler infers them from the context:

func foo(var n: Int) -> (Int) -> Int {
  return { i in n += i; return n }
}

Do we still need the declaration of i? If the types can be deduced, you can use $0, $1 etc for the arguments, and skip the in.

func foo(var n: Int) -> (Int) -> Int {
  return { n += $0; return n }
}

Finally, so long as a closure is just a single expression, you don’t need an explicit return – the result of the expression is automatically returned. This leaves us with something very similar to Ruby, where the last statement is always returned (in Ruby’s case, even with multi-line functions).

func foo(var n: Int) -> (Int) -> Int {
  return { n += $0 }
}

Except oops, no, that last one won’t compile. “Could not find an overload for ‘+=’ that accepts the supplied arguments” it says. That’s a little confusing, because the “argument” in question is actually the return type. In Swift, += doesn’t return a value7 (unlike in Ruby where almost every statement has a value8 and can be used on the right-hand side, even an if statement).

If you were thinking, I know, let’s override += to return a value, nope Swift won’t let you do that.9 Also, you’re the reason I hate other people’s code. To get inspiration for an alternative function, let’s look at the lisp example from the canonical list:

(defun foo (n)
  (lambda (i) (incf n i)))

And here is an implementation of that function:

func incf(inout lhs: Int, rhs: Int) -> Int {
  lhs += rhs
  return lhs
}

Note the use of the inout keyword to indicate that the changes made to this parameter affect the variable passed in by the caller, unlike with var.

Since our new function returns a result, we can now use it to implement a single-expression closure:10

func foo(var n: Int) -> (Int) -> Int {
  return { incf(&n, $0) }
}

Swift requires you to put an & in front variable when passing in an inout parameter, which is nice as it means you can’t accidentally miss the possibility of side-effects.

That’s probably as far as we can go. It’s pretty similar to the Ruby version at this point. Except… we didn’t quite solve the stated problem. To find out why, read on to Part 2 of this article.


  1. If you take issue with this as a measure of language power, take it up with Mr Graham.#160;
  2. If you’re eyeing foo suspiciously, and wondering why it isn’t called, say, makeAccumulator, I agree with you. 
  3. I’m not wild about the Swift syntax for type definitions of functions returned from functions. I know it’s completely unambiguous if you read it from left to right but it makes me nervous when I look at it. I don’t have any better proposals, either. 
  4. Those who are familiar – please be gentle with me and my explanation! 
  5. Note I said compact, not neater or cleaner or more expressive. But I happen to think it’s those things too. 
  6. Terms like strong or duck typing are not rigorously defined, but people can get very emotional about it when they think they’re being used incorrectly. Please email Casey. 
  7. I do wonder why they decided to not have assignment return the value of the left-hand side. Seems like this is a legit use case. I guess maybe they they thought it was too side-effecty to change a value while also using it? But if you’re going to do that, go all the way and ban ++i from being used on the right-hand side of expressions – but that would probably lead to the C guys assaulting the castle with torches and pitchforks. 
  8. That’s right, almost everything. Not everything. Grrr. Though, otherwise, I really like this language feature. 
  9. Interestingly, it will allow you define += return a value when you write it for your own classes. This is probably not a good idea. 
  10. Yes I’m aware writing a two-line function just to compact less code elsewhere is a bit silly, but give me a break, we’re just experimenting here. Plus I think the lisp “build up the language to meet your problem” thing is a nice idea.