Introduction to Swift (for C#.NET developers)

Introduction

I’m a .NET developer and I love Microsoft! Why should I care about Swift?

The Swift language is gaining wide adoption at an accelerated rate. According to the TIOBE Index for 2015, Swift increased quite a bit in popularity in just one year (from 25th place in 2014 to 14th place in 2015). It has already surpassed Objective-C (the defacto iOS programming language) which is extraordinary considering it was only released just over a year ago in September of 2014.

This is all well and good for iOS developers. But how about Microsoft developers? Does this matter to me? The answer is…it might. While it likely won’t be necessary for web developers to get involved with Swift, if you are an applications developer (particularly mobile apps), at some point, you will want to know your way around Swift. Native apps are still the ideal choice for companies wanting to give their customers a seamless experience. Web apps, no matter how much we want them to be, are still not the ideal choice for mobile devices.

Also, considering that Microsoft only commands less than 3% of the smartphone marketshare, most mobile apps will almost certainly NOT be targeting Microsoft’s platforms first.

What about frameworks like Xamarin (.NET for iOS)?

This blogger has posted a good synopsis of pros and cons of using Xamarin after almost a year of “real world” use. My first observation after reading his blog was the list of cons (11) was over twice as long as his list of pros (5). That is not to say Xamarin is not worth it (in fact, the author plainly states that it IS worth it, for him at least).

The problem with Xamarin (and frameworks like it), based on my own research, is that it adds a layer of complexity on top of something that is already complex enough. While it tries to make things simpler (or more familiar), it often exchanges one problem for another. In addition, the problems that are introduced by a framework like Xamarin are often harder to debug or to find a legitimate fix for. When bugs crop up in core frameworks (like Swift bugs, Cocoa, etc.) they will generally be fixed much faster than bugs in a third party framework.

Overhead is another concern. Typical Xamarin apps (vs. their native equivalents) are several megabytes larger. One example of this is here, where their test app was 12.1MB for the Xamarin version vs. 644KB for the native iOS version. This can be a deal breaker for some. Speed appears to be less of an issue, with the exception of load times being a little longer. In fact, in some cases, Xamarin can actually be faster.

Xamarin’s primary appeal is the cross-platform nature of it (build apps for all platforms). But if you want to create an app that is any more complex than a “Hello World” app, you will typically have to still work with the native frameworks (like Cocoa in iOS, for example) to get what you really want. The primary advantage at that point is just that you get to use C# instead of Swift. Objective-C was/is still horrible, and being able to use C# over that sure sounds appealing. But Swift really negates much of those language gripes and offers an option to C# developers to jump in head first into iOS development.

Swift is now open source. What does that mean for me?

It means that Swift is only going to get bigger and more popular. We will more than likely see several implementations of Swift.NET cropping up in the next few years. In addition, Swift is already building on Linux (since it was open-sourced). Don’t be surprised to see Swift being used at some point as an alternative to Java or C# on the server side.

C# vs. Swift

If you are a developer who is familiar with any of the C-like languages (C#, Java, etc.), you should have little difficulty understanding Swift. Aggravation for the developer will come in the form of the semantic differences between the two languages, particularly with routine things such as declaring functions and variables, using property set/get, etc.

For the purposes of introducing Swift, I will not be covering exhaustively each and every difference of the languages. For the sake of tradition, I will be reviewing a “Hello World” example. In addition, I will make an effort to cover the distinct advantages and disadvantages between the two languages.

If you are interested in viewing a comprehensive list of the detailed differences between the two languages, this and this, both written by Chris Pietschmann are both good articles.

HelloWorld – Our First Class

HelloWorld.cs

// C#
public class HelloWorld {
    private string _message;
    
    HelloWorld(string message) {
        this._message = message;
    }
    
    void display() {
        System.Diagnostics.Debug.WriteLine(_message);
    }
    
    public string Message {
        get {
            return _message;
        }
        set {
            _message = value;
        }
    }
}

HelloWorld.swift

// Swift
public class HelloWorld {
    private var _message: String
    
    init(message: String) {
        self._message = message
    }
    
    func display() {
        debugPrint(_message)
    }
    
    public var Message: String {
        get {
            return _message
        }
        set {
            _message = newValue
        }
    }
}

As you can see, at first glance, both languages offer a very similar look-and-feel. Both make use of curly braces and parentheses in similar ways, both languages offer access modifiers, and both are object oriented.

Where they are different is in the details. For example, variable declarations are reversed in Swift. That is, the data type in the declaration appears at the end, after the variable name, instead of before. While there doesn’t appear to be a distinct advantage of one over the other, there is a certain level of consistency in Swift over C#. For example, take these two code snippets in C# and Swift…

// C#
HelloWorld a;
var b = new HelloWorld("hello");
// Swift
var a : HelloWorld
var b = HelloWorld(message: "hello")

In the example above, Swift is clearly more consistent. Variables are always declared with “var” as opposed to C#, where “var” is only used for implicitly declared types. The data type of the variable, whether implicit or explicit, happens after the variable name. Also, implicitly defined (use of “var”) variables in C# can not be used in a class members. There is no such restriction in Swift. The above example can be used inside of a function block as well as in a class definition.

The use of the parameter name “message” in the constructor is required in Swift by default. You can override this with the use of “_” before the parameter name, but this is not always ideal (or obvious). For other functions, by default, only the first parameter does not require a name. As a C# developer, I have found the concept to be annoying, for the most part.

There are a few other minor differences worth pointing out. First, you will notice the constructor in the Swift example is named “init”. Constructors in Swift are always named “init”. Contrast this to C# where it must be named identically to the class. Swift seems to have the advantage here over C#, since renaming the class would only require changing the name of the class definition, and not all of its constructors as well.

Swift’s choice of “newValue” instead of “value” for property-sets seems…less smart. That said, if you are not a fan, you can override this name by specifying a parameter name after the “set” clause…

// Swift
set(value) {
    _message = value
}

Next, you will notice the complete and utter lack of the use of the “new” keyword. In Swift, it does not exist. Personally, I am a little torn on this omission from the language. While “new” is technically redundant, it does offer clarity as to whether you are calling a function or instantiating a new class. In the HelloWorld.swift example above, when assigning the variable “b” to ‘HelloWorld(message: “hello”)’, there is no way to know, without looking at the definition of HelloWorld, whether it is a class or a function.

Finally, you will notice the lack of semicolons (;) in the Swift code. In Swift, semicolons can be used in the same way as other C-like languages, but they are optional. The only exception to this rule is if you have multiple statements on a single line, in which case semicolons are required. However, the opposite is not true. You can have a single statement span multiple lines without the use of a semicolon.

Anonymous Types

Both Swift and C# have anonymous types. That is, the ability to create an object definition without creating a formal class. However, Swift’s anonymous types are generally much more powerful and flexible. Here is an example of an anonymous type in both languages…

// C#
var myAnonymousObject = new {myInt = 5, myString = "abc"};
myAnonymousObject.myInt = 2;   // Error - Read only
// Swift
var myAnonymousObject = (myInt: 5, myString: "abc")
myAnonymousObject.myInt = 2    // OK - Not read only unless using "let" instead of "var"

C#’s anonymous types are limited as they can only be read-only members that are set during initialization. Swift has no such limitation. Also, returning anonymously typed objects from a function in C# compared to Swift is not without its headaches…

// C#
public dynamic returnAnonymousObject() {
    var myAnonymousObject = new {myInt = 5, myString = "abc"};
    return myAnonymousObject;
}
...
var a = returnAnonymousObject()
var b = a.myInt    // "myInt" resolved at run-time (because of "dynamic")
// Swift
func returnAnonymousObject() -> (myInt: Int, myString: String) {
    var myAnonymousObject = (myInt: 5, myString: "abc")
    return myAnonymousObject
}
...
var a = returnAnonymousObject()
var b = a.myInt    // "myInt" resolved at compile-time

Some of C#’s limitations with anonymous types can be mitigated by the use of the Tuple generic class. However, this is not without its own annoyances such as having to refer to each property as “Item1”, “Item2”, etc. Swift makes anonymous types a core part of its language from the start, whereas in C# it is an afterthought (in fact, they were not available until Visual Studio 2010).

The Awesome NullReferenceException

One of the most common exceptions in all of C# is the dreaded NullReferenceException. It is a valid and important exception, but it is often the bane of our existence as developers. C# does little from a language perspective to keep us from doing this, unless we are really really careful. More often than not, we generally do not want to work with null objects unless there is an explicit reason to do so. Therefore, by default, Swift makes working with NULL (or nil) objects an explicit effort…

// C#
// Compiles without warnings
public void test() {
    HelloWorld a = null;
    a.test();
}
// Swift
// Does not compile
public func test() {
    var a: HelloWorld = nil
    a.test()
}

In the above example, we are clearly calling “test()” on an object that has be initialized to null. This would error at runtime on both platforms, but Swift goes a step further and refuses to compile. If you were sadistic enough to want to get something like this to actually compile, you would have to modify the Swift code to use Optional Chaining

// Swift
public func test() {
    var a: HelloWorld! = nil
    a.test()
}

or…

// Swift
public func test() {
    var a: HelloWorld? = nil
    a?.test()
}

or…

// Swift
public func test() {
    var a: HelloWorld? = nil
    a!.test()
}

All three will compile successfully. Not all three will execute without a runtime error. Which way you choose will depend on your specific scenario.

The first example uses the exclamation point (!) which indicates that the variable is “optional, but implicitly unwrapped when accessed”. The problem with this option is that it would result, for this case at least, in a runtime error when test() is called. Generally, though, this approach makes sense when you have a specific need for null objects and don’t want to worry about explicitly unwrapping every time.

The second example uses a question mark (?) in its declaration. This means that the variable is optional (it can be assigned nil), but it must be explicitly unwrapped. In this example, the code would not compile without the question mark (?) in “a?.test()”. This provides a nice level of safety while developing. It also will avoid calling test() altogether at runtime if “a?” resolves to nil.

Finally, the last example is just like the second, except we use an exclamation (!) before calling “test()”. This is an explicit unwrap and will ALWAYS call test() even if a! resolves to nil.

Optional Chaining is really useful most of the time. It can get in the way at times, but the payoff of safer, better written code, makes it worthwhile. If you find yourself using ? and ! more often than not, you’re doing it wrong.

Conclusion

There are more differences between Swift and C# that are likely worth covering. However, in the interest of keeping this blog post as an introduction, I have only highlighted the ones I feel are the most significant from the perspective of a C# developer.

Apple pretty clearly wants everyone to be using Swift. Currently, if you are planning to get into any iOS/MacOS development, it is the obvious choice. Even for cross-platform apps I would still recommend abstracting out OS-specific items in Swift and any standard shared code, like business logic, could be done in straight up C (since this is supported by both Android and iOS).

For non-Apple specific platforms, there is nothing really available (yet) to entice you from C# to Swift. I would say Swift is an evolutionary step ahead of C#, but it is certainly not revolutionary. When Swift is ported to other platforms (including .NET), the language may not be attractive enough to get people to port all of their existing C# code to Swift. However, given the possibility of choosing between Swift.NET and C#.NET in the future for new development, I could see developers choosing the former over the latter.

Leave a Reply

You must be logged in to post a comment.

To get started on your custom software solution, call 1-888-421-1155.