Swift – two WTFs, a Fail and a Train Wreck

So Apple has a new programming language called Swift. You probably heard the news and read the Swift book so I wont bother repeating the good parts. I fell in love with nearly all of the new features (compared to C/Objective C) only from reading the Swift book BUT…

There are some foul spots in that sweet fruit. I gave this post the title „two WTFs, a Fail and a Train Wreck“ to sum up my gripes. Let’s start with the first WTF:

First WTF – Constant Arrays

In the Swift book it says:

if you assign an array or a dictionary to a constant, that array or dictionary is immutable

Ok, so far so good. Exactly what you would expect.

„…and its size cannot be changed.“

Wh..what’s that? I’m confused! Let’s read on.

For dictionaries, immutability also means that you cannot replace the value for an existing key in the dictionary. An immutable dictionary’s contents cannot be changed once they are set.

Ok, still as expected.

Immutability has a slightly different meaning for arrays, however. You are still not allowed to perform any action that has the potential to change the size of an immutable array, but you are allowed to set a new value for an existing index in the array.

WHAAAT??? Ok, nice optimization but aren’t that weird rules? I use a constant because I want it to be constant and not to have a faster variable. The implementation details should not shine through like that!

If you really want to have fun, try to wrap your head around the chapter „Assignment and Copy Behavior for Arrays“ in the Swift book. That mad endeavour is left as an exercise to the reader. Good luck!

The Fail – Method names

One of the greatly undervalued gems in Objective C is that there is no difference between the name of a method and the named parameters. It’s the same thing, and it can be rather poetic:

[url bookmarkDataWithOptions:NSURLBookmarkCreationMinimalBookmark
includingResourceValuesForKeys:nil relativeToURL:nil error:nil];

becomes this abomination:

url.bookmarkDataWithOptions(options: NSURLBookmarkCreationMinimalBookmark, includingResourceValuesForKeys: nil, relativeToURL: nil, error: nil)

urgh! „Options“ twice. Not good! There is no reason Swift could not have retained the elegant square bracket syntax of Objective C. None. Still they force us to cut the first part of our method name in half with a round bracket. Thank you so much.

Second WTF – Closure Syntax in a Method/Function Invocation

According to the Swift book you can call a function with a closure as a parameter like this:

reversed = sort(names, { (s1: String, s2: String) -> Bool in return s1 > s2 } )

or like this:

reversed = sort(names, { s1, s2 in return s1 > s2 } )

or like this:

reversed = sort(names, { s1, s2 in s1 > s2 } )

or like this:

reversed = sort(names, { $0 > $1 } )

or (in this case) like this:

reversed = sort(names, >)

or like this:

reversed = sort(names) { $0 > $1 }

Any questions?

The Trainwreck – Operator overloading

Whew that’s a big one! Obviously Chris Lattner and his team have not read Scott Meyers „Effective C++“ and „More Effective C++“ back then in the mid-nineties. Meyers makes some good cases against using operator overloading in C++, which is an especially hellish place anyway. But some cases are relevant beyond C++. Let me pick one, the boolean operator problem. Let’s assume we have two functions a() and b() that return a BOOL (or Bool). When we use a if-clause like this (in C)

if (a() && b())
{ /* do stuff */}

and a() returns false, b() will not be called. You can question this design decision by Kernighan and Ritchie from over 40 years ago but this behaviour has made it into many, many languages since then and Swift is no exception. Open a playground and copy and paste as we move along for maximum fun:

func a () -> Bool {
return false
}

func b () -> Bool {
println("b() was called")
return true
}

if a() && b() {
println("YES");
}
else
{
println("NO");
}

The console contains no surprise:

NO

Now let’s do some mean operator overloading with 3 components:

// a class
class Blah {
}

// an overloaded &&-operator
@infix func && (left: Blah, right: Bool) -> Bool {
return a() && right
}

// finally a func that returns a Blah object
func c () -> Blah {
return Blah()
}

Now let’s do the same if-clause but with c() instead of a():

if c() && b() {
println("YES");
}
else
{
println("NO");
}

Guess what happens?

b() was called
NO

Ouch! This behaviour is totally expected but just as surprising at the same time. It is not easy to tell what really happens from looking at the code
if c() && b()
That’s bad. It basically means you can’t trust the evaluation rules for operators anymore. That’s a train wreck! Especially for a language that tries so hard to avoid those kinds of problems.

Probably as you read this some kid out there thinks it’s a good idea to create and use a %%%-operator in his library. He might just have pushed it to Github. Who knows? Or imagine someone thinks how cool it was to port std::stream of the C++-STL to Swift, does so and your boss likes it? Nothing wrong with the STL back then when your boss still wrote code, right? RIGHT?

But joking aside: There are so few problems you can only solve with operator overloading but so many problem to have with it. It really makes you wonder: How could this get past the reasonable people in the team of Chris?

I’m at a loss here. I have no idea.

3 Gedanken zu „Swift – two WTFs, a Fail and a Train Wreck“

  1. If I didn’t get anything wrong in the Swift book (and I am really not a Objective C programmer, and not a programmer at all), Swift threats the first parameter for a method as a local name only, but all other parameters as both local AND external names (explained in „Local and External Parameter Names for Methods“).

    So, the function call described by you (in Objective C):

    [url bookmarkDataWithOptions:NSURLBookmarkCreationMinimalBookmark
    includingResourceValuesForKeys:nil relativeToURL:nil error:nil];

    would actually be called like this in Swift:

    url.bookmarkDataWithOptions(NSURLBookmarkCreationMinimalBookmark, includingResourceValuesForKeys:nil, relativeToURL:nil, error:nil

    This, for me looks pretty much the same as in Objective C, just without the square brackets and with dot notation.

    Or am I getting anything completely wrong?

    1. Argh. forgot the closing brace. Correct should be:

      url.bookmarkDataWithOptions(NSURLBookmarkCreationMinimalBookmark, includingResourceValuesForKeys:nil, relativeToURL:nil, error:nil)

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.