November 17, 2015

Zero Dependencies

Backchannel is streamlined way for app developers to gather feedback from beta testers, right within their apps. Backchannel lets both developers and their beta testers comment on and discuss feature requests, bug reports, and general feedback about the app.

Last week, I wrote about how the classes of the Backchannel SDK are all under 250 lines of code. This week, I'd like to discuss the experience of writing a significant application with zero dependencies.

Not having any dependencies makes it a lot easier for developers (your customers!) to incorporate your code into their project. You're assured that your dependencies won't clash with their dependencies, no extraneous weight will be added to your customer's projects, and that your dependencies won't add any categories or swizzling to your customer's projects.

When I started out writing Backchannel's SDK, I had just come off the heels of releasing Instant Cocoa, which is a library I created for reducing the intense amount of boilerplate we have to deal with as iOS developers. It includes abstractions like data sources, which map index paths to objects, or resource gateways, which provide a clean interface for touching REST APIs through model objects.

I wanted to use all of this code that I had meticulously spent a year and half writing and perfecting and genericizing. However, I knew I couldn't include it. It wouldn't have been fair of me to expect other developers to import an enormous library of mine into their app just so that my development experience could be nicer.

So I turned this limitation into a feature. Not only would Backchannel not have my library, but it wouldn't have any dependencies at all. It would be a bit more work, but the developers using it would appreciate it, and that would make it worthwhile.

I had to rewrite a few of the Instant Cocoa features, like data sources. Data sources in Instant Cocoa are a lot more generic, allowing you to mix, match, and combine them in interesting ways. Since Backchannel doesn't need any of that, it was all reduced to one simple data source, that allows for a list to be downloaded from an API, mapped to local domain objects, and presented to a table view.

Preventing Instant Cocoa from being in the project meant that the code was more tightly focused and easier to understand. BAKCache or BAKSendableRequest are two other examples of classes with interfaces that were limited to exactly what I wanted them to be.

Writing an application with zero dependencies means you have to take responsibility for every line of code in your app. You can't offload networking, persistence, object mapping, or any other component to someone else's code. It's just you, UIKit, and Foundation.

Backchannel was going to need Keychain access (to store the user's API access token). I didn't know much about how the Keychain API worked. I'd only heard that its API was bad, and to use something like Apple's GenericKeychain to wrap it.

I set off looking for GenericKeychain, so that I could copy it into my project. When I found out, I realized that there's no way I could take responsibilty for that code. GenericKeychain is a mess, barely better than the C API it wrapped. (In a future blog post, I'm hoping to go into GenericKeychain as a case study of how not to write classes.) I spent about a day understanding how Apple's code worked, and wrote my own wrapper around the Keychain API, with exactly the API I wanted and the features I needed, and thus BAKKeychain was born.

The networking API was another example of code I had to design myself. Other networking libraries couldn't be relied upon. For example, AFNetworking puts a category onto UIImageView, which could conflict with code that the developer has already written.

I turned the experience of creating a networking layer into a blog post series, analyzing what was wrong with the currently available strategies, how I structured my version, a follow up on advanced techniques like pagination and mulitipart requests, and a follow up with a Swift version of the same ideas. Writing my own networking code cost some development time, but I can now stand behind the code, because I wrote it and understand it fully.

A few weeks ago, Ben Sandofsky wrote about minimizing usage of libraries. He argues for being very circumspect about which libraries you decide to import. I agree with all of his points, but I will go a step further and say that it's even more instructive to limit yourself to zero dependencies. What kind of abstractions will you make when you aren't bound by the ways others have solved the same problems?

I found that I solved the problems in new and interesting ways, and many of those lessons are applicable in other apps as well. I'll almost definitely be bringing the new networking concepts to Instant Cocoa and removing its dependency on AFNetworking.

Making a hard rule like "no dependencies" is a great way to test the limits of your code writing ability and forces you to get creative and make some awesome stuff.

I've heard that John Carmack begins every new game he works on by writing the simple functions he needs and building everything up from little pieces. He doesn't even copy and paste his implementations from previous versions, preferring to write them from scratch. I've always been dismissive of that idea, but who knows? Maybe I'm coming around.

November 12, 2015

Keeping Your Classes Shorter Than 250 Lines

Backchannel is out, and so is its SDK. I wanted Backchannel’s code to be as polished as possible, to help build trust with other developers. Having no categories, no dependencies, and no weird tricks like swizzling is essential for building that trust, but, ultimately, the code needs to be easily readable.

One way that Backchannel’s SDK maintains its readability is through simplicity. No class in Backchannel is longer than 250 lines of code. When I was newer at programming, I thought that Objective-C’s nature made it hard to write short classes, but as I’ve gotten more experience, I’ve found that the problem was me, rather than the language. True, UIKit doesn’t do you any favors when it comes to creating simplicity, and that’s why you have to enforce it yourself.

Ben Orenstein, in his Simple Rules for New Programmers, says

Just as your classes should contain tiny methods, so should your system be built of tiny classes.

The critical epiphany for me was that if the same amount of code is spread among much smaller classes, there will have to be a lot more classes.

So, how does Backchannel maintain its small class sizes? A lot of classes. If I could come up with a name for it, I made it into a new class. If it was reused code, I figured out a name for it and made it into a new class. Since the code is open-source, I want to touch on some specific techniques here.

Backchannel’s SDK is essentially a whole app that lives inside your app, so the techniques here are as applicable for a regular app as they are for an SDK.

First, and most important, I stuck to a consistent pattern of code. In a normal app, your app delegate creates a UIWindow and sets up your root view controller. From there, each view controller pushes on more view controllers as needed. Instead, in the Backchannel SDK, I used Coordinators to manage the high-level flow of each task, and pushed extraneous code I could down to children of the view controller. This helped take as much stuff as possible out of the view controller. Taking authentication as an example, this involved using:

By breaking each of these things down further and further, when a new change came in, it was obvious where to add the code to start working on that feature. Good naming also enables other developers to take a look at the file names and guess where they might want to start editing.

Line length isn’t a perfect metric for complexity (there are others), but it makes a great first approximation, since it’s so easy to determine. One of the most complicated classes in the Backchannel SDK is the message creation coordinator, with three different initializers and the task of coordinating between many small pieces. It’s no coincidence that it’s also one of the longest files. It’s also a ripe target for refactoring and breaking up.

Managing complexity by adding classes is the key here. The second technique I want to touch on is using different classes for similar concepts that are used in different ways. For example, the Backchannel SDK includes both BAKDraft and BAKMessage.

Even though they both have many similar properties, like a text body and an array of attachments, they serve different purposes: BAKDraft is used as a data clump for the data that the BAKMessageFormViewController generates, and BAKMessage is the message’s representation after it’s created in the API and includes information about display metrics and user permissions. BAKMessage has room to grow to handle new things from the API, whereas BAKDraft might expand into a persistent format for saving drafts that the user is working on.

These two objects are nominally the same thing, and it might have been possible to use BAKMessage in the place of BAKDraft. Nevertheless, the two concepts fill different roles, have different capabilities and benefit from being separate. Shoehorning them into the same class would be ugly, inelegant, and restrictive.

Finally, there are concepts that you know will need to be encapsulated and separated into their own space, but don’t lend themselves easily to a name. Without a good name, it’s hard to tell what should be in the class and what shouldn’t. In those cases, I find that the best way to develop the identity for the class is not through its name, but rather through its members.

For example, in Backchannel, images upload in the background while the user types out the rest of their message. If the user taps the “Post” button while images are still uploading, posting is delayed until all of the images have uploaded. This definitely sounds like a bit of state I want to encapsulate, potentially with a dispatch_group_t. I built an object around this dispatch group, and it eventually became BAKAttachmentUploader.

I think that name is ultimately pretty weak (a rough rule for me is if the class name ends in -er, it’s not the best name). The class’s name doesn’t really reveal what its interface should be. However, I knew that my class would have a method like - (void)waitForAttachmentUploads:((^)())block and it identity would revolve around the dispatch group, and so a new object was born.

There’s lots of little objects (they might even be enums or structs in Swift) in the Backchannel SDK that perform little tasks into which I won’t go into depth here. (Some interesting ones to explore are BAKMessageCreator, BAKAuthenticationData, or BAKErrorPresenter.) While practicing the technique of making more little objects than you’re used to, it might be worthwhile to play a game with yourself to find out what the smallest interesting object you can make is. If it encapsulates a useful piece of logic or data, you might find that you like having it around.

To find the 20 .m files with the longest length, you can use the following bash command from inside your iOS project repo:

find . -name "*.m" -type f -print0 | xargs -0 wc -l | sort -rn | head -n 20

Pick one of those files and refactor it until it’s not in the list top 20 anymore. Continue until you’re happy.

November 4, 2015


I'm proud to announce the project that I've been working on for the last few months. Backchannel is a tool for feedback inside your beta.

Instead of traditional feedback mechanisms that let the tester only communicate with the developers, Backchannel aims to open up that discussion to everyone. By allowing the testers to talk to each other and see what bugs have been reported, Backchannel removes the chilling effect of "ehhhh, somebody else probably reported this bug already".

A feature that I'm really excited for in Backchannel is screenshot detection. When users want to report bugs, their first move is going to be to take a screenshot of the bug. When that happens, we'll prompt the user and ask if they want to report that screenshot as a bug. If they indicate that they want to report a bug, Backchannel will show them the relevant form and attach the image for them.

Backchannel's SDK is written to exacting standards. I've used a lot of bad SDKs, and I didn't want to subject developers to another shoddy library. It's open-source, so feel free to take a look under the hood at how the magic happens. Readers who've been waiting for an implementation of coordinators should definitely clone the repo and poke around. The Backchannel SDK a great citizen in your app, with no dependencies, no categories, and no swizzling.

Backchannel wouldn't be what it is without the amazing people who've helped make it a reality. John Gruber and Dave Wiskus have helped tremendously in forming and focusing the idea. The design of the web site and management portal wouldn't be possible without the design chops of Carson Andrews, as well as stellar front-end work by Dustin Horton and Chris Guittierez.

Backchannel is only in its infancy. I'm looking forward to feedback on what corners of the product need to be filled out more. There's a long road ahead. Here's to the start of a great journey.

October 27, 2015

Unrigorous Definitions

A definition of functional programming is very hard to pin down.

Many introductions to functional programming start with map and other higher-order functions, and never really draw the rest of the owl. Since these tools are available even in the most staunchly object-oriented languages, like Ruby, they don’t make for a particularly good definition of functional programming.

The defining component is sometimes simple: parameter order. While I’ve argued before that we should get rid of positional parameters entirely, they’re still an important part of programming today. What’s the difference between f a b and a.f(b)? It’s really just the order of the parameters. (I would also like to submit [a f:b] for examination 😈)

Some definitions of functional programming are more encompassing. The opening paragraph of this Wikipedia article, for examples, suggests that functional programming primarily has to do with math. Languages that are particularly type-heavy, like ML and Haskell, with their monoids and monads, bear this out.

Others define functional programming primarily in terms of immutability, viewing functions as a means to that end. There are posts describing functional programming that talk about immutability before any other feature of the paradigm, including actually using functions.

Some take the immutability claim further. For them, functional programming requires purity of functions, also known as referential transparency — a lack of globals and a lack of side effects. While this purity forms the central tenet of their functional programming, a language like Lisp, the prototypical functional language, has immutability but doesn’t prevent side effects.

Finally, some people think it means using a particular style of programming called Reactive, a set of monads from the functional programming world that are grafted object-oriented languages with libraries such as RxJava and ReactiveCocoa.

This list of defintions itself isn’t complete, but provides a rough outline of the surface of functional programming. Certainly, the variety of styles available even within functional programming belies the blurriness and complexity of the field.

There’s a few of lessons to learn from a list like this. First, people define functional programming in terms of the elements of their favorite functional language or, in some cases, style. If they’re Haskell writers, referential transparency might be the component they focus on. If they’re writing Reactive Cocoa in Swift, that particular mode of programming defines what functional programming is for them.

Second, each of these definitions implies a different prescription for what makes good code. In each case, the practitioners make an argument for why their particular style of functional programming will solve your problems. It’s clear, however, from the breadth of different functional styles and values that there’s no one “real” functional programming. Anyone claiming to sell you the One True Solution to your programming woes should be scrutinized.

Lastly, and there seems to be no way around this: programming is complex. Whatever style of programming you like to use, you’re going to run into complexity. Whether your language lays that complexity bare (like FP), or gives you the tools to abstract it away (like OOP), you’re going to have to roll up your sleeves and apply elbow grease. No programming style will make that go away.

October 22, 2015


A core feature of Cocoa is class clusters. Class clusters are a way of letting a developer mimic a built-in core type by subclassing it and overriding its fundamental methods, called "primitive methods". The simplest example of this is NSArray.

To illustrate, let's use array reversal. The typical way in Cocoa of reversing an array is via the array's reverseObjectEnumerator. It could go in a category:

- (NSArray *)reversedArray {
    return self.reverseObjectEnumerator.allObjects;

This is a fine solution. But we can do something a little different, gaining us some additional efficiency. On NSArray all methods are guaranteed to be written in terms of the two primitive methods, -objectAtIndex: and -count. That means that we can subclass NSArray, override those two methods, and get all of the other NSArray methods for free. For example, we can reverse an array using a new class.

@interface ReversedArray : NSArray

@property (readonly) NSArray *arrayToReverse;


@implementation ReversedArray

- (instancetype)initWithArray:(NSArray *)array {
    self = [super init];
    if (!self) return nil;

    _arrayToReverse = [array copy];

    return self;

- (NSUInteger)count {
    return self.arrayToReverse.count;

- (id)objectAtIndex:(NSInteger)index {
    return [self.arrayToReverse objectAtIndex:self.count - index - 1];


That's it. This is a fully-functioning NSArray. You can use array subscripting, -indexOfObject:, enumerators, sorting, all of it.

At first blush, it's an extreme solution to a simple problem. But there are certain advantages conferred here that I love.

First, this is a fully encapsulated implementation. The implementation can generate its backing array eagerly or lazily, depending on constraints of the device or the whims of the developer. The implementation details are hidden away, as it should be.

Second, we gain a slight performance advantage. With the reverseObjectEnumerator way, a full copy of the array will be made. For large arrays, the class clustered will use less memory and take less execution time. We do call -copy in our class cluster, but assuming the array is already immutable that method will just return self. (If it's not immutable, -copy will create a full copy of the array, and we've lost nothing with the new solution.)

If you're still not convinced, Apple does it this way in their own SDK. Try it out in your debugger. While -reversedArray isn't exposed in the NSArray headers, it is implemented (as of the iOS 9.0 SDK, at least). And calling it returns a specialized class, __NSArrayReversed:

(lldb) po [@[@1, @2, @3] reversedArray]
<__NSArrayReversed 0x7fabfa7184c0>(3, 2, 1)

Putting this implementation inside a category will also allow you to implement it on your subclass efficiently and elegantly:

- (NSArray *)reversedArray {
    return self.arrayToReverse;

The reversed array, reversed again, is just the orignal array. With class clusters, any methods that you want to further optimize you can just re-implement on the subclass.

Class clusters and primitive methods exist for many core types, including NSArray, NSString, NSDictionary, and their mutable counterparts.

On NSString, methods like -stringByAppendingPathComponent: can return a specialized version of NSString that is backed by an array of path components, so that adding and removing path components is as easy as modifying that internal array. Let's check if this is how it's implemented:

(lldb) po [[@"a" stringByAppendingPathComponent:@"b"] class]

NSPathStore2 is a class-clustered NSString exhibits these propreties. The implemenation can be optimized so that this class doesn't have to search for path separators (like "/" or ":"), and it can manipulate paths more easily. (I wonder what happened to NSPathStore1?)

This is a cool tool for your toolbelt. What else can we use this technique for?

The project I'm currently working on has an SDK. I've used bad third-party SDKs before, and I wanted the standards for this project to be higher. I want the developers who are integrating this SDK into their project to rest easy, so the SDK has no categories at all. This was a problem for me, since I wanted to use -map: on my arrays.

This technique is how I got out of that pickle. A class-clustered array that is initialized with a "before" array and a transformation block is all this class needs.

@interface MappedArray ()

@property (nonatomic) NSArray *backingArray;


@implementation MappedArray

- (instancetype)initWithArray:(NSArray *)array transformationBlock:(id (^)(id object))block {
    self = [super init];
    if (!self) return nil;

    NSMutableArray *mappedArray = [NSMutableArray arrayWithCapacity:array.count];
    for (NSInteger i = 0; i < array.count; i++) {
        [mappedArray addObject:block(array[i]) ?: [NSNull null]];
    _backingArray = [mappedArray copy];

    return self;

- (NSUInteger)count {
    return self.backingArray.count;

- (id)objectAtIndex:(NSUInteger)index {
    return [self.backingArray objectAtIndex:index];


Notice here that while the array is backed by a mutable array, it doesn't expose that in any meaningful way. A default implementation of -map: in a category looks like:

- (NSArray *)map:(id (^)(id object))block {
    NSMutableArray *mappedArray = [NSMutableArray arrayWithCapacity:self.count];

    [self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        id value = block(obj) ?: [NSNull null];
        [mappedArray addObject:value];

    return mappedArray;

With an implementation like this, you can forget to call -copy on mappedArray before returning it. It's easy to forget that -copy, which I know because I've done it. If you don't copy, you're actually returning an array that can be accidentally cast to a mutable array. With MappedArray that can never happen, because the mutation methods aren't even implemented.

The class cluster way is definitely more code, but it's more manipulable than the simple category. It can be lazily-loaded (Gist with sample implementation) if you need those performance characteristics. Lazy loading can never be done with the category way. And if you prefer your interface to be a method on NSArray, you can still use the class cluster method from within a category:

- (NSArray *)map:(id (^)(id object))block {
    return [MappedArray alloc] initWithArray:self transformationBlock:block];

The last use for this technique that I want to cover is domain-aware arrays and collections. Because each class cluster is simultaneously an NSArray and whatever its subclassed type is, these arrays can be used in both contexts.

If you had a payroll application, you could create an EmployeesArray class that acts as NSArray. In the same way that -count is a useful method for all arrays, your EmployeesArray can have methods named -totalSalary or -highestPaidEmployee. While you could use KVC collection operators or -reduce to the same end (and perhaps it would be implemented with one of those under the hood), this technique provides you with well-named, well-typed messages. It allows you to be more expressive and clear in your code, and that's always awesome.

Class clusters are an awesome and underused Cocoa feature. These few techniques can help you realize performance and expressiveness gains at the same time.

October 13, 2015

Thoughts on Haskell

In preparation for the monad post (and also for some life goals), I've been working on learning Haskell. What a weird language.

First thing's first. I learned using Haskell for Mac and two books. First, I tried using Real World Haskell, but didn't find it terribly effective. Learn You a Haskell, on the other hand, I thought was extremely well-written and effective at teaching the priniciples. However, I've been trying to read Haskell tutorials (and monad explanations) for a few years, and it's hard to say how much that stuff primed me for being able to understand the language.

I finally feel like I can read Haskell (even if it's with a little trouble), but I'm not writing it super well yet. Nevertheless, this feels like a victory.

I want to skip all the stuff about functional purity, static compilation, strong types, currying, and lazy evaulation. I've read a lot of blog posts about that kind of thing, and I don't think there's anything to be gained from repeating the work of others.

I'm going to talk about some stuff which struck me while learning Haskell. This post is meant for people who write code in languages that are not Haskell, but would like to learn more about the experience of learning it. Like many of my posts, it's for past versions of myself.


Haskell is whitespace significant. This was the most unexpected thing I came across while learning Haskell. I thought we were all in agreement that Python would be the only programming language that maintains structure through whitespace so that we could all ceaselessly make fun of it. Apparently Haskell is also in this hilarious crowd of languages.

It seems like a goal of Haskell is to minimize the amount of punctuation that's used to write code, and being whitespace significant helps with that.


A lot of elegance is borne out of the way that functions are defined in Haskell (and in part I think to its aversion to punctuation). For example, if you wanted a function that filtered out all of the odd numbers in a list and left only the even ones, you could define it "strictly", with xs as an explicit parameter:

filterEvens xs = filter even xs

or more "loosely":

filterEvens = filter even

Because of partial application, we can define filterEvens as a partially-applied version of filter. Since that just returns another function, we can just assign it to the name filterEven and be done.

Because braces or other separating punctuation are optional, creating a function feels a lot more like definition, rather than implementation. These types of functions really lends themselves to succinct, if not one-line, definitions. I think creating functions in this style is a big part of the reason why Haskell's champions describe it as declarative rather than imperative.

Haskell seems to "fit together" really nicely in a lot of ways. Instead of separating the idea of "blocks" from the idea of "functions", they're all the same thing. Anywhere you need a "block" (like the first parameter of filter), you can just pass a function that has the correct type signature.

Another awesome example of this elegance is the quicksort implementation:

quicksort [] = []  
quicksort (head:tail) = 
        smallerNumbers = quicksort (filter (<=head) tail)  
        biggerNumbers = quicksort (filter (>head) tail)
        smallerNumbers ++ [head] ++ biggerNumbers  

It's embarrassing to admit, but I've never understood how quicksort works. Looking at the Haskell implementation, however, makes it painfully obvious.

  1. Quicksort for an empty array is an empty array.
  2. Quicksort for an array with a head and a tail is all the numbers that are smaller than the head, then the head, and then all the numbers that are larger than the head.

(Strictly speaking, this implementation isn't quicksort exactly. A true quicksort implementation requires mutation, something that Haskell steers you away from. Much like the Sieve of Eratosthenes, a real implementation of quicksort in Haskell is much messier. This is a pedantic point.)

Another great example of elegance in Haskell is foldl and foldr. These are the Haskell equivalents of reduce, which start from either the left of a list or the right.

foldl f initial []          = initial
foldl f initial (head:tail) = foldl f (f initial head) tail

foldr f initial []          = initial
foldr f initial (head:tail) = f head (foldr f initial tail)

They're defined recursively, and that lends itself to great simplicity. They're also both defined using the same components, just in a different order. I find myself having to stare at them for a while trying to parse exactly how they work, but they do work. I like the way they parallel each other.


There are also a few things about Haskell that strike me as extremely inelegant. I've gotten past the weird operators and the dense mathematical jargon. Again, those have been covered endlessly elsewhere so I'd rather not repeat other people's work.

I think my expectation was to find no flaws in Haskell. That was obviously a doomed expectation, but I had hoped that since it was designed in the academy to be as weird and experimental as possible, that the creators wouldn't make any of the terrible compromises that are so apparent in the rest of our programming languages. Haskell is an old language (about as old as Objective-C), and so it will have warts and cruft in it, like any older language.

On of the big things I found that seemed unfinished was the distinction between the identical map and fmap. map is used exclusively for arrays, and fmap is used for the more general Functor types. (There's also an identical function called liftM for monads, lending almost PHP-esque levels of inconsistency.) These functions all do the exact same thing, but they have different names.

There are a lot of excuses given to explain this insconsistency, including path-dependence and better error messages, but it's still the class of thing I would expect a language like Haskell to get right.

Another example of inelegance in Haskell is infix notation. The lanugage primarily operates with prefix functions. That means that, for example, the function div, which divides two integers, is called like so:

div 92 10

For a lot of functions, this is hard to read. English is primarily a subject-verb-object language, so English speakers find "infix notation" easier to read in some cases. If you want to convert the div function to infix style, you can surround it with backticks.

92 `div` 10

I think this is pretty ugly, and it feels like it was glommed on to the language in some kind of compromise. For div specifically, you can use the operator / to achieve the same thing, but this won't work for all other functions.

There are also other operators like . (compose), <$> (apply), and $ (low-precedence apply), which allow you to change the order of functions and parenthesis usage. I'm not sure if it becomes easier to read this kind of Haskell over time, but for now, it's very confusing to figure out how all the functions compose and apply to each other to build bigger functions.

The final thing that stands out about Haskell was the positional arguments. I'm more convinced now than ever that positional (as opposed to named) arguments are a huge flaw in the way we program. For example, the Haskell function elem returns whether an element exists in a list. Do you call it with the list first or thing to search? There's no way to know. (The thing to search comes first.)

This is even more important for partial application (or currying). If I want to make a function that searches many lists for the existence of the element 3, I can curry the elem function, like so:

existenceOfThree = elem 3
existenceOfThree [1,2,3] // => True

But if I want a function that searches the same list for many things, I have to either define my own function, or I have to use the function flip, which flips the order of the inputs:

existsInMyList = flip elem [1,2,3]

And if there's more than two arguments, it gets even worse.

Writing code like this is when I feel like I'm implementing rather than defining. This code is heading in the direction of imperative, where I have to worry about implementation details.

While I was researching this example, I found the source for both elem and flip:

elem = any . (==)

flip f x y   =  f y x

Look how nice those are! I want all the code I write to be that nice.

Positional arguments are part of how Haskell maintains its terseness, but they're hard to read, impenetrable for beginners, and cause messiness when we want to apply parameters in a different order.

Haskell and You

The creators of Swift say they picked the best features from all the languages they could find, and a lot those features and functionalism come from Haskell. It's definitely worth a weekend to take a stab at Learn You A Haskell and see where those ideas come from.

October 5, 2015

Coordinators Redux

I wrote about coordinators at the beginning of the year, but the idea has matured a lot since then, and I'd like to reintroduce the topic with all of my learnings from the last few months.

This is adapted from a talk I gave at NSSpain this year. You can find the slides here. I'll post a link to the video when it's available as well.

Three Problems

Overstuffed App Delegates

Apple does a really poor job of guiding us into putting code in good places. It's really up to us to figure out how to structure our apps. The first place this is apparent is the app's delegate.

The app delegate is the entry point into any app. Its primary responsibility is shuttling messages back and forth from the operating system to the app's subsystems. Unfortunately, because of its position at the center of everything, it's extremely easy to just plop stuff in here. One casualty of this strategy is the root view controller's configuration. If you have a tab bar controller as the root of your app, you have to set up all the tab bar controller's children somewhere, and the app delegate is as good a place as any.

In the first app that I made (and I suspect this is true for many of my readers as well), I put all the set up for my root view controller right in my app delegate. That code doesn't really belong here, and it's only there out of convenience.

I realized that after I made my first app, and I grew wiser. I did this trick:

@interface SKTabBarController : UITabBarController

I would created a subclass of the root view controller I wanted to use, and I would tuck my code away in there. It was a temporary patch over the problem, but ultimately, it's not the right place for this code either. I would propose that we examine this object, the root view controller, from a perspective of responsiblities. Managing the child view controllers is within those duties, but allocating and configuration them not as much. We're subclassing a thing that was never intended to subclassed, just so we can hide away some code that doesn't have a home.

Coordinators are a better home for this app configuration logic.

Too Many Responsibilities

Here's another confounding problem. In the same way that its easy to dump tons of responsibilities into the app delegate, each individual view controller also suffers.

A small selection of the stuff we have view controllers do:

  1. Model-View Binding
  2. Subview Allocation
  3. Data Fetching
  4. Layout
  5. Data Transformation
  6. Navigation Flow
  7. User Input
  8. Model Mutation
  9. and many more besides

I came up with ways to tuck away these responsiblities in the children of each view controller in 8 Patterns to Help You Destroy Massive View Controller. All of these responsiblities can't be in one place. It's how we end up with 3000 line view controllers.

Which of this stuff should actually be in this class? Which should be elsewhere? What is the view controller's job? It's not clear.

There's a great quote by Graham Lee that I love.

When you get overly attached to MVC, then you look at every class you create and ask the question “is this a model, a view, or a controller?”. Because this question makes no sense, the answer doesn’t either: anything that isn’t evidently data or evidently graphics gets put into the amorphous “controller” collection, which eventually sucks your entire codebase into its innards like a black hole collapsing under its own weight.

What the hell is a view controller? Controllers in the Smalltalkian sense were originally intended strictly for user input. And even the word "control" screws us. As I've written before:

When you call something a Controller, it absolves you of the need to separate your concerns. Nothing is out of scope, since its purpose is to control things. Your code quickly devolves into a procedure, reaching deep into other objects to query their state and manipulate them from afar. Boundless, it begins absorbing responsibilities.

Which of those responsibilities should be at the "controller level"? Graham's right, the question doesn't even make sense. Because we're stuck with this awful word, we have to be really careful with what we allow our view controllers to do. If we don't, it's black hole central.

Coordinators can help us with this.

Smooth Flow

The last problem I want to discuss is navigation flow.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    id object = [self.dataSource objectAtIndexPath:indexPath];
    SKDetailViewController *detailViewController = [[SKDetailViewController alloc] initWithDetailObject:object];
    [self.navigationController pushViewController:detailViewController animated:YES];

This is a pretty common snippet of code, and I believe it's in the Apple templates as well. Unfortunately, it's garbage. Let's go through it line-by-line:

id object = [self.dataSource objectAtIndexPath:indexPath];

This first line is fine. The dataSource is a logical child of the view controller, and we're asking it for the object we need to refer to.

SKDetailViewController *detailViewController = [[SKDetailViewController alloc] initWithDetailObject:object];

This is where things start getting a little hairy. The view controller is instantiating a new view controller, the next one in the chain, and configuring it. The view controller "knows" what's coming up next in the flow. It knows how that thing is to be configured. The view controller that's doing the presenting knows a ton of detail about where it exists in the world of your app.

[self.navigationController pushViewController:detailViewController animated:YES];

The third line is where it totally goes off the rails. The view controller is now grabbing its parent, because remember, these view controllers exist in a heirarchy, and then it's sending a precise message to its parent about what to do. It's bossing its parent around. In real life, children should never boss their parents around. In programming, I would argue children shouldn't even know who their parents are!

In 8 Patterns to Help You Destroy Massive View Controller, I suggested a Navigator type that can be injected into view controllers that contains the logic for moving through your app. Navigators are a fine solution if you need it in one place, but we quickly run into an issue that navigators can't help us with.

Those three lines have a lot of responsibilities in it, but that one view controller isn't the only place that this is happening. Imagine you have a photo editing app.

Your PhotoSelectionViewController presents your StraighteningViewController which presents your FilteringViewController which presents your CaptioningViewController. Your navigation flow is now spread among three different objects. Further, something is presenting your PhotoSelectionViewController, but the dismissal has to be handled in CaptioningViewController.

Passing a Navigator around keeps these view controllers all coupled together in a chain, and doesn't really solve the problem of each view controller knowing about the next one in the chain.

Coordinators will help us solve this problem.

Libraries vs Frameworks

I think Apple expects us to write code in all these ways. They want us to make the view controller the center of the world, because apps written all in the same style let them make the most impact with their SDK changes. Unfortunately, for developers, that's not always the best move for us. We're the ones who are responsible for maintaining our apps into the future, and dependable design and malleability of code are much higher priorities for us.

They say the distinction between libraries and frameworks is that you call libraries, and frameworks call you. I want to treat 3rd-party dependencies as much like libraries as possible.

When using UIKit, you're not in charge. You call -pushViewController:animated: and it does a bunch of work and at some indeterminate time in the future, it calls -viewDidLoad: on the next view controller, where you can do some more stuff. Rather than let UIKit decide when your code runs, you should get out of UIKit-land as soon as possible, so you can have full control over how your code flows.

I used to think of view controllers as the highest level thing in app, the things that know how to run the whole show. But I started wondering what it might look like to flip that around. A view is transparent to its view controller. It's bossed around by its view controller. What if we made the view controller just another thing that's transparent in the same way?


What is a coordinator?

So what is a coordinator? A coordinator is an object that bosses one or more view controllers around. Taking all of the driving logic out of your view controllers, and moving that stuff one layer up is gonna make your life a lot more awesome.

It all starts from the app coordinator. The app coordinator solves the problem of the overstuffed app delegate. The app delegate can hold on to the app coordinator and start it up. The app coordinator will set up the primary view controller for the app. You'll find can find this pattern in the literature, in books like Patterns of Enterprise Application Architecture. They call it the Application Controller. The app coordinator is a special version of an application controller, specifically made for iOS. The app coordinator can create and configure view controllers, or it can spawn new child coordinators to perform subtasks.

Which responsiblities do coordinators take over from the view controller? Primarily, navigation and model mutation. (By model mutation I mean saving the user's changes to the database, or making a PUT or POST request to an API, anything that can destructively modify the user's data.)

When we take those tasks out of a view controller, we end up with a view controller that's inert. It can be presented, it can fetch data, transform it for presentation, display it, but it crucially can't alter it. We know now that any time we present a view controller, it won't take things into its own hands. Whenever it needs to let us know about an event or user input, it uses a delegate method. Let's take a look at a code example.

Code Example

Let's start from the app delegate.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    self.rootViewController = [[UINavigationController alloc] init];

    self.appCoordinator = [[SKAppCoordinator alloc] initWithNavigationController:self.rootViewController];
    [self.appCoordinator start];

    [self.window makeKeyAndVisible];

The app delegate sets up the apps window and root view controller, and then fires up the app coordinator. The coordinator's initialization is separated from starting its work. This lets us create it however we want (lazily, greedily, etc), and only start it when we're ready.

The coordinator is just a simple NSObject:

@interface SKAppCoordinator : NSObject

This is great. There's no secrets going on here. The UIViewController class is thousands of lines, and we don't know what exactly will happen when we call any of its methods, because it's closed-source. Making the objects that run our app simple NSObject types makes everything simpler.

The app coordinator initialized with the data it needs, which includes the root view controller.

- (instancetype)initWithNavigationController:(UINavigationController *)navigationController {
    self = [super init];
    if (!self) return nil;

    _navigationController = navigationController;

    return self;

Once we hit the -start method, the coordinator sets off to work.

- (void)start {
    if ([self isLoggedIn]) {
        [self showContent];
    } else {
        [self showAuthentication];

Right from the start, coordinator is making decisions. Previously, logic like this didn't have a home. You could maybe stick it in a view controller or in the app delegate, but those both have their flaws. In a view controller, you have one view controller which is making some decisions well-beyond its purpose, or you're polluting the app delegate with stuff it doesn't care about.

Let's examine the -showAuthentication method. Here, our base coordinator spawns off child coordinators to do work and subtasks.

- (void)showAuthentication {
    SKAuthenticationCoordinator *authCoordinator = [[SKKAuthenticationCoordinator alloc] initWithNavigationViewController:self.navigationController];
    authCoordinator.delegate = self;
    [authCoordinator start];
    [self.childCoordinators addObject:authCoordinator];

We use an array of childCoordinators to prevent the child coordinators from getting deallocated.

View controllers exist in a tree, and each view controller has a view. Views exist in a tree of subviews, and each subview has a layer. Layers exist in a tree. Becuase of this childCoordinators array, you get a tree of coordinators.

This child coordinator will create some view controllers, wait on them to do work, and signal us when it's done. When a coordinator signals that its finished, it cleans itself up, popping off whatever view controllers it has added, and then uses delegates to get messages back up to its parent.

Once we've authenticated, we'll get a delegate message, and, we can allow the child coordinator to be deallocated, and then we can get back to our regularly-scheduled programming.

- (void)coordinatorDidAuthenticate:(SKAuthenticationCoordinator *)coordinator {
    [self.childCoordinators removeObject:coordinator];
    [self showContent];

Inside the authentication coordinator, it creates whatever view controllers it needs, pushes them onto the navigation controller. Let's take a look at what that looks like.

@implementation AuthCoordinator

- (instancetype)initWithNavigationController:(UINavigationController *)navigationController {
    self = [super init];
    if (!self) return nil;

    _navigationController = navigationController;

    return self;

Initialization is similar to the app coordinator.

- (void)start {
    SKFirstRunViewController *firstRunViewcontroller = [SKFirstRunViewController new];
    firstRunViewcontroller.delegate = self;
    [self.navigationController pushViewController:firstRunViewcontroller animated:NO];

Authentication needs to start with a "first run view controller". This view controller has buttons for sign up and log in and maybe a little slideshow explaining the app. Let's push that view controller on and become its delegate.

This view controller has a delegate so we can be informed when the user taps the "sign up" button. Instead of the view controller needing to know which signup view controller to create and present, the coordinator will handle that.

- (void)firstRunViewControllerDidTapSignup:(SKFirstRunViewController *)firstRunViewController {
    SKSignUpViewController *signUpViewController = [[SKSignUpViewController alloc] init];
    signupViewController.delegate = self;
    [self.navigationController pushViewController:signupViewController animated:YES];

We become the sign up view controller's delegate so that it can inform us when its buttons are pushed.

- (void)signUpViewController:(SKSignUpViewController *)signupViewController didTapSignupWithEmail:(NSString *)email password:(NSString *)password {

And so on. Here we actually perform the work of the signup API request and saving the authentication token, and then we inform our parent coordinator.

Whenever anything happens with a view controller (like user input) the view controller will tell its delegate (in this case the coordinator) and the coordinator will execute the actually task that the user intended. It's important to have the coordinator do the work, so that the view controller remains inert.

Why are coordinators great?

  1. Each view controller is now isolated.
    View controllers don't know anything beyond how to present their data. Whenever anything happens, it tells its delegate, but of course it doesn't know who its delegate is.

    Before, when there was a fork in the road, the view controller needs to ask "Okay, well, am I on the iPad or the iPhone?". "Is the user being A/B tested?" They no longer have to ask any questions like that. Have we merely pushed this question, this conditional, up to the coordinator? In a way, but we can solve it in a much better way up there.

    When we do need to have two flows at once, for A/B testing or multiple size classes, you can just swap the entire coordinator object instead of sticking a bunch of conditionals all over your view controllers.

    If you want to understand the way a flow works, that's now super easy, since all the code is in one place.

  2. View controllers are now reusable.
    They don't assume anything about what context they'll be presented in, or what their buttons will be used for. They can be used and reused for their good looks, without dragging any logic along with them.

    If you're writing your iPad version of your app, the only thing you need to replace are your coordinators, and you can reuse all the view controllers.

  3. Every task and sub-task in your app now has a dedicated way of being encapsulated.
    Even if the task works across multiple view controllers, it's encapsulated. If your iPad version reuses some of those subtasks but not others, it's really easy to use just those sub-tasks.

  4. Coordinators separate display-binding from side effects.
    You never again have to worry about if a view controller will mess up your data when you present a view controller. It can only read and display, never write or corrupt data. This is a similar concept to command-query separation.

  5. Coordinators are objects fully in your control.
    You're not sitting around waiting for -viewDidLoad to get called so you can do work, you're totally in control of the show. There's no invisible code in a UIViewController superclass that is doing some magic that you don't understand. Instead of being called, you start doing the calling.

    Flipping this model makes it much easier to understand what's going on. The behavior of your app is a completely transparent to you, and UIKit is now just a library that you call when you want to use it.

The current project I'm working will be open-sourced in a few weeks, and it uses coordinators to manage all of its view controllers. The app coordinator and auth coordinator examples come from that project.

Ultimately, coordinators are just an organizational pattern. There's no library you can use for coordinators because they're so simple. There's no pod you can install and nothing to subclass from. There's not even really a protocol to conform to. Rather than being a weakness, this is a strength of using a pattern like coordinators: it's just your code, with no dependencies.

They'll help make your app and your code more manageable. View controllers will be more reusable, and growing your app will be easier than ever.

September 28, 2015

What The Heck Is A Monad

There's an everpresent hilarious thread in programming blogs where an author tries to explain what a monad is, starts strong, and then ends up losing everyone with some nonsense about an endofunctor.

I'm going to take a crack at it. I'm probably going to fail, and I'm going to prove Soroush's Burrito Law in the process: anyone trying to explain monads is going to fail, even if they account for how hard explaining monads is.

A monad is a wrapper for a thing. (It honestly is like a burrito.)

The Maybe Type

So. Let's talk Swift. Let's say you have a function that reads something from disk. It can either return the thing, or it can return nothing. Swift calls this type Optional, but let's recreate it and call it Maybe.

enum Maybe<WrappedType> {
    case Something(WrappedType)
    case Nothing

Angle-bracket blindness is real. WrappedType here just means that our Maybe can have anything inside of it, and we can refer to whatever type that thing is with WrappedType. This lets the compiler know the type of what's coming out is the same as the type of what's put in. Let's continue. Imagine a function called readString() reads a string from the disk, where its provenance is doubtful. It "maybe" doesn't exist.

func readString() -> Maybe<String> {
    return .Something("someString");

let maybeString = readString()

This is the first important part of a monad. You have to have a way to create one. In this case, the constructor, Maybe.Something, fills that role. In other languages, this is known as unit or the inconveniently-named function return. It's a function that takes one parameter, and returns a monad that wraps that parameter.

If this is all we have, it's kind of frustrating to use. To get access to the information inside that Maybe, you have to explicitly unwrap it. The structure of the type forces you to check it, every time.

switch (maybeString) {
    case let .Something(definitelyString):
    case .Nothing:

After we use Maybe with a case statement like this for a while, we notice that we're writing this switch statement over and over. It's a lot of boilerplate just so we can access the Something.

Maybe we can wrap up the switch into a function, and pass that function a block that will be executed if the Maybe is a Something and not a Nothing.

extension Maybe {
    func ifSomething<NewWrappedType>(block: (WrappedType) -> Maybe<NewWrappedType>) -> Maybe<NewWrappedType> {
        switch self {
        case let .Something(wrapped):
            return block(wrapped)
        case .Nothing:
            return .Nothing

I would love to remove the types in the function declaration to make it shorter and clearer, but they actually confer a very important piece of information: The block that we're accepting takes a WrappedType (a string, in the example above), and returns a new type wrapped in a monad.

This is very important. ifSomething doesn't just give us access to the Something, it also lets us transform it, but requires that it be wrapped in the Monad type again. (Sometimes we want to transform but not wrap it, and I'll address that in a moment.)

It's important that the block returns an already-wrapped monad, so that we can chain these calls. This is a big part of why monads are useful.

Now that we have this power of transforming the wrapped thing, we can do something very cool. Imagine we had a function that converts strings to JSON objects. It returns a Maybe, since deserializing JSON can fail.

readDataFromDisk().ifSomething({ string in
    return convertToJSON(string)

or, more succinctly:


At the end of .ifSomething(convertToJSON), we just get back a new Maybe monad, on which we can again call ifSomething. This is how monads let us chain stuff. Imagine another function called getProperty, which also returns a Maybe.

readDataFromDisk().ifSomething({ string in
    return convertToJSON(string)
}).ifSomething({ JSON in
    return getProperty(JSON, "username")

Et cetera. We can keep chaining like this, as long as we need to. Notice how this is flat, instead of nested. We've totally skipped the part where you have to unwrap an Optional with an if let, then unwrap another one, then another one, and you end up with something 5 levels deep.

If we didn't have ifSomething, our code would look like this:

var maybeData = readDataFromDisk()
if let data = maybeData {
    let maybeJSON = convertToJSON(string)
    if let JSON = maybeJSON {
        let maybeUsername = getProperty(JSON, "username")
        if let username = maybeUsername {
            //we can finally use the username

While indented code like this might work in early stages, the fact that it continues to indent inwards means that it's not scalable. With monads, we can remove the nesting and organize our code much better.

Functional programmers took a great name like ifSomething and made it totally inscrutable by calling it flatMap. (In some of the literature, it's also known as bind. In Haskell, aka peak inscrutability, it's invoked with the operator >>=.)

bind (or flatMap) and unit (the constructor) are all it takes to be considered a monad. From those two, we can also build map. map lets us transform the wrapped object without having to rewrap it ourselves at the end of the function. This is particularly useful for arrays and other collection types.

To build map, we wrap the result of the map block with the constructor and send that to flatMap:

extension Maybe {
    func map<NewWrappedType>(block: (WrappedType) -> NewWrappedType) -> Maybe<NewWrappedType> {
        return flatMap({ wrapped in
            return .Something(block(wrapped));

In this way, map can be written in terms of bind and unit.

The Monadic Laws

For something to be monad, in addition to implementing bind and unit, it has to follow some special rules.

First, left identity.

unit(a).flatMap(f) == f(a)

Wrapping a in the monad, then calling flatMap with any function f will have same result as just calling f with a, since f returns a new monad.

Second, right identity.

m.flatMap(unit) == m

Since the unit function doesn't do anything but take the unwrapped value and wrap it, calling flatMap on an existing monad m with unit will have no effect.

The first two monadic laws exist to assert that unit, the constructor, doesn't do anything other than wrap a.

Lastly, associativity.

m.flatMap(f).flatMap(g) == m.flatMap({ a in
    return f(a).flatMap(g)

This says that we can combine two functions f and g into a new function, and calling flatMap with the new function is the same as calling flatMap with each of the functions separately.

In Swift

You don't need to write your own Maybe type to start using this in Swift today. Swift's Optional type supports flatMap.

let optionalString = Optional.Some("123");
let optionalInt = optionalString.flatMap { string in
    return Int(string)

Because all versions of flatMap behave the same, you can use this just like the flatMap we wrote above, chaining it over and over.

In A Nutshell

That's monads in a nutshell. Well, they are the nutshell. They wrap a value, like a shell.

Other monads you might have seen include:

  • Result, which wraps a "Something" with an optional "Error".
  • Eventually/Promise/Deferred, which wraps a value that doesn't exist yet.
  • Array, which wraps many values.

With Result in particular, it's easy to see how you might have a series of functions where each is dependent on the previous one, and where each can fail and generate an error. You would have a pyramid of doom without being able to flatMap them repeatedly.

I've used the Promise monad a lot in Javascript, and it organizes code greatly:

User.signup = function(user) {
    return new Promise(function(resolve, reject) {
        User.validate(user).then(function() {
            return Bcrypt.genSalt(10);
        }).then(function(salt) {
            return Bcrypt.hash(user.password, salt, null);
        }).then(function(saltedHashedPassword) {
            return User.insertIntoDatabase(user, saltedHashedPassword);
        }).then(function(userRecord) {
        }).catch(function(error) {

The chaining that the promise monad affords us is crucial when all of your operations are asynchronous and can fail. We return a new Promise in each then block, and the chain continues. In this way, we've described an inherently complex, asynchronous task in a serial list of steps.

Monads are weird thing. The idea lets us treat all these different wrappers, which all serve different functions, similarly. When we know that something is a monad, we gain a ton of knowledge about how we can use it and what it can do.

After all, they're just monoids in the category of endofunctors.

September 24, 2015

The Limited Subset

Two of the most impressive languages in my mind are Lisp and Smalltalk. They are both extremely limited: Lisp is structured around spaces and parentheses. That's it.

Smalltalk has only 6 keywords: true, false, nil, self, super, and thisContext. Everything in Smalltalk, including conditionals, is handled by sending messages to objects. How many keywords does Swift have already? Why can't I name my UISwitch "switch"? (I know why, and it's vexing.)

Most languages don't do this. Their users want more toys and more sugar in the language. The language maintainers add it, and you end up with a languages that are a complicated mess.

While most langauges aren't designed with simplicity as a feature, I've found that with a little self-control, it's possible to intentionally limit yourself to a subset of your favorite language, and have great results.

I'm writing Objective-C and Javascript on a day-to-day basis, so my examples will come from those languages. The idea, however, is universalizable.

First, app structure. When structuring an app, I limit myself to one structure. Inasmuch as I can control it, everything has one and only one owner, so that my object graph looks as much like a tree as possible. From the top, the app is run by coordinators, which boss around the view controllers. Those view controllers each have a view, which is a custom subclass of UIView designed specifically for each view controller. This lets me push subview configuration and layout out of the view controller and down into the view. Subview allocation is always handled via lazy loading. Layout itself is pushed even further into a layout object.

I'll break these rules every once in a blue moon, but almost every time, I will write code like this. It helps increase consistency and removes any doubt about how to structure the simple stuff. When a new programmer comes on board, if they understand one section of the app, they'll be able to easily navigate through the rest of it.

Second, communication patterns. Since everything is a tree, messages need to go down, from parents to children, and up, from children to their parents. Parents know about their children, so they can just send simple messages. But when children talk to parents, I almost always use the delegate pattern exclusively. I know about KVO, I know about NSNotificationCenter, and I know about the responder chain, but delegates have a simplicity to them that I value. Their relationships are one-to-one (each object generally has one delegate), their data is typed, and it's easy to search for delegate conformance. There's a small cost to the extra code of declaring the protocol, but I find that it pays off in the long run.

Delegates are great, but the key here is not the pattern itself, but limiting yourself to it. The artifical limitation simplifies decision-making while writing code. When you limit yourself intentionally, you don't end with a tangled mess of code that fires an NSNotification from inside of block that calls another method via a delegate.

Finally, a Javascript example. The project I've been working on has a backend written in Express. Express assumes very little about your code's structure. It gives you the standard Node.js Request and Response types, as well as a Router. That's pretty much it. Routers let you register functions with routes. Now, I could try to build a roughly object-oriented model layer within Javascript, but I don't really understand how Javascript constructors work, so that choice is out.

Instead of trying to make each route (represented by a function) talk to an object-oriented model layer, the User type holds onto all of the things that a user can do.

var loginAction = function(req, res, next) {
    var creds = { email:, password: req.body.password };
    User.login(creds).then(function(session) {
        res.sendJSON({ session: session });
    }).catch(function(error) {
        res.sendError(error, "There was an error logging in.");

Each of the things on the User type is a function, and calling it returns a new Promise. This, and the fact that data is represented by dumb objects that do nothing but hold the data, make the model layer is very functional in nature. Of course, it wouldn't be interesting if it were only in one place, so every single route in the system works like this.

When I'm making a new route, it's no longer necessary to think about how go from the functional "action" layer to the Promise-based model layer. It's always the same. The sendJSON and sendError functions on Result are also almost always used, making it dead simple to add new endpoints. You get to the meat of writing your code even quicker. Limiting you and providing a One True Way to do stuff is how frameworks like Rails help you speed up development.

When you limit yourself to a small part of the language, you end up with code that's simpler and requires less thought to implement. It removes a lot of the weight from working in your codebase and makes it easier for outsiders to understand how things work.

September 10, 2015

Learning Lessons The Hard Way

This happens more often than I’d care to admit. While programming, I’ll receive a flash of insight that maps cleanly onto a trite phrase I’d heard dozens of times before. Prefer composition to inheritance. The law of Demeter. Code is read a lot more than it is written. The pith is endless.

You’ll come across a problem and realize how doing it the easy way has bitten you in the ass. You’ll stop making the mistake of doing it the easy way, and start doing it the right way. I’ve found that with lessons like these, you almost always have to go the long way around, experiencing them firsthand before there can be a deep understanding.

A great example of one of these lessons is making small classes and small methods. Ben Orenstein gives advice to this effect in one of his posts. I remember defending to my Ruby-writing coworkers: maybe you could write Ruby that way, but Objective-C is just too complex and verbose to write with one-line methods. I was, of course, super wrong. Not only is it possible to write Objective-C in that style, it’s also joyful.

David Foster Wallace, in his now-classic commencement address for Kenyon College, said:

Because a huge percentage of the stuff that I tend to be automatically certain of is, it turns out, totally wrong and deluded. I have learned this the hard way, as I predict you graduates will, too.

There’s a delightfully meta component here: not only are the lessons hard to learn, but the lesson that the lessons are hard to learn is hard to learn.

There’s a somber component too: learning lessons the hard way sucks. Our knowledge is stuck in our brains, and can only come out in low-bandwidth forms, like prose, speech, or drawing.

When you finally have that bug that causes you to have the epiphany, all you end up with is a shitty platitude. You have no way to impart to anyone else what you’ve discovered. The lesson took time for you to learn, and once you’ve learned it, you wish you could give it to other people. If you’ve ever written a monad tutorial, I’m looking at you.

I’ve found only two ways to route around it. The first is to feel someone else’s suffering at the hands of one of these bugs and experience empathy.

The everpresent joke in computer science says there’s two hard problems: naming and cache invalidation. When I was starting out, I remember thinking “ha ha, there’s no way cache invalidation could be that hard”. Fast forward a few years, and while I’ve learned a few lessons of my own about bad caches, reading Code Climate’s incident report for a major issue made me understand on a far deeper level what it means for cache invalidation to be hard. Lesson learned, bon mot deployed.

The second approach to teaching hard ideas is to change the value function. Programmers take shortcuts and write code “the bad way” because it’s way easier. It feels as though the cost is lower than the hard way, because you can’t see the interest acquired by your technical debt. Instead of making the cost of shortcut higher, we can increase the value of the “right way”.

To make the hard way more appealing to your audience, the trick is finding the perfect example to illustrate it. Most readers will skim a new post when it comes out. They don’t stop and pick out each word you write. Code blocks break up the writing, and they provide somewhere for the readers eye to jump. Given that you’re only getting a small amount of the reader’s attention, you have to find an example that strikes the right note with the reader. The example decides if the post lands or not. It has to be relatable and short, so that you don’t lose the attention of the reader, but it has to be complex enough to not be trivial.

For example, I’m very proud of my post on the method object pattern, Graduation. This post makes it simple, obvious, and elegant to take a method and make a new class out of it. It readjusts the value function in the programmer. When the value of the good way increases, it takes far less activation energy to jump from the bad way to the good way. Put another way, the intensity of the lesson you have to learn is much lower before you’re happy to switch over.

Part of why I love Sandi Metz’s work is that she takes a simple problem, like inheritance, and thinks about it a lot, and finds the right words to make even the most novice programmer understand why to prefer composition to inheritance. I’d heard about this platitude plenty when I was just starting out, but Sandi’s talk was what really drove it home.

Ultimately, we can only do so much. It’s a shame that these methods have to be learned over and over, the slow way. The best we can do is grease that path for those that follow us.