More on the Optionals!

We can chose to write stable code or we can hand-wave stuff that “shouldn’t fail”. I’m extremely wary of the pattern that I keep seeing from Apple about ! and Optional… I find it odd that Apple is promoting the use of the ! pattern.

An initializer defined with init can be made failable by adding a ? or a ! after the init, which indicates the form of optional that will be produced by constructing an object with that initializer. For example, one could add a failable initializer to Int that attempts to perform a conversion from a String:

extension Int {
    init?(fromString: String) { 
        if let i = fromString.toInt() {
            // Initialize 
            self = i
        } else {
            // return nil, discarding self is implied
            return nil
        }
    }
}

Source: Apple Developer Blog: https://developer.apple.com/swift/blog/

If we change the init? above to init! (which the description above tells us is perfectly valid)…

let value = Int(fromString: "abc")
return value + 1

BOOM! Hello my EXC_BAD_INSTRUCTION friend.

Look, sometimes your code really should only return nil in the most dire of circumstances, ok… but is the right behavior to crash your app? Even if it is, it should not be so easy to enable the return of nil from something that should practically never return nil, such as memory allocations handled by the system.

One of Swift’s goals is this: “Understanding and properly handling cases where objects are nil is fundamental to the frameworks, and Swift code makes this extremely easy.” (Source: https://developer.apple.com/swift/)

I truly believe this behavior is leading us away from that – I’d go so far to claim it’s the antithesis of it, but that may be too extreme for some.

As developers, we want to be able to write both safe and stable apps. The ! is leading us down the path of safe but crashy apps. We’re going to get there just as we got there with * and dereferencing null pointers. Of course, everyone knows not to do it… yet sometimes we forget. And to those new to the language, they might not know better.

See: Pointer fun with Binky.

I would much rather see APIs defined like this:

@unsafe_force_unwrap func init(fromString: String) { ... }

Give support for the feature when needed, but people will be much less prone to accidentally doing it. It needs to be marked as unsafe; currently there is no really indication other than experience with the language.

This also gives us the ability to have compiler warnings/errors when these are used so we can much easier audit those code usages.

More on the Optionals!

Optionals Beware

Update: 10/20/2014 I was inappropriately applying ? to the key lookup, which of course, does nothing. It is simply not needed.

Optionals… that pesky little safe, but sometimes dangerous, construct in Swift. It's not new or unique, but they do work a bit different than other languages.

GIVE ME THE VALUE!!! In John Siracusa's Yosemite review, there's a section on Swift. In it, while talking about safety and optionals, there's a trap in here.

let ages = [
    "Tim":  53,  "Angela": 54,  "Craig":   44,
    "Jony": 47,  "Chris":  37,  "Michael": 34,
]

let people = sorted(ages.keys, <).filter { ages[$0]! < 50 }

swift

Do you spot it? It's the use of !.

And that's the problem with the !, in some cases, it is safe to use it… until you start to modify the code around the area, then it might start to get dicey.

There is a safe way to write the code that will never cause your program to crash, regardless of the refactoring you do:

let people = sorted(ages.keys, <).filter { ages[$0] < 50 }

Removing the ! provides all the safety we need. The comparison operators already handle optionals. In the case of <, when the left hand side is nil, the result is always true.

Whenever you see the ! in your code, BE CAREFUL!!! I'd go so far as recommending to never use it. There are safer ways, though, they are sometimes it is a bit more verbose.

So instead of writing this:

func |||<T>(opt: T?, defaultValue: T) -> T
{
    return opt != nil ? opt! : defaultValue
}

swift

Write this:

func |||<T>(opt: T?, defaultValue: T) -> T
{
    if let opt = opt { return opt } else { defaultValue }
}

Update: Yes, you could use ??, that's not the point. The point is just showing how to write the forced unwrapped version in way that doesn't require forced unwrapping.

Beware of the optional!

Optionals Beware

Stop to Smell the Roses

I would love to build a better Objective C language. It would be a language that embraces the functional programming world and the imperative programming world, the world of dynamic runtimes and static types, and build a bridge to the future from the past.

The following is taken from some of my notes, so the code samples might be a bit rough.

Class definitions would be simple and straight forward:

' All classes derive from `NSObject` by default. Use the `derives <class>` syntax
' to subclass differently. Also, use `implements <type>, <type>, ...` for protocols.
interface Person
    ' The `let` keyword creates readonly properties.
    let firstName :: NSString
    let lastName :: NSString

    ' The `var` keyword creates read/write properties.
    ' The `[copy]` is the attribute applied to the property, in this case
    ' all writes to `emailAddress` will create a copy of the incoming value.
    var emailAddress :: NSString [copy]

    ' initializer with parameters, defaults to returning `instancetype` in ObjC
    def initWithFirstName::NSString lastName::NSString
        _firstName = firstName
        _lastName = lastName

    ' a message name with a single parameter, defaults to returning `void` in ObjC
    def say message::NSString
        log("\(firstName) says \"\(message)\"")

    ' A simple message that returns a `NSString`
    def fullName -> NSString
        return "\(firstName) \(lastName)"

All function definitions would allow for partial application:

def sum x: Number -> y: Number -> Number
    return x + y

let sum1 := sum 1
let sum2 := sum1 2
let full := sum 3 4
log "sum of 1 + 2 = \(sum2)"

Syntax would be light and free of unnecessary tokens:

' No difference between message calls and function calls
let david := Person newWithFirstName:"David" lastName:"Owens
david.emailAddress := "david@owensd.io"

' Use () to group nested calls for ordering
let sally := (Person alloc) initWithFirstName:"Sally" lastName:"Sue"
sally say:"Hello all the peoples!"

let ages = {
    "Tim":  53,  "Angela": 54,  "Craig":   44,
    "Jony": 47,  "Chris":  37,  "Michael": 34,
}

let people = filter (key => ages[key] < 50) (sort < (ages allKeys))

All of this code can be re-written to ObjC (by a tool). I have prototypes of some of it and manual constructions of others. I know it’s possible and it allows for full interop between this language dubbed Proteus and ObjC.

But… what’s the point?

I don’t mean to ask that as a submission or a throw-in-the-towel remark. But really, what’s the point? Where do I want to go with it? It would be fun to go through designing this out and getting all of the main scenarios working – I haven’t done that since my college days. I don’t even think it’s a super amount of work. But the edge cases will suck. The considerations of certain C constructs will get a bit dodgy. And in order to really get the performance up to par, I’m likely going to need to emit LLVM code instead of going through the ObjC source code, or worse (in my opinion), need to make changes to LLVM or Clang like the Eero project did. And this is before I even get into editor support, code highlighting, debugging, etc…

Swift has it’s warts. It’s a baby that’s trying to grow up quickly in a world that is harsh. The question I’ve been asking myself, both through these posts and throughout the weeks is really this: are Swift’s warts and ugly places worse than those of Objective C’s? Will they be tomorrow?

There will be a lot I miss about ObjC. Hopefully we’ll see more of that over time. But I think it’s time for this station to get back to it’s regularly scheduled program.

Stop to Smell the Roses

Building a Better Objective C

If you’ve been following along with my recent posts regarding enums and Objective C, you’ll notice a theme: Objective C is quite capable of expressing what we want, it’s just extremely verbose, especially compared to the improved syntax that Swift brings to the table.

There are many significant drawbacks to Swift, especially when you need to interop with ObjC code. In this world, we need something better. We need to be able to transparently bridge between the world of modern syntax and conveniences without being shackled to the days of C programming, while at the same time, being able to maintain 100% interop with all of our existing ObjC code.

We could continue to suffer through the ObjC syntax, or, we can do something about it.

Framing the Solution One solution to solving the problems I exposed in the series with enums is to use a bunch of MACROs. That works, but it doesn’t get us nearly where we want to be: a modern, sleek syntax that is both easy to write, and more importantly, easy to read and reason about.

This is where we want to be:

enum CompassPoint: North | South | East | West

That’s it. That’s all it should take to define one of the “traditional” enums.

enum Barcode:
  | UPCA(numberSystem :: int, manufacturer :: int, product :: int, checkInt :: int)
  | QRCode(code :: NSString)

And above is what the “associative value” enum looks like. I’d like to call out something here, we actually have more information encoded in the enum then Swift here – we capture the name of the components1. This adds much more clarity to what the values actually are.

And finally, the raw values:

enum ASCIIControlCharacter :: NSString:
  | Tab := "\t"
  | LineFeed := "\n"
  | CarriageReturn := "\r"

You might be wondering at how we are going to accomplish this. Well, it’s actually pretty straight forward. Here are the items we’ll be building:

  1. A parser for our enum syntax
  2. A tool to convert our parse tree to ObjC code

That’s it. We don’t actually need anything else2. I’ll show how we can leverage Xcode’s built-in extensibility points to give us nice error reporting and seamless integration of our new enum definition.

I will be calling this new language: Proteus.

Building the Parser There are basically two ways to generate the parser: handwrite one or use some tools to generate one from a grammar. I’m going to handwrite our parser, primarily because our enum grammar is quite simple and it’s really easy to provide very friendly error messages with a handwritten parser.

Note: I’ll only be showing building the most simple of parsers accepting only the basic version of the enum. The full github link will be posted at the end. Overtime I’ll continue to add support more features.

The work is going to be broken up into the following components:

  1. Scanner – this is going to break up the input file into a set of tokens.
  2. Analyzer – this is going to take the tokens from the Scanner and apply meaning to them, returning an array of Constructs.
  3. Construct – a representation of the different type of language constructs, such as enum or func.
  4. Rewriter – a function that can take a Construct and turn it into the appropriate Objective C header and implementation files.

I will be writing the components in Swift – I like the irony of building a better Objective C in a language that I think didn’t live up to that promise. =)

The full source for the project can be found here: https://github.com/owensd/proteus3.

If you take a look at the code for the scanner (in lexer.swift), the output for the CompassPoint declaration are the following tokens:

  1. Token(Keyword) “enum”
  2. Token(Identifier) “CompassPoint”
  3. Token(Colon) “:”
  4. Token(Identifier) “North”
  5. Token(Pipe) “|”
  6. Token(Identifier) “South”
  7. Token(Pipe) “|”
  8. Token(Identifier) “East”
  9. Token(Pipe) “|”
  10. Token(Identifier) “West”

This input is passed into the Analyzer which outputs an Enum construct.

Enum:
  typeName = "enum"
  identifier = "CompassPoint"
  options = [
    "North",
    "South",
    "East",
    "West"
  ]

Then there is the rewriteEnumToObjC rewriter function. The full code for that is below:

private func rewriteEnumToObjC(value: Enum) -> (header: String, implementation: String)
{
    var header = "@interface \(value.identifier) : NSObject\n\n"

    var implementation = "#include \"\(value.identifier).h\"\n\n"
    implementation += "#define RETURN_ENUM_INSTANCE() \\\n"
    implementation += "    static \(value.identifier) *instance = nil;\\\n"
    implementation += "    static dispatch_once_t onceToken;\\\n"
    implementation += "    dispatch_once(&onceToken, ^{\\\n"
    implementation += "        instance = [[\(value.identifier) alloc] init];\\\n"
    implementation += "    });\\\n"
    implementation += "    return instance;\n\n"

    implementation += "@implementation \(value.identifier)\n\n"

    for option in value.options {
        header += "+ (\(value.identifier) *)\(option.name);\n"
        implementation += "+ (\(value.identifier) *)\(option.name) { RETURN_ENUM_INSTANCE(); }\n"
    }

    header += "\n+ (NSArray *)values;\n"
    implementation += "\n+ (NSArray *)values\n"
    implementation += "{\n"
    implementation += "    static NSArray *values = nil;\n"
    implementation += "    static dispatch_once_t onceToken;\n"
    implementation += "    dispatch_once(&onceToken, ^{\n"
    implementation += "        values = @[ "

    for (idx, option) in enumerate(value.options) {
        implementation += "\(value.identifier).\(option.name)"
        if (idx != value.options.count - 1) {
            implementation += ", "
        }
    }

    implementation += " ];\n"
    implementation += "    });\n\n"
    implementation += "    return values;\n"
    implementation += "}\n"

    header += "\n@end\n"
    implementation += "\n@end\n"

    return (header, implementation)
}

swift

The basic concept is to literally just write the header and implementation files as you would normally.

With each of those components in place, it’s time to hook it up!

Integration with Xcode If you download the project I linked, there will be a command-line tool called protc. It takes two parameters:

  1. -file – the path to the .prot file that contains our enum definition
  2. -output – the path that the .h and .m files will be written to

So here’s the magic… Xcode has these things called “Build Rules”. It’s basically how anything gets compiled within Xcode. Well, we can create our own build rules for our .prot files.

Step 1: Build Rules To do that:

  1. Select your project in the project navigator
  2. Select the target for your app/tool
  3. Select the “Build Rules” tab in the project editor
  4. Add a new build rule

The script will be filled in with this content:

rm "${DERIVED_FILE_DIR}/${INPUT_FILE_BASE}.h" 2> /dev/null
rm "${DERIVED_FILE_DIR}/${INPUT_FILE_BASE}.m" 2> /dev/null
/Users/owensd/Library/Developer/Xcode/DerivedData/protc-ecehehjngfljckcirxwdltnqqayl/Build/Products/Debug/protc -file ${INPUT_FILE_PATH} -output ${DERIVED_FILE_DIR}

Then be sure to set the “Output Files” to:

  1. $(DERIVED_FILE_DIR)/$(INPUT_FILE_BASE).h
  2. $(DERIVED_FILE_DIR)/$(INPUT_FILE_BASE).m

Here’s a screenshot of what it looks like:

Custom build rules allow us great flexibility.

: .caption

Step 2: Create your .prot file Next, create your .prot file just as you would any file. The trick is to add it to your “Compile Sources”.

  1. Select your project in the project navigator
  2. Select the target for your app/tool
  3. Select the “Build Phases” tab in the project editor
  4. Add your .prot file to the list of “Compile Sources”

Don’t forget this step or nothing will seem to be working!

: .caption

Step 3: Use your new enum! That’s really it. Now when you build your project, the .prot will be processed and in turn the generated .m file will be compiled into your project’s target.

To use it, simply add the header file as normal:

#import <Foundation/Foundation.h>
#import "CompassPoint.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        for (CompassPoint *point in CompassPoint.values) {
            if (point == CompassPoint.North) {
                NSLog(@"direction is north");
            }
            else if (point == CompassPoint.South) {
                NSLog(@"direction is south");
            }
            else if (point == CompassPoint.East) {
                NSLog(@"direction is east");
            }
            else if (point == CompassPoint.West) {
                NSLog(@"direction is west");
            }
        }
    }

    return 0;
}

objc

If you set your “Output Files” to be ${DERIVED_FILE_DIR}, the header paths have no trouble finding the generated header.

Step 4: Handling Build Errors Of course, sometimes you might make a mistake in your .prot file. It would suck if there was no way to handle this or to be notified of this… but of course that’s not the case!

Change your .prot file to this:

enum CompassPoint North | South | East | West

Notice the missing : between CompassPoint and North. Re-build your project, and voila!

Errors are reported and clickable!

: .caption

Not only can the error be reported, but it will cause your project to report a build failure. Those errors are also linked back to your source, so double-clicking will open your .prot file and show the error there.

Pretty cool.

The only missing thing is code completion and colorization. Unfortunately, to the best of my knowledge, those two features require full-blown Xcode plug-ins – way out of scope for this blog entry.

Next Steps Over the years, Objective C has attempted to get facelifts. Way back the 1997 timeframe, there was a project to create a “modern syntax” for ObjC. It didn’t go well. Then there was the ObjC-Java bridge that came in 2001. That also didn’t go well.

However, in 2006 we got ObjC 2.0. That was pretty good step forward for the Objective C language. And of course, in 2014, we got Swift.

I think the biggest disservice we can do to the Cocoa developer community is remove the underpinnings of the ObjC runtime. It is the language’s, and I truly believe, the platforms’ greatest strength.

I believe if we hide the complexities of C from our source code and focus on letting the power of the ObjC runtime shine through in our code, we can create a new language that provides of the great flexibility of the ObjC runtime while still accomplishing many of the goals that Swift is attempting to solve – namely safer code by default.

So I guess this is the start of the project I’m calling Proteus. We’ll see how far it gets.

  1. Note that you can put labels here in Swift as well, they just are not required.
  2. Now, we could go the extra mile on step #2 and simply emit the LLVM code, but honestly, I don’t have time to go down that route. It’s also not necessary for what I want to accomplish here.
  3. Here’s the repo link for the state at the time of authoring this blog entry: https://github.com/owensd/proteus/tree/78d0b2ad729948fcef7e6da80e966574b372cc91.
Building a Better Objective C

Building Swift-Style Enums in ObjC, Part 3

You can find part 1 and part 2 if you need to catch up. This part will be about creating Swift’s “raw value” enum type.

Feature Set This is essentially the same as the “traditional” enum with additional piece: a specific value for the given enum value. The requirements are simple:

  1. Each value represents a unique option
  2. Each value has an intrinsic value

Swift Examples This is what the Swift code looks like:

enum ASCIIControlCharacter: Character {
    case Tab = "\t"
    case LineFeed = "\n"
    case CarriageReturn = "\r"
}

swift

You assign one like this:

var controlCharacter = ASCIIControllCharacter.Tab

And you use it like this:

switch controlCharacter {
case .Tab:
    println("this is a tab")
case .LineFeed:
    println("who doesn't love newlines?")
case .CarriageReturn:
    println("notepad needs these... don't forget!")
}

ObjC Usage Let’s start with how we use it. First, how we declare it:

ASCIIControlCharacter *controlCharacter = ASCIIControlCharacter.Tab;

Like the previous examples, the switch-statement needs to be converted to an if-statement.

ASCIIControlCharacter *controlCharacter = [ASCIIControlCharacter fromRaw:@"\t"];
if (controlCharacter == ASCIIControlCharacter.Tab) {
    NSLog(@"this is a tab");
}
else if (controlCharacter == ASCIIControlCharacter.LineFeed) {
    NSLog(@"who doesn't love newlines?");
}
else if (controlCharacter == ASCIIControlCharacter.CarriageReturn) {
    NSLog(@"notepad needs these... don't forget!");
}

objc

There is a bit less typing in the Swift version, but not much1.

ObjC Implementation Now is time for the dreaded implementation… it’s always much more painful in ObjC.

@interface ASCIIControlCharacter : NSObject

@property (copy) NSString *rawValue;

- (instancetype)initWithCharacter:(NSString *)rawValue;

+ (ASCIIControlCharacter *)Tab;
+ (ASCIIControlCharacter *)LineFeed;
+ (ASCIIControlCharacter *)CarriageReturn;

+ (ASCIIControlCharacter *)fromRaw:(NSString *)rawValue;

@end

@implementation ASCIIControlCharacter

#define RETURN_ENUM_INSTANCE(CHAR) \
    static ASCIIControlCharacter *instance = nil;\
    static dispatch_once_t onceToken;\
    dispatch_once(&onceToken, ^{\
        instance = [[ASCIIControlCharacter alloc] initWithCharacter:CHAR];\
    });\
    return instance;

+ (NSMutableDictionary *)rawLookup;
{
    static NSMutableDictionary *lookup = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        lookup = [[NSMutableDictionary alloc] init];

        [lookup setObject:ASCIIControlCharacter.Tab forKey:@"\t"];
        [lookup setObject:ASCIIControlCharacter.LineFeed forKey:@"\n"];
        [lookup setObject:ASCIIControlCharacter.CarriageReturn forKey:@"\r"];
    });

    return lookup;
}

- (instancetype)initWithCharacter:(NSString *)rawValue
{
    if (self = [super init]) {
        self.rawValue = rawValue;
    }
    return self;
}

+ (ASCIIControlCharacter *)Tab              { RETURN_ENUM_INSTANCE(@"\t"); }
+ (ASCIIControlCharacter *)LineFeed         { RETURN_ENUM_INSTANCE(@"\n"); }
+ (ASCIIControlCharacter *)CarriageReturn   { RETURN_ENUM_INSTANCE(@"\r"); }

+ (ASCIIControlCharacter *)fromRaw:(NSString *)rawValue
{
    return ASCIIControlCharacter.rawLookup[rawValue];
}

@end

So yeah… without doing anything magical, the straight ObjC version is not so awesome to author compared to the Swift version. It is more flexible, but much more verbose.

The root of the problem is not the inability for ObjC to express these types, it’s simply the ease in which ObjC can do it.

It’s about the syntax. And we’re getting there… =)

  1. If we wanted, we could even set it up so that the ObjC version could hold different types of raw values; that’s something that’s not possible in Swift today.
Building Swift-Style Enums in ObjC, Part 3

Building Swift-Style Enums in ObjC, Part 2

In the previous article, I took a look at building “traditional” enums from Swift into ObjC. This time, we’ll take a look at how we might build the “associative value” enum.

Feature Set

Swift also allows you to create “enum” values that are able to store various pieces of data stored alongside that enum value. The requirements are essentially this:

  1. Store associated values of any given type
  2. The value types can be different for each member of the enumeration

Swift Examples

In Swift, one such enum might look like this:

enum Barcode {
    case UPCA(Int, Int, Int, Int)
    case QRCode(String)
}

swift

You create one like this:

var productBarcode = Barcode.UPCA(8, 85909, 51226, 3)

And you use it like this:

switch productBarcode {
case .UPCA(let numberSystem, let manufacturer, let product, let check):
    println("UPC-A: \(numberSystem), \(manufacturer), \(product), \(check).")
case .QRCode(let productCode):
    println("QR code: \(productCode).")
}

swift

Essentially what you are creating is a set of classes that hold data grouped under a Barcode namespace. We can do something similar in ObjC.

ObjC Usage

Let’s start with how we use it. First, how we declare it:

Barcode *productBarcode = [Barcode UPCA:8 :85909 :51226 :3];

Pretty similar to Swift, not too bad.

And how about that switch-statement? Well, we can do it with an if-statement instead:

if ([productBarcode isKindOfClass:[UPCA class]]) {
    NSLog(@"UPC-A: %ld, %ld, %ld, %ld", [(UPCA *)productBarcode part1],
                                        [(UPCA *)productBarcode part2],
                                        [(UPCA *)productBarcode part3],
                                        [(UPCA *)productBarcode part4]);
}
else {
    NSLog(@"QR code: %@", [(QRCode *)productBarcode part1]);
}

objc

Ok, the ObjC version is starting to look ugly again because of a syntax problem; we cannot pull out the components and nicely as we can in Swift… but we’ll address that later too.

ObjC Implementation

Ok… so how do we implement this in ObjC? Well, remember, this is really just a special type that is getting returned depending on which “enum” value you want.

@class UPCA;
@class QRCode;

@interface Barcode : NSObject

+ (UPCA *)UPCA:(NSInteger)part1 :(NSInteger)part2 :(NSInteger)part3 :(NSInteger)part4;
+ (QRCode *)QRCode:(NSString*)barcode;

@end

@interface UPCA : Barcode
@property (assign) NSInteger part1;
@property (assign) NSInteger part2;
@property (assign) NSInteger part3;
@property (assign) NSInteger part4;
@end

@interface QRCode : Barcode
@property (copy) NSString *part1;
@end

@interface UPCA (Private)
- (instancetype)initWith:(NSInteger)part1 :(NSInteger)part2 :(NSInteger)part3 :(NSInteger)part4;
@end

@interface QRCode (Private)
- (instancetype)initWith:(NSString *)part1;
@end

@implementation Barcode

+ (UPCA *)UPCA:(NSInteger)part1 :(NSInteger)part2 :(NSInteger)part3 :(NSInteger)part4
{
    return [[UPCA alloc] initWith:part1 :part2 :part3 :part4];
}

+ (QRCode *)QRCode:(NSString*)barcode
{
    return [[QRCode alloc] initWith:barcode];
}

@end

@implementation UPCA

- (instancetype)initWith:(NSInteger)part1 :(NSInteger)part2 :(NSInteger)part3 :(NSInteger)part4
{
    if (self = [super init]) {
        self.part1 = part1;
        self.part2 = part2;
        self.part3 = part3;
        self.part4 = part4;
    }

    return self;
}

@end

@implementation QRCode

- (instancetype)initWith:(NSString *)part1
{
    if (self = [super init]) {
        self.part1 = part1;
    }

    return self;
}

@end

objc

WOW! That is a ton of boiler-plate code. But we are there, we have the same functionality that we have in Swift. Would you I want to write this? Eh… no. But, the point here is just to see how we might implement these features from Swift in ObjC directly. There are of course many optimizations we can do and generalizations to make; this is only one naïve implementation of “associated values”.

More next time.

Building Swift-Style Enums in ObjC, Part 2

Building Swift-Style Enums in ObjC, Part 1

I thought it would be an interesting thought experiment if we take a look at features that are present in Swift and see what it would take to build them out in ObjC.

Up on the docket today is the Enum. Of course, Swift really supports three different types of enums:

  1. The "traditional" enum — simply a list of potential options
  2. An "associated value" enum — enums with particular values that can be held but grouped under a context
  3. The "raw value" enum — an enum that stores a specific value for each of the options.

In this post, we'll be looking at the "traditional" enum.

Feature Set

So the traditional enum is quite basic and needs only to implement the following rules:

  1. Each value represents a unique option
  2. There is no intrinsic value to any given option

Optionally, it would be nice to be able to:

  1. Iterate over all of the options
  2. Know the number of options available

Implementation There are a couple of options available to us:

  1. Use the C-style enum that is already supported in ObjC
  2. Build the enum using @interface (e.g. classes)

I'll be going with option #2 as it provides the most flexibility and allows us to be true to all of the rules.

I'll be creating the CompassPoint enum from the Swift language guide.

enum CompassPoint {
    case North
    case South
    case East
    case West
}

swift

In ObjC, we need to have the following:

@interface CompassPoint : NSObject

+ (CompassPoint *)North;
+ (CompassPoint *)South;
+ (CompassPoint *)East;
+ (CompassPoint *)West;

@end

#define RETURN_ENUM_INSTANCE() \
    static CompassPoint *instance = nil;\
    static dispatch_once_t onceToken;\
    dispatch_once(&onceToken, ^{\
        instance = [[CompassPoint alloc] init];\
    });\
    return instance;

@implementation CompassPoint

+ (CompassPoint *)North { RETURN_ENUM_INSTANCE(); }
+ (CompassPoint *)South { RETURN_ENUM_INSTANCE(); }
+ (CompassPoint *)East  { RETURN_ENUM_INSTANCE(); }
+ (CompassPoint *)West  { RETURN_ENUM_INSTANCE(); }

@end

objc

Well… that's looking a bit ugly, but we've met the initial requirements.

Usage of the enum is almost identical to Swift, with two caveats:

  1. Unable to use the shorter dot-notation
  2. Unable to use the switch-statement

Here's what the usage code looks like:

CompassPoint *directionToHead = CompassPoint.South;
if (directionToHead == CompassPoint.North) {
    NSLog(@"Lots of planets have a north");
}
else if (directionToHead == CompassPoint.South) {
    NSLog(@"Watch out for penguins");
}
else if (directionToHead == CompassPoint.East) {
    NSLog(@"Where the sun rises");
}
else if (directionToHead == CompassPoint.West) {
    NSLog(@"Where the skies are blue");
}

objc

The nice thing about this ObjC version is that it's quite easy to add some additional functionality, like the ability to iterate over all of the values:

@interface CompassPoint (Iteration)
+ (NSArray *)allValues;
@end

@implementation CompassPoint (Iteration)
+ (NSArray *)allValues
{
    static NSArray *values = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        values = @[ CompassPoint.North, CompassPoint.South, CompassPoint.East, CompassPoint.West ];
    });

    return values;
}

@end

Obviously the syntax for the ObjC sucks, especially in comparison to what we get in Swift. There are lots of different options available for us to make this better in ObjC, but more on that later.

Building Swift-Style Enums in ObjC, Part 1

What Do We Really Know?

It's funny to look at the history of computer science and to examine just how little we actually know about the field. I mean, sure, we have made crazy technological advancements in hardware design and raw performance of compute power, but we still do not actually know very much.

The sad part is, the world of academia1 does not teach this. Instead, they teach the false illusion of how much we know and how we know so much more than those that preceded us. I recently read this quote (which is from a few years back in 2011):

Object-oriented programming is eliminated from the introductory curriculum, because it is both anti-modular and anti-parallel by its very nature, and hence unsuitable for our purposes.

Source: Robert Harper, Professor of Computer Science at Carnegie Mellon University

: .source

Functional programming isn't new. It's been around since the 1950s.

Object oriented programming isn't new. It has also been around since the 1950s.

Can you take a guess how long parallel computing has been around? The 1960s…

The point is simply this: this stuff isn't new, we are just trying to figure out how to best apply our thinking and make machines do what we tell them to and really, only what we tell them do. I'll tell you a secret: we still do not know how to do this stuff. Yes, we can accomplish things, and sometimes great things. But at the end of the day, we do not have a lot of good answers to solve all of our problems, most of which have been around for nearly 70 years now.

I believe there is a fundamental reason why all of the paradigms (let's use the big three: imperative, object oriented, and functional) we have for coding break down in various problem spaces: we need all of them. If we instead thought of the problem space more like we do physical sciences, I think we can come to a better realization of this. Just as we need biology, physics, and mathematics we also need our imperative, object oriented, and functional programming paradigms. Each are a more natural fit for different problem domains, but when used together, provide a more holistic approach to our understanding of one another.

  1. I'm perfectly aware that this is a broad generalization. This is based on my time there, my experience with others come out of there, and what I see main stream colleges teaching. It's really, really, sad when a PHD graduate comes into my office and struggles with writing basic code… but this is starting to digress a bit further than anticipated.
What Do We Really Know?

How Much Is Enough

I was driving back from lunch with a friend today thinking about Swift, its strongly-typed nature, and the arguments I've heard about why strongly-typed is so much better. I do not know how to explain my position very well to someone else because a lot of it is subjective.

But then I remembered a poem I've seen at Jimmy Johns.

The American investment banker was at the pier of a small coastal Mexican village when a small boat with just one fisherman docked. Inside the small boat were several large fin tuna. The American complimented the Mexican on the quality of his fish and asked how long it took to catch them.

The Mexican replied, "only a little while."

The American then asked why he didn't stay out longer and catch more fish?

The Mexican said he had enough to support his family's immediate needs.

The American then asked, "but what do you do with the rest of your time?"

The Mexican fisherman said, "I sleep late, fish a little, play with my children, take siesta with my wife, Maria, stroll into the village each evening where I sip wine and play guitar with my amigos, I have a full and busy life."

The American scoffed, "I am a Harvard MBA and could help you. You should spend more time fishing and with the proceeds, buy a bigger boat, and with the proceeds from the bigger boat you could buy several boats. Eventually, you would have a fleet of fishing boats. Instead of selling your catch to a middleman you would sell directly to the processor, eventually opening your own cannery. You would control the product, processing and distribution. You would need to leave this small coastal fishing village and move to Mexico City, then LA and eventually NYC where you will run your expanding enterprise."

The Mexican fisherman asked, "But, how long will this take?"

To which the American replied, "15-20 years."

"But what then?"

The American laughed and said that's the best part. "When the time is right you would announce an IPO and sell your company stock to the public and become very rich, you would make millions."

"Millions?" asked the fisherman, "Then what?"

The American said, "Then you would retire. Move to a small coastal fishing village where you would sleep late, fish a little, play with your kids, take siesta with your wife, stroll to the village in the evening, sip wine and play your guitar with your amigos!"

I'm the Mexican fisherman and you're the American telling me how great strongly typed languages are.

How Much Is Enough

My Swift Dilemma

Author's Note

I've tried to use this piece to capture my current thoughts on Swift, the troubles that I've had with it, and provide a reflection of the state I'm currently in on the benefits of Swift. Your experience will undoubtedly be different than mine, but maybe someone will find this helpful in their pursuits.

The v1.0 release of Swift has come and gone, and v1.1 is right around the corner. My thoughts so far can be summed up as this: the hype of Swift is over for me – I want my ObjC 3.0 language. I'll keep trucking along in Swift for the projects I can, but at the end of the day, I'm, on the whole, fairly disappointed in the language.

The truth of the matter is that I really, really, wanted to like Swift. Much of the Objective-C syntax is clunky, bolted on, and downright infuriating at times (I'm looking at you block syntax). However, the power and flexibility the language provided in its relatively minuscule ruleset should not be overlooked.

But it is.

I've tried many different projects with Swift from algorithms to data structures to solutions for working with structured data like JSON; pretty much everything short of a full-blown app. Around every corner I've been met with frustration due to design limitations, bugs, performance issues, poor debugger support, and what ultimately comes down to design choices. It's this last group that has me the most disheartened.

I look at the feature set of Swift, and I have to ask myself the question: what's the point? What is really trying to be solved? And does it provide significant benefits over languages that already exist? Does it provide a significant benefit over Objective C?

If we stand back and objectively evaluate Swift, I cannot find anything that is truly notable between itself and other languages besides the built-in ObjC interop. However, we know why this is the case: the language is designed by Apple, all of Apple's APIs are written in ObjC, and Swift has no alternative to those APIs. Thus, for Swift to ever have a hope of becoming the de-facto language for Apple development, Objective-C interop is simply a must have.

I said it in my initial gut reaction to Swift, and after mustering through the full 1.0 release of Swift and part of the 1.1 release, my initial reaction is still pretty much the same: we didn't get a better ObjC; we got Apple's take on a better, more modern C

I, for one, am not overly encouraged by that.

Examples

Let's take a look at some of the examples that represent the "goodness" of Swift.

Throughout, I'll be using the label "objc3" when referring to my envisioned improvements over ObjC 2.0. I'll also be throwing in "fobjc" for my take on a functional version, just for my own amusement, of ObjC heavily influenced by Haskell.

Modern Syntax

This is taken directly from the front page about Swift: Introducing Swift.

let stringArray = [ "Bob", "Frank", "Anne" ]
var sortedStrings = sorted(stringArray) {
    $0.uppercaseString < $1.uppercaseString
}

swift

What we see here is the simplest way Swift can express a function that takes a closure as a trailing parameter, infers the types of the arguments, and makes use of operator overloading to actually perform the comparison. I will not argue that this is not indeed extremely clean and terse. However, I would argue that it is loaded with an extreme amount of hidden complexities and ambiguities.

The first, what is the type of $0 and $1? In this case, because the definitions are so close, it's obvious that they are String instances. But code is never this clean.

The second, what < operator is actually getting called? No idea… but since we can infer that the types are Strings, we can make a guess that < is one defined to take two String arguments. However, we cannot actually go to the definition of it to make sure.1

For the third, we just happen to know that there are only two arguments, well, at least only two arguments that we care about, in the closure that is being passed in.

The fourth is the type of stringArray variable – it's an array of Strings because the values in the array are all of the type String.

It's not that any single one of these ambiguities cause issues, it's that your code becomes littered with all of these little subtleties. Sure, one can CMD+Click to see what the compiler thinks the type is, but that only works when working within Xcode. For code reviews on GitHub? Forget about it. Also, this can have a severe impact on the performance of code compilation. There's little I hate more in programming than changing valid syntax to something else simply to make the compiler happy.

Ok, so let's take a look at the code with the ambiguities removed:

let stringArray: [String] = [ "Bob", "Frank", "Anne" ]
var sortedStrings = sorted(stringArray, { (lhs: String, rhs: String) in
    return lhs.uppercaseString.compare(rhs.uppercaseString) == NSComparisonResult.OrderedDescending
});

swift

Well, that certainly sucks compared to the first example2. But this is one of my points: it's the syntactic sugar that makes the syntax modern, not the feature set within Swift itself. A cleaner ObjC could have done the same thing.

For good measure, let's take a look at two ObjC implementations if we were to create our own high-level sorted function.

NSArray *stringArray = @[ @"Bob", @"Frank", @"Anne" ];
NSArray *sortedStrings = sorted(stringArray, ^NSComparisonResult(NSString *lhs, NSString *rhs) {
        return [lhs compare:rhs];
    });

objc

We could strip the types and just use the loose types as well:

id stringArray = @[ @"Bob", @"Frank", @"Anne" ];
id sortedStrings = sorted(stringArray, ^NSComparisonResult(id lhs, id rhs) {
    return [lhs compare:rhs];
});

objc

There's no question that the first Swift example is the cleanest, but not by much. Really, the biggest eyesore in the last ObjC example is the @ requirement for arrays and strings. Simply removing that would result in this code:

let stringArray = [ "Bob", "Frank", "Anne" ]
let sortedStrings = sorted(stringArray, ^NSComparisonResult(id lhs, id rhs) {
    return lhs.compare(rhs)
});

objc2+

If we had some of the Swift features and created a functional version of ObjC, the code might look like this:

let stringArray := [ "Bob", "Frank", "Anne" ]
let sortedStrings := sorted (lhs rhs => compare lhs rhs) stringArray

fobjc

This uses the following constructs from Swift:

  1. The let construct to define an immutable instance. The stringArray contents can never be changed. 2. Type inference for declaration when it is explicit. The [] brackets return an Array instance, as well as the sorted function. 3. The block definition doesn't need to be repeated in the declaration. 4. Dropping the @ for type declarations. 5. Drop the semicolons.

There are a few other changes as well:

  1. The usage of := for assignment. This reduces the problem with = not being associative. For example, x = 5 and 5 = x are not the same thing in computer languages, but in all fields of mathematics, they are. 2. Closure declarations use the => (fat arrow) syntax. 2. Functions are structured functionally, that is, the data being operated on are the last inputs.

Any way you look at it, this example is an extremely poor example of how "Swift" modernizes our existing ObjC code.

Optional Types

Another change in Swift was the advent of Optional. The problem is not with the concept, but the application and the attempt and creating the ? and ! operators/syntax to work with them all over the place. The biggest source of these issues arise from the ObjC bridging as the APIs in ObjC can sometimes return nil even when they shouldn't. This results in the oh-so-awesome "implicitly unwrapped optionals".

Here's the rub, it's never safe to use implicitly unwrapped optionals because they can actually be nil. Using these nil optionals will result in a runtime crash. That's bad.

func foo(string: String!) {
    assert(string != nil)
}

let str1 = "Some String"
let str2: String! = nil

foo(str2)

swift

Fortunately, the use of these should be limited to ObjC bridging. However, the construct is available for general use in Swift; that is not good.

The other side of the problem comes with how we use and unpack optionals. There is only one straight forward way3 to do it that is safe.

let string: String? = "Some optional string"
if let string = string {
    // now we can use the non-optional value of string
}

swift

If we want to do anything in the error case, we need to construct the if-let-else block4.

let string: String? = "Some optional string"
if let string = string {
    // now we can use the non-optional value of string
}
else {
    // handle the case where there is no value
}

swift

However, this is seldom the code we ever want to write as we often times want to do validation on the optionals.

if string == nil {
    // handle the error case
}

// later in the code

if let string = string {
    // use the non-optional value
}

swift

In the above case, we end up working the optionals in various ways. Over the various Xcode betas, this pattern has changed because of various usability problems with each of the various incarnations.

For me, the problems really boil down to this:

  1. The equality check against nil is semantically wrong. It's not nil, it has no value. 2. To avoid nested if-let constructs, we need to use the unwieldy switch statement syntax. 3. The existence of implicitly unwrapped optionals defeats the entire purpose of the safety they are supposed to be provide in the first place.

Functional

Swift is said to open up the world of functional programming to Apple developers. It is definitely true that some things are easier to do with Swift, especially if you make use of operator overloading. But really, how much better is it over Objective C?

High Order Functions

Let's take a look at map as one of the examples.

The map function takes a set of data, performs an operation on each component, and returns a new set of data back to the caller.

NSArray *map(id (^transform)(id element), NSArray *array);

The ObjC version simply takes a block to transform the element, the array to work on, and returns a resulting array.

func map<S : SequenceType, T>(source: S, transform: (S.Generator.Element) -> T) -> [T]

The Swift version does essentially the same thing, though in a slightly different order.

Let's say we want to return a new array of all uppercase strings.

NSArray *names = @[ @"Bob", @"Frank", @"Anne" ];
NSArray *unames = map(^(id element) { return [element uppercaseString]; }, names);

objc

let names = [ "Bob", "Frank", "Anne" ]
let unames = map(names) { $0.uppercaseString }

swift

There is a pattern emerging here… Again, I will not argue that the Swift code does not look nicer, because it does. However, if we were building a truly modern ObjC language, we could have still done all of these niceties.

let names := [ "Bob", "Frank", "Anne" ]
let unames := map(x => x.uppercaseString(), names)

objc3

let names := [ "Bob", "Frank", "Anne" ]
let unames := map (elem => uppercase elem) names

fobjc

Chaining

The other aspect we'll look at it is chaining and we'll do this in the context of applying transformations to an object.

Our scenario will be simple; we'll start off with a list of names and the goal will be to apply the following filters to the list of names:

  1. Convert each name to uppercase 2. Removed names that start with ‘A' 3. Reverse the order of the names

Now, this is going to be the section where Swift comes out the clear winner. The reason will become clear shortly.

The final code will look like this:

id names = @[ @"Anne", @"Bob", @"Frank" ];

id names1 = toUpper(names);
id names2 = filterNames(names1);
id names3 = doreverse(names2);
NSLog(@"names3: %@", names3);

id result = doapply(@[toUpper, filterNames, doreverse], names);
NSLog(@"result: %@", result);

id nested = doreverse(filterNames(toUpper(names)));
NSLog(@"nested: %@", nested);

objc

let names = [ "Bob", "Frank", "Anne" ]

let names1 = toUpper(names)
let names2 = filterNames(names1)
let names3 = reverse(names2)
println("names3; \(names3)")

let filtered = apply([toUpper, filterNames, reverse], names)
println("filtered: \(filtered)")

let nested = reverse(filterNames(toUpper(names)))
println("nested: \(nested)")

swift

From this perspective, things are looking pretty much the same. Swift, of course, has the advantage of many of the high level functions that we'll need to use already being defined, namely: map, filter, and reverse.

Note that I had to prefix the ObjC implementations of mentioned high level functions with ‘do' as some of the names were already taken in the global space.

So let's take a look at implementing toUpper and filterNames:

typedef NSArray*(^filter_type)(NSArray *);

filter_type toUpper = ^NSArray*(NSArray *array) {
    return domap(^(id e) { return [e uppercaseString]; }, array);
};

filter_type filterNames = ^NSArray*(NSArray *array) {
    return dofilter(^BOOL(NSString *e) {
        return ![e hasPrefix:@"a"] && ![e hasPrefix:@"A"]; }, array);
};

objc

Well that's looking pretty ugly… So why blocks instead of straight C functions? A few reasons:

  1. Blocks are functional objects for ObjC. 2. You cannot put C functions into an NSArray5. 3. Parity with semantic meaning between the function declarations between our Swift and ObjC implementations; there's not context in which our blocks cannot be used but the Swift functions can. This would not be true if C functions were used.

The Swift version looks a lot cleaner:

func toUpper(array: [String]) -> [String] {
    return map(array) { return $0.uppercaseString }
}

func filterNames(array: [String]) -> [String] {
    return filter(array) { return !$0.hasPrefix("a") && !$0.hasPrefix("A") }
}

swift

The biggest problem with the ObjC version thus far has been the horrible block syntax that Swift has unquestionably made significantly better.

If we had the mystical new ObjC language, the ObjC code might have looked like this instead:

func toUpper(array: NSArray) -> NSArray
    return map(x => x.uppercaseString, array)
end

func filterNames(array: NSArray) -> NSArray
    return filter(x => !x.hasPrefix("a") && !x.hasPrefix("A"), array)
end

objc3

toUpper :: (array: [String]) -> [String]
toUpper array := map (x => uppercase x) array

filterNames :: (array: [String]) -> [String]
filterNames names := filter (x => not contains (prefix x) ["a", "A"]) names

fobjc

Swift does have a clear advantage over ObjC today: we could rewrite the apply function as a new operator. However, this is a very powerful feature that can lead to much ambiguity in your code; it should always be used with great care and consideration.

infix operator >> {
    associativity left
}

func >> <T>(lhs: [T], rhs: ([T]) -> [T]) -> [T] {
    return rhs(lhs)
}

let names = [ "Bob", "Frank", "Anne" ]
let result = names >> toUpper >> filterNames >> reverse
println("result: \(result)")

swift

Even with all of these niceties, Swift is no more functional than C# is, and really, ObjC can be. The fact that you can curry certain functions and create special operators makes it appear more functional than it really is. While those things lend itself to better functional approaches with less syntax, they do not make Swift a functional language.

That's ok, but we would simply stop calling Swift a functional language.

The Road to Hell is Paved with Generics

If you've made it with me this far, then I'll probably lose many of you here…

I hate generics. I don't just dislike the concept of generics, I hate the extremism that generics forces onto your code. Once you move to generics in your code, you, by definition, give up an extreme amount of flexibility in your code base. In exchange, you are supposed to get back improvements in type safety, code reduction, and performance. What no one talks about though, is the cost to write that code, to debug that code, and to understand that code, especially as generic systems get more and more "feature rich".

The canonical example that I also see with generics is typed collections. This is absurd on many counts. First, this is often touted as the way to solve this problem. It's not, it's one of several ways to fix this problem. The issue here is that every solution has benefits and drawbacks to them. However, for some odd reason, few seem to think generics brings anything bad to the table.

func reverse<C : CollectionType where C.Index : BidirectionalIndexType>(source: C) -> [C.Generator.Element]

WTF? Really, nothing bad to the table? And mind you, that's a very simple generic declaration. Compare that to this:

func reverse(source: CollectionType) -> CollectionType

I'm not a compiler author. I'm not one that gets excited about enforcing that every item in your collection is of type String. Why? Because it does not actually matter. If an Int gets in my array, it's because I screwed up and likely had very poor testing around the scenario to begin with.

var names = [String]()
names.append("David")
names.append("Frank")
names.append("Sally")

swift

var names := NSArray()
names.append("David")
names.append("Frank")
names.append(90120)

objc3

Uh… oops. Whatever… let's say I really, really wanted to ensure that all of my containers contained on a single type of element. How else might I do that without generics?

var names := MYTypedArray(x => return x.isKindOfClass(NSString.class))
names.append("David")
names.append("Frank")
names.append(90120)   // runtime exception

objc3

Yes, in this example, I've moved the validation from compile-time to runtime. But you know what, that's likely where many of these types of errors are going to be coming from to begin with because the content of the array is being filled in with dynamic content getting coerced into your given type at runtime from dynamic input sources, not from a set of code statements appending items to your arrays.

To me, the cost of generics is extremely high and brings little to the table that cannot be solved via other means, namely code generation and protocol conformance. Using those two patterns, you can achieve nearly everything that generics brings to the table without enforcing the extreme type system that it requires to function. These come at a cost too, I just find that cost significantly smaller.

Of all of the changes to Swift, generics is the #1 reason why I'm very hesitant to move forward with it. Yes, I miss many of the other features of ObjC, but this one tops the cake because it drastically decreases my ability to quickly write code.

A Lot More to Say

There's a lot more to say about my experience with Swift, and maybe I'll cover it more in the future. Some of the topics that I did not cover are:

  1. The baggage that the Swift language has because of ObjC. 2. The compile-time performance of Swift in anything but small projects. 3. The sheer number compiler bugs that need to be worked around just to make your code work as intended. 4. The lack of reflection. 5. The inability to create Cocoa, arguably one of the best platform frameworks, in Swift because design choices. 6. The terrible debugging support.

I'm not trying to claim that Swift is a terrible language, it's not. There are parts of it that I really enjoy, such as many of the improved syntax features. But at the end of the day, when I ask myself the question of whether it's going to make me more productive as both an app developer and a framework author, the answer for me is clear: "not yet".

Do I think that will ever change?

I honestly do not know.

  1. This is strange and must be a regression or limitation of built-in operators. At one point in time, I was able to go CMD+CLICK on operators and see which one was being invoked.
  2. There's an interesting bug in Xcode 6.1 Beta 2 as well. Without the lhs: String annotations in the closure definition, Xcode cannot actually provide you the proper completions for either $0 or lhs. A point-in-time deficiency in the tooling most likely, but still an issue we need to suffer through now.
  3. It's also possible to use switch and pull out the optional values as well, but that is more complicated, especially in the single optional case.
  4. Yes, we can use the switch-statement as well. However, I find it offers no distinct advantage in these single optional cases. The pattern is more helpful when we have multiple optionals though.
  5. Ok… you can, but you have to box the function pointer and it's a complete mess…
My Swift Dilemma