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

Striving for Simplicity

When I was working on the my new blog layout, I had two primary goals in mind:

  1. Cleaner feel with better functionality
  2. Seamlessly integrate with the tools I enjoy

Tidy up the Mess

I think I've captured #1 well enough, for my tastes anyhow. I know that there are bugs in the site layout1, but in the spirit of my "ship early and ship often mantra", I think it's more important for me to get the results that are "good enough" out there so that I can improve the things that matter and to catch issues that I simply will not run into2.

Workflow Improvements

Another way to capture this is: "quality of life improvements".

My writing tool of choice is Ulysses. I think it's great. It offers nearly everything I want in a Markdown editor. However, I write technical content with code snippets. My previous workflow was a bit terrible:

  1. Write the initial post in Ulysses
  2. Apply the kramdown syntax using Brackets
  3. Run jekyll serve -w to view my blog update
  4. Go back to step 2 for any edits

You see, once I move from step 1 to step 2, I cannot actually use Ulysses to do the editing anymore. Some of this is because of quirks with the app, others because of limitations of not supporting the kramdown syntax, or fenced blocks well.

But here's the thing: I really like Ulysses and using that tool is more important.

So, with the new blog design, I set out on how I can remove step 2 from the process. It's going to be just me and my editor. I know exactly what the markdown should look like in Ulysses, so there is no need to "preview" the pages anymore. Simply write, edit, and push. Done.

Optimize for You

The moral of the story is quite simple: optimize for the things that are important for you. When you do that, realize that you need to make compromises in other areas.

That's OK.

Here's a sample of what my new layout should look like for a full content blog post: https://owensd.io/sample.html.

With one exception, I am able to achieve all of what I want with standard markdown3. I find that very liberating4.

  1. Especially in IE11… oh man is that a train wreck. It's probably just some CSS prefix I forgot, I'll get to to it. =)
  2. I run with the OS X setting of "Show scroll bars: When scrolling" option. This means I never see those large fat scroll bars, even when I have an external mouse plugged in. Of course, others run with a different option and that exposed some bugs in my design.
  3. The actual standard… http://daringfireball.net/projects/markdown/
  4. If you're interested, the exception is the need to apply a specific class to the blockquote I use for image captions. I cannot figure out how, with CSS only, to select that nested blockquote and style it how I want.
Striving for Simplicity

The Problem with Enums

In a bit of back and forth on Twitter about tuples, structs, and enums, Chris wrote up a good overview of why you might use one or the other. Check it out here: Tuples, Structs and Enums. It's a good read.

Here's my dirty secret: I really dislike enums for exactly the reason they exist. The entire purpose of an enum is to solve problems like Chris mentions, "In the previous example, we've used String to use the currency, but what if we want to restrict our program to only currencies we know about?".

I emphasized the problem, well, my problem with enums: a complete lack of extensibility in the case options.

If you build a library that handles currencies and model them with enums, you have forever locked your users into using the currencies you have explicitly allowed in your enum definition.

Take Chris' example:

enum Currency {
   case EUR
   case USD
   case YEN
}

If you, as the consumer of the library, want to add CAD to the set of supported currencies, you are out of luck.

You can get the source code and make changes, sure. However, then you need to manage two different versions unless you can get that change pushed back. This is not always possible though.

Whenever you make an enum, ask yourself the question: do I need to constrain this a specific set of possibilities (Either is a good example), or do I need to constrain it to a certain class of possibilities. It might actually be more appropriate to use a interface instead.

An example of that would be the following:

private let usd = USD()
private let eur = EUR()
private let yen = YEN()

protocol CurrencyType {
    class var currency: Self { get }
    class var symbol: String { get }
}

final class USD : CurrencyType {
    class var currency: USD { return usd }
    class var symbol: String { return "$" }
}

final class EUR : CurrencyType {
    class var currency: EUR { return eur }
    class var symbol: String { return "€" }
}

final class YEN : CurrencyType {
    class var currency: YEN { return yen }
    class var symbol: String { return "¥" }
}

typealias Currency = (value: Int, currency: CurrencyType)     // or as a struct

let usd = Currency(5, USD.currency)

There are many other ways to model what I did above; this is just an illustrative example.

I really wish Swift would have solved the problem of case extensions for enums in Swift. It would help in these cases where we really do want a nice set of possible values, but we would also like to have the ability for others to extend those cases in their own code.

The Problem with Enums

Tuples Are The New Struct – Revisited

Yesterday I wrote about thinking about using tuples in place of your dumb data types. However, my example used a class of problem that was typically modeled using an Either<T,U> type. That, understandably, added some confusion that was not intended.

Today, let's instead take a look at an example that is hopefully a little less contentious: the Point type (just two-dimensional).

At a quick glance, I see the following as ways in which we might model the Point type as a tuple, struct, class, or even as an enum.

Here's some sample uses for each of them:

Tuple

typealias Point = (x: Int, y: Int)

let p = Point(2, 6)                   // Point(x: 2, y: 6) is also valid
println("(x, y) = (\(p.x), \(p.y))")

Struct

struct Point {
    var x: Int
    var y: Int
}

let p = Point(x: 2, y: 3)
println("(x, y) = (\(p.x), \(p.y))")

Class

class Point {
    var x: Int
    var y: Int

    init(x: Int, y: Int) {
        self.x = x
        self.y = y
    }
}

let p = Point(x: 2, y: 3)
println("(x, y) = (\(p.x), \(p.y))")

Enum

enum Point {
    case Components(Int, Int)
}

let p = Point.Components(2, 3)
switch p {
case let .Components(comp):
    println("(x, y) = (\(comp.0), \(comp.1))")
}

Now, each of the above approaches has positives and negatives to their approaches. However, to me, the tuple has all of the right behavior out of the box. The enum based approach is the most verbose and I'm unclear of any distinct advantage it has over both the tuple and struct/class options.

If you're anything like me, you might tend to write your code in stages:

  1. There's the initial prototyping and scaffolding to make sure your thoughts apply to code.
  2. Then the roughing in with types and better names.
  3. Finally we get to the flushed out public API surface.

Along the way there is a lot of back and forth between the stages. I tend to start with the least amount of code so that it's easier to through away. So, in flushing out my API, the Point might remain a tuple throughout all of the stages.

Also, by starting with a tuple, I have to specifically ask myself the question: do I really need to add this function or private data here? Is there a better way to model this?

Don't forget about the tuple. Of course, your mileage may vary.

Tuples Are The New Struct – Revisited

Tuples Are The New Struct

I published a "revised" look at this that uses a less controversial example as people were getting stuck on this example being an Either<T,U> (enum based) instead of looking at structs vs. tuples.

: .info

I've been playing around with using named tuples instead of structs for pure data types. One such use case was in returning errors from a function.

Let's say we a function foo and we want to return an Int or an Error?. There are lots of ways to model this: structs, enums, tuples, inout parameters, global error state, etc…

Of course, each has their positives and negatives. However, I want to look at what the difference of the struct and the tuple implementation looks like.

The function definition will look like this:

func foo() -> IntOrError {}

The struct would look like this (Error is my own custom error type, you could use NSError too):

struct IntOrError {
    let value: Int
    let error: Error?
}

The tuple would look like this:

typealias IntOrError = (value: Int, error: Error?)

Usage of the two looks exactly the same:

let result = foo()
if let error = result.error {
    println("Uh oh! An error occurred")
}
else {
    println("The value is: \(result.value)")
}

So should you use tuples? Well, I don't know. =) There are two big disadvantages of the tuple approach:

  1. No generics support; I cannot create: typealias ErrorOf<T> = (value: T, error: Error?). I consider this a deficiency in the generics system of Swift though.
  2. No ability to add functionality to the type itself; essentially no OOP-style programming. This also extends to specific initializers.

However, the I see some benefits for the tuple approach too:

  1. Much faster prototyping while maintaining good readability of code
  2. Currently (as of Beta 6), tuples as return types perform much better than structs. This should get better though. Update: I think the root cause of this was due to rdar://18111139: Swift: Optimizer Perf Bug with inline/external class definitions.
  3. "Upgrading" to a full-blown struct requires only updating the definition of your code (beware, this would be a breaking change for code linking your code though).

If all you need is a dumb data type, try out the named tuple!

Tuples Are The New Struct