The Secret to Swift is Enums

I’ve found the CS193P (Developing iOS 8 Apps with Swift) iTuneU class really helpful in wrapping my old Objective-C head around Apple’s new Swift programming language. Yes, I know we’re at iOS9 but the fundamentals of the class are still relevant and coaxing the code to compile in iOS 9/Swift 2.0 is a fun little last in and of itself.

The big revelation for me is how core Swift’s enums are to understanding and using the language properly. When Apple decided to improve it’s development environment it could have done so in a million different directions. Apple could have just patched up Objective-C. Apple could have moved over to Java or Scala or even JavaScript. (I was hoping for  JavaScript as Node.js and ECMAScript 6 have proved that JavaScript is an industrial strength language with a real future.)

So when I learned that Apple created a new language for iOS and Mac OS X (and now WatchOS and tvOS) application development I was intrigued and disappointed and hopeful all at the same time. Many parts of Swift seems easy and cool but some parts were down right intellectually challenging: Classes and Structs? Super fancy Enums? Optionals? Strings with out a simple function to get their length? What the heck is going on here?

Swift seemed promising. But it was also changing rapidly over the last year. I fooled around with it but when I hit optionals and weak references I realized the language was not going to sugarcoat the problems of null pointers and memory management–it was trying to make them more tractable.

Optionals were especially vexing. var amount: Double? was not a Double. It was a potential Double. Amount! had better be a Double or it would crash my program. If it was’t for Xcode’s automated static code analysis I never would have been able to put the ? and ! in the right places after the right variable names. And I didn’t like that feeling.

But then I found CS193P and Professor Paul Hergarty’s remarkable ability to explain things simply.

Enums in Swift are amazing little machines. They have little in common with C Enum other than you can use them to define collections of related constants. Enums are types with values that evaluate to themselves. But  you can associate a “raw value”, like a number or a string, or more a advanced value, like Tuples or Arrays or Dictionaries. And with advanced types come functions and closures.

Yikes. These are not your father’s Enums. As Professor Hergarty’s says, Swift Enums are types used for when you want to switch between values. And, point of fact, Swift Enums are defined like a Switch structure with case statements. Each of the cases, except with raw values, can be of different types.

And boom! That explains Optionals. When you have a value that could be nonexistent or of some type, an Optional is just an Enum that wraps up it safely so you can pass it around without crashing. ? and ! are just syntactic shortcuts for accessing the different states an Optional variable might be in. Imagining that Optionals are Enums gave me the handle my mind needed to process the whole concept.

In CS193P Professor Paul Hergarty uses an Enum to power his “Calculator Brain”. In any other programming language an Enum would be used to make the code more readable. But in Swift you can use an Enum as the glue to associate states with types with functions. I have a feeling that this Enum-driven mechanism is the cleanest way to write a Swift state machine. It’s still a little rough around the edges and verbose. But it’s a super reusable pattern good not only for the mathematical operations of a calculator but for managing the states of a web server, business application, or game.

//: Playground - noun: a place where people can play

import UIKit
import Foundation

class CalculatorBrain {
    
    enum Op: CustomStringConvertible {
        case Operand(Double)
        case BinaryOperation(String, (Double, Double) -> Double)
        
        var description: String {
            get {
                switch self {
                case .Operand(let operand):
                    return "\(operand)"
                case .BinaryOperation(let symbol, _):
                    return symbol
                }
            }
        }
    }
    
    var opStack = [Op]()
    var knownOps = [String:Op]()
    
    init() {
        func learnOp (op: Op) {
            knownOps[op.description] = op
        }
        
        learnOp(Op.BinaryOperation("*", *))
        learnOp(Op.BinaryOperation("+", +))
        learnOp(Op.BinaryOperation("-", {$1 - $0}))
        learnOp(Op.BinaryOperation("/", {$1 / $0}))
    }
    
    func evaluate() -> Double? {
        let (result, _) = evaluate(opStack)
        return result
    }
    
    func evaluate(ops: [Op]) -> (result: Double?, remainingOps: [Op]) {
        if !ops.isEmpty {
            var remainingOps = ops
            let op = remainingOps.removeLast()
            
            switch op {
            case .Operand(let operand):
                return (operand, remainingOps)
            case .BinaryOperation(_, let operation):
                let op1Evaluation = evaluate(remainingOps)
                if let operand1 = op1Evaluation.result {
                    let op2Evaluation = evaluate(op1Evaluation.remainingOps)
                    if let operand2 = op2Evaluation.result {
                        return (operation(operand1, operand2), op2Evaluation.remainingOps)
                    }
                }
            }
        }
        return (nil, ops)
    }
    
    func pushOperand(operand: Double) -> Double? {
        opStack.append(Op.Operand(operand))
        return evaluate()
    }
    
    func popOperand() -> Double? {
        if !opStack.isEmpty {
            opStack.removeLast()
        }
        return evaluate()
    }
    
    func performOperation(symbol: String) -> Double? {
        if let operation = knownOps[symbol] {
            opStack.append(operation);
        }
        return evaluate()
    }
    
    func showStack() -> String? {
        return opStack.map{ "\($0)" }.joinWithSeparator(" ")
    }
}

var cb = CalculatorBrain()

print(cb.knownOps)

cb.showStack()
cb.pushOperand(1)
cb.pushOperand(2)
cb.performOperation("+")
cb.pushOperand(3)
cb.pushOperand(4)
cb.performOperation("/")
cb.pushOperand(5)
cb.pushOperand(6)
cb.performOperation("*")
cb.pushOperand(7)
cb.pushOperand(8)
cb.performOperation("-")
cb.showStack()

You should watch all the videos in CS193P to get the full picture. But in the meantime I’ve created a simplified version of Professor Hergarty’s CalculatorBrain suitable for a Swift Playground (above). As you fool around with the code keep in mind the following points:

  • CalculatorBain is a class and when it’s instantiated it’s initializer creates a dictionary of operations that it knows about based on type. You can add more known operations by writing a little code in one place. In the sample code the operations for addition, subtraction, division, and multiplication are written very concisely using Swift’s shortcut syntax for closures with default parameter names. (This reminds me of the best features Perl.)
  • The custom type Op is an Enum that is self documenting and has values associated with either a Double (for operands) or a Dictionary (for operations indexed by name). So simple lookups via a case statement are all that is needed to process input and output a result.
  • The two Evaluate functions are recursive, calling each other until every operand or operation needed in the Ops stack is consumed. Evaluate basically does this:
    • Until the Ops stack is empty pull an item off the end of the stack.
    • If that item is an Operand return it and the remainder of the Ops stack.
    • If that item is an operation dig into the Ops stack until you can get two operands and then execute the function associated with the operation using the operands.
    • The return the result with the remaining Ops stack.
  • If I had to write this code without using recursion and without Swift’s muscular Enums, well, there would be a lot more code and it would be more “hard coded”.

The only improvement I can think of would be to declare the known operations as a literal Dictionary. But the Swift compiler isn’t ready for that and complains: “Expression was too complex to be solved in reasonable time”. I guess if Swift can’t do something swiftly it doesn’t want to do it at all!

 

Nothing Changes More Swiftly than Apple’s Swift Syntax

Screen Shot 2015-09-24 at 6.39.39 PM
Look at that beautiful Apple Swift code on the right with closures and shorthand argument names! Make’s me smile every time!

I’m enjoying the Stanford University class CS193P: Developing iOS 8 Applications with Swift. It’s free on iTunes U and the instructor Paul Hegarty knows his stuff. He’s a great explainer. I like how first he writes some code in a naive way and then fools around with it, getting it to work and then reworking it like a sculptor with clay. That’s how real programmers work. We write a rough draft of the code, make sure we understand it and then “refactor” it until we’re no longer embarrassed to share it on GitHub.

But even though the class was recorded in 2014 and updated in June of 2015 it’s aging rapidly. We’re already working with Xcode 7 and iOS 9. And all the little minor changes and improvements are adding up.

One problem you might run into is with the second video: More Xcode and Swift, MVC. In this lesson Professor Hegarty wants to show how we can use a form of polymorphism to write clean code. Specifically with Swift supports something that Objective-C did not! In Swift we can have class functions with the same name but different signatures. In the example in the lesson he shows how we can write two versions of performOperation–one that takes two Doubles as arguments and another that takes only a single Double as an argument. Very cool…

Unfortunately this code no longer compiles.

There is an explanation on Stack Overflow (if you can find it). But it’s not really clear as there are a couple of solutions. Perhaps the best solution, like so much on the human side of computer programming, is a matter of taste.

Here is the code and the fix:

    // these functions won't compile with Swift 1.2 and above
    func performOperationWith(operation: (Double, Double) -> Double) {
        if operandStack.count >= 2 {
            displayValue = operation(operandStack.removeLast(), operandStack.removeLast())
            enter()
        }
    }
    
    func performOperationWith(operation: Double -> Double) {
        if operandStack.count >= 1 {
            displayValue = operation(operandStack.removeLast())
            enter()
        }
    }
    // these functions will happily compile
    func performOperationWithTwoOperands(operation: (Double, Double) -> Double) {
        if operandStack.count >= 2 {
            displayValue = operation(operandStack.removeLast(), operandStack.removeLast())
            enter()
        }
    }
    
    func performOperationWithOneOperand(operation: Double -> Double) {
        if operandStack.count >= 1 {
            displayValue = operation(operandStack.removeLast())
            enter()
        }
    }

Because Swift is smart about classes written in Objective-C that you are subclassing from, it forces those subclasses, in this case UIViewController, to obey Objective-C’s limitations. One of those limitation was not allowing polymorphism for methods with the same name but different arguments.

The code is a little uglier, because there is slightly more of it, but it smart of Apple to be as compatible with Objective-C as possible. At least for a few more years 🙂

Grunt unable to locate JSDoc (wrong installation/environment)

Recently I set up Himins (a server-side node project) to properly build using Grunt. I got every tool working awesomely in my gruntfile.js except for JSDoc! Grunt give me this clue:

Running "jsdoc:dist" (jsdoc) task
>> Unable to locate jsdoc
Warning: Wrong installation/environnement Use --force to continue.
Aborted due to warnings.

I had previously installed JSDoc with NPM globally and tested it on the command line. Googling around didn’t turn up much at first. I was not going to move JSDoc to a non-standard location just for Grunt!

This blog post, The Best Document Generator for Node, gave me the clues I needed to resolve the problem!

I just had to add

jsdoc: './node_modules/.bin/jsdoc'

to my gruntfile.js!

Why Grunt doesn’t look for JSDoc there in the first place is weird to be. All it’s friends are there. The sample code for using the JSDoc Grunt plug-in doesn’t mention this issue.

You can find my full guntfile.js here.

Comic Page for Dualism by Bill DeSmedt

dualism_page_001

I drew this for Bill just because I like his work, he’s a super smart guy and good friend, and I hope he is working on a sequel. You can buy the book here: http://www.amazon.com/Dualism-Archon-Sequence-Bill-Desmedt/dp/0974573434

Notes on the tools and process

  • I drew on actual comic book bristol board with pencils, india ink, pens with nibs and artist brushes–old school style!
  • Scanned the black and white 11 x 17 page into Photoshop
  • Corrected some mistakes and added lettering and colors

Upcoming Important Holidays (Now that Nerds Rule)

Mark your calendars so that you can send an eCard to your favorite hacker, startup co-founder, or sys admin!

  • March 14 – Pi Day – Celebration of everyone’s fav irrational number!
  • March 25 – Tolkien Reading Day – Commemoration of the fall of Sauron (where did I put that ring?)
  • April 25 – DNA day – The day the paper on the structure of DNA was published in the journal Nature and later the day when the Human Genome Project was declared “mostly done.”
  • April 27 – Morse Code Day – The day Samuel Morse was born …. .- .– .– -.– / -… .. .-. – …. -.. .- -.– / … .- —
  • May 1 – No Pants Day – Thanks Knighthood of Buh!
  • May 4 – Star Wars Day – May the fourth be with you!
  • May 25 – Towel Day – According to the Hitchhiker’s Guide to the Galaxy you should alway have your towel with you (it’s in my backpack)
  • May 26 – National Paper Airplane Day – The only way to fly!

Surface Pro 3: Quick Status Update

I’ve been using the Surface Pro 3 all week and I continue to find ways to integrate it into my daily routine and overcome minor obstacles.

sp3_awk_amm

Apple Magic Mouse and Wireless Keyboard.

I have some unused Apple bluetooth peripherals lying around the house and I wanted to see how they paired with the Surface Pro 3. The Apple Wireless Keyboard works flawlessly. I love the firm feel and responsiveness of Apple’s keyboard. Most wireless keyboards, including Microsoft’s, feel chintzy to me. I’m happily typing away with the Apple Wireless Keyboard and the Surface Pro 3 as I write this blog post. Just remember: The Apple command key maps to the Microsoft windows key.

The Apple Magic Mouse was more problematical. It paired immediately with the Surface Pro 3 and works find as far as left and right clicking go. But the touch-based scrolling feature of the Magic Mouse is disabled. There is a utility that claims to enable the full functionality of the Magic Mouse. You can find it here: Trackpad Magic. It didn’t work for me. I installed both the drivers and the utilities. But they must be out of date or just incompatible with the Surface Pro 3. It doesn’t matter! I’m really used to interacting with the screen to pan and scroll and scrolling with a mouse is starting to feel unnatural. I only need a mouse for precision clicking when the pen or my finger would be too awkward or imprecise.

 

This Page Intentionally Left Blank

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

(Yeah, I’ve been meaning to post an intentionally left blank page for some time now. Whenever I see one my mind spins in a little mental loop: The page is blank. But the page is not blank because it has writing on it. But the page is blank because it was the author’s intention to leave it blank and she wrote a note about that intention. But the page is not blank because the authors intention was to write the words “This Page Intentionally Left Blank” on it. So the author is lying. No, actually, the author is in self-denial. No, the author was didn’t want to be ambiguous. But what is more ambiguous than a blank page with a message on it that claims it is a page without a message. Is there a message within the message? Is it all a joke? Is it a metaphor for something? A pointer to void? The page is blank…)

Surface Pro 3: Patience is Rewarded

I recently acquired a Surface Pro 3 during a Black Friday sale from a local Microsoft Store. I knew I was in for a challenge but I was up for it. I’m from the generation that witnessed the rise of personal computing in the late 20th century from clunky calculator-like boxes with tiny displays and obscure software commands to modern sleek slates of glass and metal that are all display and responsive to touch and voice. It’s been a fun ride and part of the thrill was trying to figure out how to get anything useful out of the ever evolving personal computer. Quite frankly I’ve been a bit bored with modern iOS and Android devices. Well designed and rapidly becoming indistinguishable, my iPad, iPhone, and Android phone pretty much work as expected and do no more and no less then their makers intend.

I’m also a little worried about the future of the general purpose personal computer. The biggest game changer in my life has not been the ability to play games, write blog posts, or edit movies on an affordable computer. It’s the ability to write computer programs that create games, blogging systems, and multimedia editors that has given me a community, confidence, and a livelihood.

PC sales have been and continue to be in decline. To fight this decline Apple and Microsoft are making their PCs more like tablets with keyboard: sealed boxes with safety belts and airbags that keep users from getting into trouble–like installing botnets or mining bitcoin.

In another five or ten years the general personal computer that can compile and link C code into a tool or application might be a thing of the past. Computer engineering might require expensive development systems and a University education. That’s were we started in the 1960s. The web, the apps, and the games that we use everyday have only been possible because kids, with little money or training, have been able to purchase a general purpose personal computer and start hacking around. For me, and millions like me, exploring the capabilities of a personal computer is like going on a hike. It’s fun and there is no other purpose then to do it. Software like Facebook, Flappy Bird, and FileMaker are just side effects.

So I bought a Surface Pro 3, which is a real PC that looks like a tablet, and put my MacBook Air aside. I’ve spent the last few weeks figuring it out. I’m not quite there but I’m having a blast as I try to relearn basic computer skills, discover its limits, and find workarounds for it’s bugs and so-called features!

Below are some of my field notes:

  • The Surface Pro 3 is a real computer and a tablet combined. It’s light enough to use as an ereader but powerful enough to code with. It’s also powerful enough to play serious games, edit images, and do anything a modern laptop can do. It’s not a desktop replacement but it’s close enough for me.
  • The Surface Pro 3 is still a work in progress. There are many good ideas but either they aren’t implemented well or they should be reworked. Let’s look at a few examples:
    • The Type Cover, which is a full keyboard and cover combined, is an awesome idea but feels flimsy on my lap, makes too much noise while typing, has to be physically connected, and is awkward when you don’t need it but want to keep it handy. The little track pad on the Type Cover is terrible, not needed, and makes the text cursor bounce all over the screen. Luckily you can turn it off! You won’t miss it!
    • The Windows 8.1 user interface works pretty well with a finger or a pen, but there are a few major problems when editing text with Google Chrome as the web browser. With the Type Cover connected a finger tap brings up the touch keyboard and obscures the lower third of the screen. The touch keyboard goes away on its own when you type on the Type Cover but it breaks your concentration.
    • Your finger is all you need if you are not drawing except when it comes to small icons and so-called left mouse clicks. I’ve got enough motor control that only the smallest of icons and buttons are inaccessible to my index finger but I can’t execute some left mouse clicks without a pen (or mouse) on the Surface Pro 3 with Google Chrome. Windows 8.1 maps a long-press to the left click but it doesn’t work for spell checking. As a terrible speller I need that popup menu of spelling corrections!
  • Windows 8.1 is a work in progress as well! It poorly combines the the user experience of Windows 7 with a touch interface. The results are confusing and inconsistent:
    • There are two system control panels and it’s not always clear where a setting will show up.
    • If you are not connected to a wireless network the Windows 7 part of the interface tells you that “no networking hard is detected”. But all you have to do is touch the little signal bars icon on the task bar and a list of wireless networks appear.
    • The Windows 8.1 start screen wants to replace the Windows 7 start menu. But the start screen feels like a disordered Mondrian painting. My advice to Microsoft: go back to the usability lab. Nobody uses Apple’s app launcher either. We use the task bar and the Finder.
  • The best feature of the Surface Pro 3 for the practicing coder is that you can install and run real development software like Node.js, Ruby, Git, Sublime, Vim, Emacs, C, and other UNIX-based tools. Many of these tools have Windows equivalents and others run well via Cygwin and Msys. Cloud 9, the web-based IDE for web apps also works fine with the Surface Pro 3 via Google Chrome. The HipChat client really needs a UI update but does it’s job so you can chat with your fellow engineers.
  • I’ve download the open source version of Microsoft’s Visual Studio and runs very well on the Surface Pro 3. I’m not a Windows developer (any more–the last time I developed with Windows was Windows 95!) but I’m impressed with Microsoft’s adoption of JavaScript as a primary programming language. I formally forgive Microsoft for JScript.
  • In my spare time I like to draw and paint with my computer and I’ve found that the Surface Pro 3 runs Abode Photoshop and Clip Studio Paint (Manga Studio) very well. It has a few minor problems distinguishing a resting palm from a touch but the pressure sensitive pen is as good as a Wacom tablet.
  • If you need to use the Microsoft Office, the Surface Pro 3 and Windows 8.1 is excellent at it. I know this isn’t cool but my favorite word processor is Microsoft Word. The Office apps simply don’t run well on a Mac and are missing important features. The one aspect of my MacBook Air that I don’t miss is struggling with Microsoft Word 2011!

So there you have it. If you enjoy a challenge and being different and have the patience to put up with some annoying bugs then the Surface Pro 3 might be for you. It’s more realistically usable than a ChromeBook but far from the antiseptic polish of a Macbook.