Swift is like Visual Basic

I’m trolling a little with the title. But it is in a way. Let me explain myself.

My first job out of college at the end of the 90s was writing Visual Basic GUIs, along with C++ DLLs underneath them. That was quite a culture shock. I went from coding in Scheme and Haskell (or C and assembly, depending on the class I was taking), to writing basic. Basic! The kiddy language! The C++/MFC developers down the hall called us “paint monkeys”.

Except after a few months, under the patient tutelage of a couple of experienced devs who took my immature scorn for their language in their stride, I realized I actually enjoyed it. More importantly, I was productive in it. It was so much quicker to express business logic in VB than C++. I started writing my DLLs in VB as well, except when the problem demanded something more powerful, and when it did, it was the power of the STL it demanded rather than the C++ language. When I did have to go back and forth with C++, it was easy to switch – my VB and C++ interoperated so easily that I could pick my language on a class-by-class basis.

The interop was smooth for a few reasons. First, VB was compiled to binary executables,1 rather than bytecode to run on a VM. You could call C functions directly from your VB code, passing in the addresses of raw VB Integers or Arrays or Strings. This meant most of the Win32 API was directly available without any extra wrappers or native interface hoops to jump through.

VB was also reference counted rather than garbage collected. COM objects could be instantiated in C++ or VB and passed directly back and forth between the two languages. Most VB devs didn’t know about the ref counting, and it rarely mattered, but understanding the need to break reference cycles was our stock screening interview question.

Any of this sound familiar?

Swift’s easy interop with its platform’s older established language makes trying it out a fairly painless experience (or it should once the beta ends and the language and compiler stabilizes). My feeling is, once interested Objective-C developers try writing real code in it, and get accustomed to type inference and cleaner syntax and see some of the other benefits it brings like generics and functional paradigms, it’ll be a one-way trip. But without the downside of having to port old codebases.

The similarities with VB are only superficial. Just enough to give me a vague feeling of déjà vu. Swift is way more powerful, picking the best of the innovations in programming languages from the last 20 years. It does this while making the language as accessible as VB was. Despite their academic superiority, a new generation of developers are not going to adopt Haskell or Clojure or F# as their language of choice.

VB was still Basic of course. Those Begin, End, and Dim keywords are hard to live down. When Java took the Enterprise development world by storm, Microsoft did their knee-jerk reaction thing and shipped a garbage-collected Java/JVM clone.2 As a sop to the existing developers, they gave us Visual Basic.NET which was just a stupid cousin to C#.

Those that adopted it plunged themselves into a world of interop pain as they tried to make their CLR code work with non-CLR C++ (or even worse, tried to convert that to “managed” C++). The MFC developers that laughed at us paint monkeys stuck with C++, and plenty are still using it today. Microsoft can’t make up its mind what to back, continuing to make a hash of things with Silverlight or their weird HTML5 proposals for Windows 8 app development. I’m certain Apple won’t make the same mistake. In 5 years time, Swift will be the language you write apps in.

There are still some die-hard VB6 developers out there, god bless them, and Microsoft’s obsession with backwards compatibility means they can keep using the version of Visual Studio that was released in ’98. I gave up on Microsoft in disgust and switched to C++ on Linux. Part of why I’ve been enjoying writing Swift is because it reminds me of the old times. Now if only I could figure out how to be in my 20s again, I’d be set.


  1. Assuming you chose the compiled rather than the interpreted route. VB code could also be interpreted in a script mode. All our batch files were written in VB. 
  2. Yes, I know C# has been way more innovative than Java in recent years. But at the beginning it was just a pale imitation. 

Default Parameters in Swift – Dynamically or Statically Bound?

edit: after this post originally went up, the Swift dev team confirmed on the forums that default parameters should be dynamically bound. However, as of Swift 1.1, they’re still statically bound.

Quick quiz. What does the following code do?

class Shape {
  func draw(colour: String = "Red") { 
    println("\(colour) shape")
  }
}

let s1 = Shape()
s1.draw()

It prints Red shape, right? No argument supplied, so the default value of Red is used.

Ok what about this?

class Circle: Shape { 
  override func draw(colour: String = "Blue") { 
    println("\(colour) circle") 
  } 
}

let s2 = Circle()
s2.draw()

It should Blue circle. No surprises there. Again no argument, but the overridden function defaults to a different color and prints a different shape.

Ok finally, what about this?

let s3: Shape = Circle()
s3.draw()

Blue circle again, right? s3‘s static type is the base class, but it points to an inherited class. Polymorphism means the overridden function runs, so it should be just like the previous example.

If Swift bound default parameters dynamically, sure. But as of Swift 1.1, it behaves like C++,1 and you actually get Red circle. This is because parameters are bound statically not dynamically. Similarly, which overloaded function is chosen is also done statically – as seen in our series on Swift overload resolution

Why is C++ like this? Because default arguments are determined at compile time, not at run time. So while the correct function is applied, the default argument is looked up via the static type of s3, which is a Shape not a Circle. This could lead to some quite surprising behavior, which is why this is Item 37 of the Effective C++ book, which has more info on why it is this way (it’s related to run-time performance) and some workarounds to avoid it.


  1. I wrote the same code in C++ to double-check this and, holy cow, writing some simple C++ was painful after a week of Swift. 

Rundown of how each Effective C++ item relates to Swift

In this post we talked about how some of the items in Effective C++ might apply to Swift.

Many of the entries highlighted some limitations on the part of Swift, so some might think this post was a criticism of Swift.  Actually far from it – many of the items in Effective C++ are pointing out dangers of C++ where you can shoot yourself in the foot if you aren’t careful.  In most cases, when you look at the equivalent issue in Swift, it’s a non-issue.

For completeness, here is a rundown of every item, what kind of article it is, and how it applies to Swift:

Item Danger or benefit? In Swift
1: View C++ as a federation of languages Probably a benefit? Applies the same
2: Prefer consts, enums and inlines to defines Pre-processor dangerous! No preprocessor!  No reflection or lisp-style macros either tho.
3: Use const whenever possible Benefit let and mutating are there, but they only go so far. 
4: Make sure that objects are initialized before they’re used Danger Fully locked down, you have to initialize variables properly.
5: Know what functions C++ silently writes and calls Bit of both Swift writes some init methods automatically, though it’s nowhere near as potentially confusing as C++
6: Explicitly disallow the use of compiler-generated functions you do not want Benefit Doesn’t really apply to Swift
7: Declare destrutors virtual in polymorphic base classes Danger Not an issue, every method is virtual in Swift classes.
8: Prevent exceptions from leaving destructors Danger No exceptions in Swift!
9: Never call virtual functions during construction or destruction Danger Swift’s enforcement of initializing the super and all member variables helps prevent this problem
10: Have assignment operators return a reference to *this More of a convention No assignment (or copy constructors) in Swift
11: Handle assignment to self in operator= Danger No assignment (or copy constructors) in Swift
12: Copy all parts of an object Danger Still dangerous, but without as good tools to fix it (no copy constructors on structs!)
13: Use objects to manage resources Benefit ARC + deinit = same benefit!  So long as you’re careful about variable capture.
14: Think carefully about copying behavior in resource-managing classes Good advice Good advice applies, take it
15: Provide access to raw resources in resource-managing classes Good advice Good advice applies, take it
16: Use the same form in corresponding uses of new and delete Bit of both No need for explicit memory management in Swift.  That’s good, right?
17: Store newer objects in smart pointers in standalone statements Bit of both ARC means every pointer in Swift is a smart pointer, so all good.
18: Make interfaces easy to use correctly and hard to use incorrectly Good advice Good advice applies, take it
19: Treat class design as type design Good advice Good advice applies, take it
20: Prefer pass-by-reference-to-const to pass-by-value Bit of both Doesn’t really apply to Swift, though I wish it had proper const support.
21: Don’t try to return a reference when you must return an object. Danger ARC means every pointer in Swift is a smart pointer, so all good.
22: Declare data members private Benefit No public/private in Swift – yet.  It’s coming apparently.
23: Prefer non-member non-friend functions to member functions Bit of both Seems to apply the same to Swift.
24: Declare non-member functions when type conversions should apply to all parameters Bit of both Type conversion in Swift is very different, and rarely implicit, so this doesn’t really apply.
25: Consider support for a non-throwing swap Bit of both No exceptions in Swift, so your swap will definitely be non-throwing.
26: Postpone variable definitions as long as possible Good advice Good advice applies, take it
27: Minimize casting Danger Swift type casting is a lot safer/saner/more powerful than C++. 
28: Avoid returning “handles” to object internals. Good advice Good advice applies, take it
29: Strive for exception-safe code Danger Swift code is definitely exception-safe.
30: Understand the ins and outs of inlining Danger If compilers aren’t better at humans at inlining these days, something has gone wrong.
31: Minimize compilation dependencies between files Danger No more headers!
32: Make sure public inheritance models “is-a” Good advice Good advice applies, take it
33: Avoid hiding inherited names Danger Swift mandates you override a method if it has the same signature as a parent class version
34: Differentiate between inheritance of interface and inheritance of implementation Good advice Good advice (mostly) applies, take it
35: Consider alternatives to virtual functions Good advice I need to research this one…  It probably applies.
36: Never redefine an inherited non-virtual function Danger No non-virtual functions in Swift
37: Never redefine a function’s inherited default parameter value Danger Swift behaves the same right now but this has been declared a bug in the compiler
38: Model “has-a” or “is-implemented-in-terms-of” through composition. Good advice Good advice applies, take it
39: Use private inheritance judiciously Danger Private inheritance is a weird C++ thing, don’t sweat it.
40: Use multiple inheritance judiciously. Danger No multiple implementation inheritance in Swift.  Most people think this is the right idea.
41: Understand implicit interfaces and compile-time polymorphism Benefit Swift has compile-time polymorphism through generics much like C++ templates but they differ a lot (C++ templates are crazy powerful crazy complicated)
42: Understand the two meanings of typename Confusing, if not dangerous You know how I said C++ templates got crazy complicated?  This is part of that.
Item 43: Know how to access names in templatized base classes Confusing, if not dangerous I need to research this one… probably doesn’t apply.
Item 44: Factor parameter-independent code out of templates Danger Is it possible Swift generics use could result in code bloat?  Would really need some serious LLVM digging to find out.
Item 45: Use member function templates to accept “all compatible types.” Benefit Swift generics provide much of the same features.  Needs a bit more research.
Item 46: Define non-member functions inside templates when type conversions are desired Benefit Swift is not very implicit type-conversion friendly (opinion probably divided on whether this is a good or bad… I think bad, most probably think good)
Item 47: Use traits classes for information about types Benefit I need to research this one… Associated types and type constrains in Swift seem related to this.
Item 48: Be aware of template metaprogramming A bizarre C++ rabbit hole Probably best not to think about it.
Items 49-52: New and delete Various Swift does have UnsafePointer and malloc so maybe these are kind of topics are not as much of a non-issue as you might think at first.
53: Pay attention to compiler warnings Good advice Good advice applies, take it
Item 54: Familiarize yourself with the standard library, including TR1 Benefit Objective-C, like C++, has a huge library behind it, all of which can be used from Swift.  Question is, how much will be ported to a more Swift-like form?  Time will tell
Item 55: Familiarize yourself with Boost Beneft Boost is fantastic.  But early indications are, there’s a huge community of Swift developers looking to do similar things.

 

 

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? 

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.