HATEOAS app structure explained through some flimsy analogy

You are in a tall, narrow view. A vibrant, neon sign overhead tells you that this is the entrance to “Stocks” – below it is one of those scrolling news tickers you might see on Times Square. In front of you lies a panel of buttons. Before you can do anything, an automatic droid introduces itself as “Searchfield”. It invites you to tell it the name of a stock you’d like to know the price of, and tells you that it will then GET the price.

You can see:

Searchfield<br/>
A button marked “Price”<br/>
A button marked “Market Cap”<br/>
A box marked “PUT trades here”<br/>

There is an exit going Back. Additionally you can go Home.

Are you an [X] programmer?

On my twitter bio, I describe myself as:

a Lovelacologist for portable transactators

which is, in keeping with the way I’m dressed in the avatar pic, a steampunk way of saying that I’m a programmer of mobile computers. But is that strictly true, or fair? It’s what I’ve spent most of the last couple of years doing, but then I’ve also worked on:

  • web servers
  • SMPP servers
  • one particle accelerator
  • workstation apps
  • desktop apps
  • administration scripts
  • books

and there’s bound to be more things that I haven’t remembered. I don’t think I’m alone in picking quite a narrow definition to expose as “me” (though maybe I should have thought a bit harder before titling this blog). Social scientists refer to this as “doing identity work”, the effort we go to to control the definition of who we are in interactions with others. To confirm this choice of narrow identity work, here’s a not-quite-random look at excerpts from a few other Twitter bios (anonymised for no real reason):

  • iOS, OS X, BMWs, photography, and food.
  • App developer by day – Apple fanboy by night
  • now a Clojure and Ruby programmer
  • iOS Developer

It’s interesting that while we choose these restricted “brands” for ourselves, we actually spend a lot of time solving the same problems. I’ve been working on another web app project lately, and it’s remarkably similar to building a mobile app. Even a lot of the constraints are similar:

  • keep the event loop fast
  • avoid loading lots of large data files
  • maintain separation of concerns between modules
  • try to minimise power consumption

and indeed the solutions turn out to be similar too. The command bus introduced in an earlier post, perfect for (and, according to some readers, informing their own work in) mobile apps, was actually built for this web app project. The problems and the solutions turn out to be interchangeable.

What we need is more of this interchangeability. Rather than waiting for a mobile person to say in a mobile way how to write mobile software, we can take advantage of what people have already said in a software way about how to write software. I have resolved to widen my horizons, and pay broader attention to what my colleagues are up to.

Blame culture

The tweet that started this post off:

Candidate for the worst name of any SCM feature: “blame”. Don’t use it for that.

I was recently watching a couple of conference talks (given by people working at the same company) where the presenters described using the ‘blame’ feature of their version control tool to find the person responsible for a bug so that they could go down to their office and chew them out.

This is not constructive. What are you going to do if that person is on holiday, let the bug fester for a week so you can have the rant when they get back? What if they left the company? Remember that you’re on the same team: you are permitted to fix the bug. Fixing the bug helps you, your team, your company and your customers; complaining at the person who introduces it only helps to poison your relationships with your team. So fix it. That’s not to say the blame feature isn’t useful:

  • use it to find out why the change was introduced, which might help you understand what was intended. This is why you write good commit messages.
  • use it to find out when the change was introduced, to help you understand the severity of the bug[*]
  • yes, use it to find out who made the change, but only if you think that you’re going to learn something from the discussion. Remember, we do not set the bozo bit.

[*] I’ve done this recently. On discovering and isolating a bug, I used git blame to work out whether it was introduced before or after the software was released. Sadly, it was before.

Maybe it should be called “explain”; whatever, do not use your blame feature for blame.

Aside on blame visualisation

If you’re reading this blog post from Black Pixel, hello! Please feel welcome to build this feature into Kaleidoscope without the need to pay me a licensing fee :-)

As code ages, small changes tend to get added here and there. We build an initial implementation of some feature, then discover that there are some edge cases or new ways of using it that we didn’t consider, so little patches get built on. These can overlap or supersede earlier patches, and interact in interesting ways (where “interesting” can be read as “infuriating”, if you like).

What I would find useful is a diff tool that just shows the current state of the file, but uses the z-axis to indicate the age of each line. In the same way that code editors can identify regions for folding using (simulated or actual) depth, they could identify regions of change. This would make it easy to see at a glance how the file has evolved over time, to see where and when changes were needed.

The code you wrote six months ago

We have this trope in programming that you should hate the code you wrote six months ago. This is a figurative way of saying that you should be constantly learning and assimilating new ideas, so that you can look at what you were doing earlier this year and have new ways of doing it.

It would be more accurate, though less visceral, to say “you should be proud that the code you wrote six months ago was the best you could do with the knowledge you then had, and should be able to ways to improve upon it with the learning you’ve accomplished since then”. If you actually hate the code, well, that suggests that you think anyone who doesn’t have the knowledge you have now is an idiot. That kind of mentality is actually deleterious to learning, because you’re not going to listen to anyone for whom you have Set the Bozo Bit, including your younger self.

I wrote a lot about learning and teaching in APPropriate Behaviour, and thinking about that motivates me to scale this question up a bit. Never mind my code, how can we ensure that any programmer working today can look at the code I was writing six months ago and identify points for improvement? How can we ensure that I can look at the code any other programmer was working on six months ago, and identify points for improvement?

My suggestion is that programmers should know (or, given the existence of the internet, know how to use the index of) the problems that have already come before, how we solved them, and why particular solutions were taken. Reflecting back on my own career I find a lot of problems I introduced by not knowing things that had already been solved: it wasn’t until about 2008 that I really understood automated testing, a topic that was already being discussed back in 1968. Object-oriented analysis didn’t really click for me until later, even though Alan Kay and a lot of really other clever people had been working on it for decades. We’ll leave discussion of parallel programming aside for the moment.

So perhaps I’m talking about building, disseminating and updating a shared body of knowledge. The building part already been done, but I’m not sure I’ve ever met anyone who’s read the whole SWEBOK or referred to any part of it in their own writing or presentations so we’ll call the dissemination part a failure.

Actually, as I said we only really need an index, not the whole BOK itself: these do exist for various parts of the programming endeavour. Well, maybe not indices so much as catalogues; summaries of the state of the art occasionally with helpful references back to the primary material. Some of them are even considered “standards”, in that they are the go-to places for the information they catalogue:

  • If you want an algorithm, you probably want The Art of Computer Programming or Numerical Recipes. Difficulties: you probably won’t understand what’s written in there (the latter book in particular assumes a bunch of degree-level maths).
  • If you want idioms for your language, look for a catalogue called “Effective <name of your language>”. Difficulty: some people will disagree with the content here just to be contrary.
  • If you want a pattern, well! Have we got a catalogue for you! In fact, have we got more catalogues than distinct patterns! There’s the Gang of Four book, the PloP series, and more. If you want a catalogue that looks like it’s about patterns but is actually comprised of random internet commentators trying to prove they know more than Alastair Cockburn, you could try out the Portland Pattern Repository. Difficulty: you probably won’t know what you’re looking for until you’ve already read it—and a load of other stuff.

I’ve already discussed how conference talks are a double-edged sword when it comes to knowledge sharing: they reach a small fraction of the practitioners, take information from an even smaller fraction, and typically set up a subculture with its own values distinct from programming in the large. The same goes for company-internal knowledge sharing programs. I know a few companies that run such programs (we do where I work, and Etsy publish the talks from theirs). They’re great for promoting research, learning and sharing within the company, but you’re always aware that you’re not necessarily discovering things from without.

So I consider this one of the great unsolved problems in programming at the moment. In fact, let me express it as two distinct questions:

  1. How do I make sure that I am not reinventing wheels, solving problems that no longer need solving or making mistakes that have already been fixed?
  2. A new (and for sake of this discussion) inexperienced programmer joins my team. How do I help this person understand the problems that have already been solved, the mistakes that have already been made, and the wheels that have already been invented?

Solve this, and there are only two things left to do: fix concurrency, name things, and improve bounds checking.

Separating user interface from work

Here’s a design I’ve had knocking around my head for a while, and between a discussion we had a few weeks ago at work and Saul Mora’s excellent design patterns talk at QCon I’ve built it.

A quick heads-up: currently the logic is all built into a side project app I’ve been working on so I don’t have a single project download I can point to. The post here should explain all of the relevant code, which is made available under the terms of the MIT Licence. A reusable component is forthcoming.

Motivation

Remove the Massive View Controller from our applications’ architectures. Push Cocoa, Cocoa Touch, or other frameworks to the edges of our codebase, responsible only for working with the UI. Separate the concerns of user interaction, work scheduling and the actual work.

There are maintainability reasons for doing so. We separate unrelated work into different classes, localising the responsibilities and removing coupling between them. The same code can be used in multiple contexts, because the UI frameworks are decoupled from the work that they’re doing. This is not only a benefit for cross-platform work but for re-using the same logic in different places in a single user interface.

We also notice performance optimisations that become possible. With a clear delineation between the user interface code and the work, it’s much easier to understand which parts of the application must be run on the user interface thread and which can be done in other contexts.

Solution

Implement the Message Bus pattern from server applications. In response to a user event, the user interface creates a command object and sends it to a command bus. The command bus picks an appropriate handler, passes it the command and schedules it. The user interface, the work done and the scheduling of that work are therefore all decoupled.

IKBCommand Class Diagram

Workflow

At application launch, the application accesses the shared IKBCommandBus object:

@interface IKBCommandBus : NSObject

+ (instancetype)applicationCommandBus;
- (void)execute: (id <IKBCommand>)command;
- (void)registerCommandHandler: (Class)handlerClass;

@end

and registers command handlers. Command handlers know what commands they can process, and can tell the bus whether they will accept a given command. Handlers can also be loaded later, for example in Mac applications or server processes when a new dynamic bundle is loaded.

Once the application is running, the command bus can be used by user interface controllers. These controllers are typically UIViewControllers in an iOS app, NSViewControllers, NSDocuments or other objects in a Cocoa app, or maybe something else in other contexts. A controller receives an action related to a user interface event, and creates a specific IKBCommand.

@protocol IKBCommand <NSObject, NSCoding>

@property (nonatomic, readonly) NSUUID *identifier;

@end

Commands represent requests to do specific work, so the controller needs to configure the properties of the command it created based on user input such as the current state of text fields and so on. This is done on the user interface thread to ensure that the controller accesses its UI objects correctly.

The controller then tells the application’s command bus to execute the command. This does not need to be done on the user interface thread. The bus looks up the correct handler:

@interface IKBCommandHandler : NSObject

+ (BOOL)canHandleCommand: (id <IKBCommand>)command;
- (void)executeCommand: (id <IKBCommand>)command;

@end

Then the bus schedules the handler’s executeCommand: method.

Implementation and Discussion

The Command protocol includes a unique identifier and conformance to the NSCoding protocol. This supports the Event Sourcing pattern, in which changes to the application can be stored directly as a sequence of events. Rather than storing the current state in a database, the app could just replay all events it has received when it starts up.

This opens up possibilities including journaling (the app can replay messages it received but didn’t get a chance to complete due to some outage) and syncing (the app can retrieve a set of events from a remote source and play those it hasn’t already seen). An extension to the implementation provided here is that the event source acts as a natural undo stack, if commands can express how to revert their work. In fact, even if an event can’t be reversed, you can “undo” it by removing it from the event store and replaying the whole log back into the application from scratch.

When a command is received by the bus, it looks through the handlers that have been registered to find one that can handle the command. Then it schedules that handler on a queue.

@implementation IKBCommandBus
{
  NSOperationQueue *_queue;
  NSSet *_handlers;
}

static IKBCommandBus *_defaultBus;

+ (void)initialize
{
  if (self == [IKBCommandBus class])
    {
      _defaultBus = [self new];
    }
}

+ (instancetype)applicationCommandBus
{
  return _defaultBus;
}

- (id)init
{
  self = [super init];
  if (self)
    {
      _queue = [NSOperationQueue new];
      _handlers = [[NSSet set] retain];
    }
  return self;
}

- (void)registerCommandHandler: (Class)handlerClass
{
  _handlers = [[[_handlers autorelease] setByAddingObject: handlerClass] retain];
}

- (void)execute: (id <IKBCommand>)command
{
  IKBCommandHandler *handler = nil;
  for (Class handlerClass in _handlers)
    {
      if ([handlerClass canHandleCommand: command])
        {
          handler = [handlerClass new];
          break;
        }
    }
  NSAssert(handler != nil, @"No handler defined for command %@", command);
  NSInvocationOperation *executeOperation = [[NSInvocationOperation alloc] initWithTarget: handler selector: @selector(executeCommand:) object: command];
  [_queue addOperation: executeOperation];
  [executeOperation release];
  [handler release];
}

- (void)dealloc
{
  [_queue release];
  [_handlers release];
  [super dealloc];
}

@end

Updating the UI

By the time a command is actually causing code to be run it’s far away from the UI, running a command handler’s method in an operation queue. The application can use the Observer pattern (for example Key Value Observing, or Cocoa Bindings) to update the user interface when command handlers change the data model.

Fiction: The Ouroborus School pt 1

On a warm Spring day, the camera follows a butterfly as it wends its coruscating way around a buddleia bush. The plant is growing in the well-kept border surrounding an immaculately manicured lawn, the quadrangle of an imposing Jacobean building. Now the perspective shifts, you zoom in over the bright primary colours of the butterfly’s wings, dancing on the thermals and eddies of the sunlit quadrangle, until you can see through the eyes of the butterfly. This is actually quite easy to arrange, as the butterfly is a Milliard Maps autonomous photography drone and its eyes are internet-connected fisheye camera lenses. As you see the slate roof slowly getting larger due to the butterfly stochastically flapping towards it, the last few words of a university lecturer addressing his students can be heard drifting from an open window.

“So even though the applications were all protected and the kernel was protected, the criminals still found ways to circumvent the system and get their malicious softs to run. Next week, we’ll look at how the firms itself was enhanced to keep customers safe and increase value. You should all read Chapter 7 before then. Don’t forget that the collections on digirights will be coming up the following week. OK! That’s it for today.”

A “collection”, we have time to reflect upon as the students gather their things and leave the lecture hall, is a mid-term examination at the Ouroborus Inc. School for Higher Education, in the centre of Oxford. It is that institution’s window, under its clinker-like roof, that leaked the words from that professorial denouement. The university isn’t really run by Ouroborus, of course. That company is actually a large manufacturer of consumer electronics over on the far side of the United States of America, and managing an educational institution is not in its core strengths. The company merely owns the building, approves lecturers into the school’s “team”, advertises the courses in its online music store (an unfortunate quirk of history that has never been corrected), and processes the registration of new students. The school is self-governed, and keeps 70% of the tuition fees. In return for its share of the fees, Ouroboros Inc. reviews the syllabus prepared for each course and rejects suggestions by the tutors that would not be in the best interests of the students. These days the curricula tend to get through with only minor tweaks, but back in 2018 the course on Experiences of Computer Softs was rejected for including a lecture on the uses of devices made by the Milliard Internet Searching Company.

The lecture you just caught the end of is from “Introduction to Digirights”, one of the compulsory courses for first year app sci undergraduates at OISHE. App sci is one of the school’s most widely-renowned degrees. Many of its graduates have left five star reviews on the Diploma Store, and it frequently tops the highest-grossing list in its category. Hiring a softsmith from OSHE’s app sci graduate pool, it is said, is a sure-fire way to build a company whose softs can command five dollars-some fetch even more-per sale. As a result they receive myriad applications every year per place, many of which are actually in localised classes presented in other countries. One such localisation is offered in the Ouroborus Institute of Technology in Cambridge, Massachusetts, United States of America. Since the federal government outlawed the teaching of American citizens in British English the school has found it more cost-effective to let OIT lecturers deliver its classes to American students.

Having contemplated the centuries-old tiles and cupolas of OSHE’s roof, your gaze is directed toward the last pair of students to leave the digirights lecture and enter the quadrangle. Mary Wilkes looks with some concern at her wristwatch. The Ouroboros OWatch (“You’ll love it for its timelessness. And for its time.”) can in fact tell you how far into the day you’ve progressed, but Mary, like many of its users has other designs on it. Currently it’s showing her that she received three public messages during the lecture, that her digirights notes have synced successfully, and that she has another lecture in fifteen minutes over in the Tutte Building. The OWatch was originally designed to help Ouroboros Inc. sell into Latin America. The theory was that the kind of people who were flashy enough to buy their phones were also sensible enough not the wield them on the streets of Sao Paulo, and therefore were not actually going to buy the phones. The watch let them show off their allegiance to the marque without as much chance of being mugged. In fact the OWatch quickly gained customers in Europe and North America, and a few more people reported to hospitals in South America with wrist lacerations.

“Sorry, Ivan, I’m going to have to skip that coffee. I’ve got to get over to King Tutte, and I’ll need to get another pack of stylus tips before that in the MISCStore. How about you send me an invite for another time?”

Ivan shakes his head, an action that sets his messy tangle of blond hair and much of the rest of his wiry frame oscillating in sympathetic motion. A playful grin erupts over his face. “No way, Mair, I’m not eventing you. Every time you’re evented you reply ‘maybe’ to the invite, and you never turn up! I’ll see you walking past a ‘Bucks sometime, and I’ll check your profile to see you’ve got nothing else on. Then you’ll have to let me buy you a coffee.” He pronounces her name ‘Mair’, but spells it ‘Mar’: saving a crucial character for those microblog posts.

“You’ll see that I have nothing else on…’maybe'” retorted Mary. The two of them laugh as they turn in opposite directions out of the OISHE main gate, Mary turning left toward the high street and the Tutte Building. Cars automatically slow down as she unconcernedly approaches the road, their computerised drivers detecting her position and speed and extrapolating that she probably means to cross seconds before she actually steps out into their path.

As the OSHE is not actually run by Ouroborus, neither is the MISCStore actually run by Milliard Internet Searching Company. “MISCStore” is the nickname given by students to the Williams Mart branch nearest to the school, whose systems are integrated with those of the search giant. Mary’s OWatch vibrates as she enters the store. “You have checked in at Will. Mart!” proclaims a notification. She selects a box of stylus tips, and takes them over to the cashier.

“Hi Mary,” the cashier says. While she has shopped at the MISCStore many times, Mary doesn’t recognise this particular employee either from the shop or school (judging by her age, and the fact that she can afford to live in Oxford, Mary guesses that the woman behind the counter is probably a fellow student). She must have read the name from her cash register, which would have received the same notification as Mary’s watch. The register will also be displaying pertinent facts from Mary’s profile; just the useful stuff like her credit rating and recent spending habits. “Just the styluses?”

“Just the styli,” Mary emphasises the last word as one of her few chances to show off her latlang A-level. Latlang is not a popular course and frequently gets one-star reviews from former students who felt that it was too hard and should, as a result, be free. Despite this, a hardcore of students (typically those who did quite well in the exams) have formed a bit of a latlang cult, with correct declension being the password between members. The cashier in MISCStore is, evidently, not among their number as the correction goes entirely without remark.

“Are you sure? It looks like you enjoy Winnesota brand hot chocolate, and we’ve got five percent off kilo packs at the moment. We think you’re really gonna love it.”

“Uh, no thanks. Just the styli, please.”

“Oh,” the cashier looked put out. “Should I go ahead and put that you don’t like Winnesota brand hot chocolate on your profile?”

“No, really, just no, it’s fine. I like the stuff, but I only bought it the once. I don’t really want any right now, it’s a bit pricey.”

“Not with five percent off it isn’t! We think it’d be the best thing to compliment your purchase of replacement touchscreen styluses.” Whether it was through a gargantuan effort of will or not seeing any issues with that sentence, the cashier kept a straight face throughout delivery.

“No, I don’t want your hot bloody chocolate! Look, I’m running late, I just need to buy these. O Watch,” this last being directed at her watch, triggering its speech command feature, “post that I’ll be late to the softscraft class. Can anyone take some notes for me?” She looked up again at the cashier. “Look, just the styli, they’re one ninety-nine right? Here’s my Millicard.”

“Thankyou for shopping at Willims Mart. Will you ‘Like’ this transaction on your profile? Liking is a great way to keep up with all the buzz and special deals on offer at Williams Mart!”

“Fuck off will I fucking like this fucking transaction! You’ve made me late with all this crap about chocolate and now you want to know if I like you? Piss off!” Having exhausted her daily allowance of expletives Mary turns to leave the store. She notices for the first time that a short bald man, a sort of overweight weasel that got its wish to be a real boy, is standing by a door behind the counter. As he isn’t wearing the cheap polyester official Williams/Milliard shirt he must be the manager.

“Thank you for shopping with us, miss. Company policy requires that after insulting our transaction enabler we must ask you to apologise on your public profile and to ‘Like’ Williams Mart.” Mary is storming out of the store and only barely hears the last part, “it is a federal crime to disregard compliance with any Williams Mart policy.”

Another vibration from her watch. “You have checked out.”

On the design of iOS 7 and iconographoclasm

As I write this, the WWDC keynote presentation has been over for a little more than half a day. That, apparently, is plenty of time in which to evaluate a new version of an operating system based on a few slides, a short demonstration, and maybe a little bit of playing with an early developer preview.

What I see is a lot less texture than an iOS 6 screen, with flatter, simpler icons and a very thin Sans Serif typeface. That’s because I’m looking at a Windows RT screen, though. What’s that? iOS 7 looks the same? They’ve gone Metro-style? Surely this heralds the end of days. Dogs and cats lying with each other, fire and brimstone raining from the sky. It would be time to give all the money back to the shareholders, except that it costs too much to bring all that cash back into the US.

Oh no, wait. It’s just a phone, not the apocalypse. Also it’s just less than half a day with a preview of a phone. If first impressions of a graphics set were enough to form a decision on how an artifact is to carry around with me all day, every day for the next couple of years, the iPhone would have been dead a long time ago. Remember the HTC Desire, with its bright, saturated background and parallax scrolling? Or the Samsung Galaxy series, with their bigger screens that are easier to see across a brightly-lit and packed showroom? How about the Nokia Lumia, with its block colours and large animations? Those are the kings of the short-tem attention grab. Coincidentally they’re the things that many journalists, trying to find an angle on day one of a device’s release, latched on to as obvious iPhone killers. Well, those and anything else released in the last few years.

What no-one has investigated is how the new iOS interface is to use all the time, because no-one has had all the time yet. I don’t know whether the changes Apple have made to the design are better, but I do know (largely because they mentioned it at the beginning of the talk) that they thought about them. The icons on the home screen, for example, are a lot more simplistic than they previously were. Is that because they were designed by some cretin wielding a box of Crayola, or did they find some benefit to simpler icons? Perhaps given a large number of apps, many users are hunting and pecking for app icons rather than relying on muscle memory to locate the apps they need. If this is true, a simpler shape could perhaps be recognised more quickly as the pages of apps scroll under the thumb.

As I say, I don’t know if the changes are for the better or not, but I do know they weren’t the result of whimsy. Though if Apple are chagrined at the noise of a million designers angrily dribbbling over their keyboards, they only have themselves to blame. It’s my belief that this evaluation of computer products based on what they look like rather than on their long-term use has its origin with Apple, specifically with the couple of years of Apple Design Awards that preceded the iPhone app store’s launch. It’s these awards that heralded the “Delicious generation” of app design that has informed Mac and iOS ISVs (and Apple) to date. It’s these awards that valued showy, graphically-rich apps without knowing whether they were useful: giving design awards to software that people could not, at time of award, yet use at all.

Now it turns out that many of these winners did indeed represent useful apps that you could go back to. I was a long-term user of Delicious Library 2 right up until the day Delicious Library 3 was launched. That benefit was not directly evident on the granting of the ADA though: what Apple were saying was “we would like to see you develop apps that look like this” rather than “we recognise this as the type of app our customers have derived lots of enjoyment from”. It’s my belief that this informed the aesthetics and values of the ISV “community”, including the values with which they appraised new software. If Apple are suffering a backlash now from people who don’t immediately love the new design of iOS 7, it is their own petard by which they have been hoisted.

Lighter UIViewControllers

The first issue of Objective-C periodical objc.io has just been announced:

Issue #1 is about lighter view controllers. The introduction tells you a bit more about this issue and us. First, Chris writes about lighter view controllers. Florian expands on this topic with clean table view code. Then Daniel explores view controller testing. Finally, in our first guest article, Ricki explains view controller containment.

Each of the articles is of a high quality, I thoroughly recommend that you read this. I powered through it this morning and have already put myself on the mailing list for the next issue. I think it’s worth quite a few dollars more than the $0 they’re asking.

On a more self-focussed note, I’m pleased to note that two of the articles cite my work. This isn’t out of some arrogant pleasure at seeing my name on someone else’s website. One of my personal goals has been to teach the people who teach the other people: to ensure that what I learn becomes a part of the memeplex and isn’t forgotten and reinvented a few years later. In APPropriate Behaviour a few of the chapters discuss the learning and teaching of software making. I consider it one of the great responsibilities of our discipline, to ensure the mistakes we had to make are not made by those who come after us.

The obj.io team have done a great job of researching their articles, taking the knowledge that has been found and stories that have been told and synthesising new knowledge and new stories from them. I’m both proud and humble about my small, indirect role in this effort.

enum class in C++11

I’ve opened the new edition of Cuboid Stroustrup exactly once, and I’ve already learned exactly one useful thing.

Before going into what that thing was, a comment on the book: The C++ Programming Language is, along with Object-Oriented Software Construction by Bertrand Meyer, one of the best books on a programming language I’ve ever read. In addition to explaining the language and its features, they explain why it is as designed. You get to find out how the various features are expected to be used: a great introduction to the idioms adopted by its community.

Conversely, Object-Oriented Programming: An Evolutionary Approach discusses much of the philosophy without going into much depth on the language itself. The C Programming Language goes the other way, explaining the language in detail without describing why any of its features were designed the way they were, or how you mighty want to put them together. It also happens that both of these books are too old to learn modern idiomatic use of their languages from.

Anyway, enum class. The problems with C enum are twofold: firstly the named values go into the global namespace so you can’t duplicate names (imagine if you wanted to have text alignment and view content mode enumerations, for example, you couldn’t use “Left” and “Right” as names in both places). Secondly, the values are just integers, so nonsense expressions like Left + Right are possible. What C++ has added recently is strongly typed, namespaced enum classes:

enum class TextAlignment { Left, Right };

You can’t do silly things like add these together, because TextAlignment is a custom type so it can’t be treated as an integer. You’d have to overload operator+() before addition could work—meaning you’d need a reason to do it. This is something I’ve long wanted in Objective-C, though my expectation is that Objective-C enumerations would be Flyweight Objective-C objects:

An Objective-C specific @enum type, which creates static, immutable instances. So you could have:

@enum GLScreenOrientation {Landscape, Portrait};

which creates a class like this:

@interface GLScreenOrientation: NSObject <NSCopying>
+ (GLScreenOrientation *)Landscape;
+ (GLScreenOrientation *)Portrait;
+ (NSSet *)values;
@end

This is modelled after the Java enum.