VS Code Swift Colorizer

I started working on a Swift colorizer for Visual Studio Code a few days ago. While looking through the code for VS Code1, I've come to realize a few things.

  1. There are basically three different ways to create colorization:
    1. With a TextMate syntax file
    2. With a "Monarch" syntax declaration; I can only assume this is a VS Code specific declaration
    3. A full language service 2. Customization is not really supported that well at the moment 3. Swift has a bunch of language constructs to worry about in order to properly colorize itself

I actually tried going down the path of building a proper tokenizer to give semantically correct highlighting, but without knowing how the internals of VS Code really work2 and my lack of wanting to build a full on parser for Swift, I opted to go down the "Monarch" syntax path3.

So… does the "Monarch" syntax declaration work well? Actually, it works quite well. It's basically a declarative state machine syntax so it allows some pretty nice stuff that is either extremely difficult or just impossible to do with regex. For instance, string interpolation highlighting was fairly straight-forward and you can push and pop states on the syntax highlighting stack.

Anyhow, I've updated the project here: https://github.com/owensd/vscode-swift. It's mostly working, though I do have a set of known issues and I haven't got around to implementing those yet, such as unicode operator colorizing.

Enjoy.

  1. After all, it's just a JavaScript app.
  2. All of that code is minimized as it's not ready for mainstream consumption.
  3. As far as I know, there are no TextMate Swift colorizers that actually work for the entirety of the language.
VS Code Swift Colorizer

Optionals and if-let

Natasha posted a article a little over a week ago: http://natashatherobot.com/swift-unused-optional-value/. I agree with her initial feelings, "This immediately stood out as "wrong" to me."

Basically she was talking about this:

var someOptionalVar: String? = "something there"

if someOptionalVar != nil {
    // just need to check for the presence of a value
}

I don't like this. It just doesn't feel semantically correct. The optional is not nil, it specifically has a value of None. I've never liked this syntax; I've talked about it before – thankfully the bool comparison has been lost, but the nil check still sits wrong with me.

Another example:

let f‚ÇÄ: Bool? = true
let f‚ÇÅ: Bool? = false
let f‚ÇÇ: Bool? = nil

let fn = [ (f‚ÇÄ, "f‚ÇÄ"), (f‚ÇÅ, "f‚ÇÅ"), (f‚ÇÇ, "f‚ÇÇ")]

for (f, label) in fn {
    if f == nil {
        println("\(label) has no value")
    }
    if f != nil {
        println("\(label) has a value")
    }

    if let fv = f {
        println("\(label) = \(fv)")
    }
    else {
        println("\(label) = nil")
    }

    switch (f) {
    case .Some(_):
        println("\(label) has a value.")

    case .None:
        println("\(label) has no value")
    }
}

It's a bit annoying that we have so many ways to check for the presence of a value in an optional. I find languages that have multiple ways of achieving the same thing end up being confusing, especially as more features get added. It's unnecessary complexity that adds over time. Natasha already pointed out the multiple discussions of people doing it different ways.

I also prefer a different way:

func hasValue<T>(value: T?) -> Bool {
    switch (value) {
    case .Some(_): return true
    case .None: return false
    }
}

for (f, label) in fn {
    if hasValue(f) {
        println("\(label) has a value")
    }
    if !hasValue(f) {
        println("\(label) has no value")
    }
}

There is no ambiguity here, there is not transparent conversion between nil and .None, and most importantly to me, the code is always extremely obvious.

Optionals and if-let