Thursday, June 26, 2014

Why Does Apple's Swift Use Pascal's Variable Declaration Syntax?

I'm extremely excited about Swift. I’ve read The Swift Programming Language and Using Swift with Cocoa and Objective-C. Both were very well written and explained with clear examples what you can do with Swift, but left out information I'm dying to know: why?

Not why does Swift exist, I think it's pretty obvious that Apple's Objective-C, which along with AppKit dates to 1988, was showing its age. C itself is from the late 60s, early 70s. A language purportedly as fast as C with non-garbage collected but automatic memory management (mostly) and protection against common programmer mistakes has been needed for a while now. No we need the why of Swift's design.


Why was Swift Designed the Way It Is?

That's the missing link for me in both Swift books. Some might argue that explaining why Swift is designed the way it is requires a third book. I would have found it much easier to digest some syntax design if those decisions had been explained inline. Especially when that syntax is largely used from another non-C like language.

For example, Swift uses Pascal's variable declaration syntax, but not its constants declaration syntax.

Why?

Pascal Variables
var one = 1;
var two: Integer = 2;
Swift Variables
var three = 3
var four: Int = 4
Pascal Constants
const five = 5;
const six: Integer = 6;
Swift Constants
let seven = 7
let eight: Integer = 8


Why Happened To Objective-C Without the C?

If the goal was Objective-C without the C, then the up to Xcode 6 Beta 2 Swift syntax seems kind of far way from that. Chris Pietschmann has a good Basic Comparison of C# and Apple Swift Programming Language Syntax. I haven't used C# in a few years, so this was a nice refresher:

C# Variables
var legalAge = 18;
string firstName;

C# Constants
const int legalAge = 18;

Looks a lot more like Objective-C without the C. There is a rough edge there. C# didn't have a var keyword in early versions. So explicitly typed variables start with the type name, not var. Var is only for method local scope implicitly typed variables.

An important idea here is that C# looks an awful lot like C++ without the second +. C++ Intrinsic type variables and constant declaration looks identical to C# (ignoring C++ 2011 additions since it post dates core C#, and C#'s var keyword). The main difference is C# class variables have no pointers.

Here are a few possible versions of an alternative universe variable declaration syntax in Swift following C# and C++, but would sand away the C# var rough edge:

Swift Alt 1
var:String lastName = "Kirk"

//Traditional C constant keyword
const:Int rulesBroken = 4

//A new C like constant keyword whose length matches var
con:Int rulesBroken = 4
Swift Alt 2
var String lastName = "Spock"

//Traditional C constant keyword
const Int rulesBroken = 4 


//A new C like constant keyword whose length matches var
con Int rulesBroken = 4


What I like about these examples is the connection of type with the kind of variable. It makes the code more readable as a sentence to me:

//With type
variable of type String named Kirk

//Without type
variable named Kirk
Instead of Swift's current syntax: 

//With type
variable named Kirk of type String

//Without type
variable named Kirk
I introduced a new constant declaration keyword con anticipating that the use of let was due in part to wanting length matched keywords for variables and constants. I dislike let which reads weird to me in non-declaration cases (more on that in another post) and it's meaning compatible with JavaScript. Perhaps there's a compiler land reason why name:type is better, I don't know because it's not explained.

Maybe there is an across Swift consistency reason for the use of keyword(s) name:type = default


Unified Theory for Swift's Variable Declaration Syntax

Swift & LLVM lead designer Chris Lattner is obviously a C++ wizard since LLVM is written in it. He must also have seen and likely used a lot of C# since he was a Research Intern at Microsoft's Research lab. He didn't adopt C# or slightly modified C++ variable declaration syntax. Why not?
In the absence of an official explanation, I have a theory. Look at function and closure declarations in Swift:

Swift Functions and Closures
//function
func backwards(s1: String, s2: String) -> Bool {
    return s1 > s2
}

//closures
reversed = sort(names, { (s1: String, s2: String) -> Bool in
    return s1 > s2
})
By default all parameters are constants, so let is ommitted. What remains? In the majority case, name: type.

My theory is that Swift uses the Pascal variable declaration syntax to make reading functions and closures with constant parameters easier for people.

At worst, the the function & closure parameter declaration syntax can expand to this keyword(s) name: type. Examples:

//keyword(s) name: type

func fullName(var middleName: String) -> String

func lastName(inout lastName: String) -> String

{ (firstName: String) -> String in return firstName.description }
Contrast with a couple functions in C#

void addReferenceType(SomeRefType refType) {
    // do something
}

void SwapStrings(ref string s1, ref string s2) {
    // The string parameter is passed by reference. 
    // Any changes on parameters will affect the original variables.

    string temp = s1;
    s1 = s2;
    s2 = temp;
    System.Console.WriteLine("Inside the method: {0} {1}", s1, s2);
}
C# can make the position of the parameter name position 2 or 3 after each comma, but can result in some method signatures that are possibly more jagged than Swift.


Why Else Would Swift Use Pascal Variable Declaration Syntax?

If the Pascal variable declaration syntax isn't for the compiler or it really doesn't make functions & closures more readable, I don't know why it was chosen. Personal taste? Just to be different than C#?

Obviously the LLVM and Swift team at Apple are brilliant people. I have immense respect for the amazing work they've been doing to modernize the platform. But it seems like there was a more familiar path from Objective-C to Swift for variable declaration and it wasn't taken. I'd love to know why.