The joy of finishing

Then, the finish. Stain. Wipe. Wait. Stain. Wipe. Wait. Sand. Wipe. Stain. Wipe. Wait. Check. Seal. Wait. Sand. Wipe. Seal. Wait. Sand. Seal. Wait. And that's if everything goes according to plan.
Finishing. It's about woodworking. Or everything.  Or sometimes an essay about furniture is just an essay about furniture.

Let the right something in

There will always be more somethings we want to do than we have time to do. Right? Maybe.

  1. A lot of the right somethings can add up to a great thing, even if the somethings aren't of the highest quality or express the biggest idea.
  2. A lot of the wrong somethings aren't that interesting, unless your work is generally of great enough import that historians take an interest in it.
  3. A lot of the wrong somethings may not add up to much at all and are unlikely to attract the interest of historians.
  4. If you don't care about whether something's great, you can produce a lot of somethings.
  5. If you don't care if something expresses a big idea, you can produce a lot of somethings.

A lot of truisms will tell you that quality is the important thing and quantity is secondary. But perhaps there are all sorts of cases where that’s not entirely true.

Mozart wrote way more music than Beethoven; Beethoven’s was more sophisticated but their bodies of work are considered on the same level. There are way more episodes of Law and Order and all its spin-offs than Breaking Bad; one made more money, one gathered more acclaim.

Rather than deciding to pursue quality over quantity, perhaps it’s better to:

  • Choose your somethings with care
  • Execute on the idea central to those somethings
  • Produce as many somethings as possible without hating the quality of your work

Not that kind of log

First, read all of this excellent distillation of distributed systems by Jay Kreps,  The Log: What every software engineer should know about real-time data’s unifying abstraction. Now, consider this.

There’s a moment, when you’re building services and web APIs, when you think you’ve pretty much got it under control. You’ve got an endpoint for every query, a resource for every workflow. All the use-cases seem to be under control. And then, the question appears:

“How can I get access to all the updates to all the data? You know, for [REASONS].”

For APIs exposed to external developers over the web, this is where you’d reach for web hooks or PubSubHubbub. It’s not the best solution, but it works. If you’re building an internal system, you could  use the same approaches, or…you could build a log.

No not that kind of log. An event log, like LinkedIn did with Kafka for their internal systems. Every time your data model changes, every create, update, or delete, you drop an event with all the metadata related to the change. The event goes into some kind of single-producer, multiple consumer queue. Then all the clients that want to know about all the changes to all the things can read events off the queue and do whatever it is they need to for those important REASONS.

If you find this intriguing, this is a lot like replication in database systems. Definitely read LinkedIn’s article on this, and definitely read up on how your database of choice handles replication. And if you’ve built this before and have a good answer to initially populating “replicas” of a database, let me know; I haven’t come up with anything better than “just rsync it”.


Dear Sync Diary

Brent Simmons is keeping a diary as he works through implementing sync for Vesper, an iOS note-taking app. Building this sort of thing isn’t easy; cf. it took Cultured Code multiple years to implement it for Things. Thus it’s pretty neat that Simmons is breaking it down into understandable chunks:

If you think you need to implement a synchronization system for your application, try to find a shortcut so that you don’t. If you can’t find a shortcut, you could do worse than starting with these notes.


Tony Romo media circuses over the years

2011: should not have thrown that pass 2012: should not have allowed that pass to be tipped and intercepted 2013: should not have allowed his back to become herniated 2014: should not have gone back for that last donut

The Romo singularity is nigh! Soon Romo’s every facial expression will trigger wild fluctuations in betting lines. Prepare yourself.


This is how you chalkboard

vimeo.com/82253916

By pal Brandon Keepers, who I had no idea had that kind of talent. Well done!


Toot a horn while you test

Someone make me a thing that plays horn samples as my test suite runs. Every time a test or assertion finishes, toot the horn sample. A fast suite would sound like Phil Spector’s Wall of Sound (i.e. awesome), a slow one would sound like a grade school marching band (i.e. kill it with fire).


Give me all your Blackbird stories

The Blackbird had outrun nearly 4,000 missiles, not once taking a scratch from enemy fire.
Apparently its sister plane, the A-12, was not so lucky. I will always be a sucker for SR-71 stories, no matter how many times I may have heard them before.

Team superpowers: invest early, reap often

Startup Engineering Team Super Powers. You want all of these. Well-considered investments in tooling and conventions can pay out handsomely, and daily, if you put it in place sooner than later.


Aliens ate my program's state

So, Adam from a few years ago, you think you can build a distributed system?

Designing a concurrent system, one that runs across multiple processors using shared memory threads, is difficult because someone can move your cheese. One moment you’ve got food on your plate, and the next moment it’s on someone else’s plate.

Designing distributed systems, one that runs across multiple computers over networks that occasionally do weird things, is difficult because you can’t assume that the message will get through. One moment you’re telling your friend about an awesome new album and the next moment they don’t even know who you are anymore.

In both scenarios, you can’t assume the simplest case. You have to discard Occam’s razor; it’s entirely possible a perfectly devious alien is tinkering with your system, swallowing messages or preventing threads from running. For every operation in your system, you have to ask yourself what could go wrong and how will my system deal with that?

The first jarring thing about these sorts of problems is that you’re probably not using a framework. There are libraries to help you with logging, instrumentation, storage, coordination, and low-level primitives. There aren’t a lot of well-curated collections of opinions expressed as code. There’s no Rails, no Play, no Django, no Cocoa. There’s hardly even a Sinatra, a Celery, a JDBC.

That means you’re going to be designing, for real. Drawing on whiteboard, building prototypes and proofs of concepts. Getting feedback from as many smart people as you can corner. Questioning your assumptions, reading everything you can find on the topic. Looking for tradeoffs that decrease risk and simplify your problem domain.

Accept that you’re unlikely to ever get it entirely right. Those who are really good at it are more like Scotty than Spock. They’re surrounded by levers and measurements, tweaking and rebuilding the system as they go. It’s a fun puzzle!


NSHipster rainbow bar

NSHipster Rainbow bar

My favorite design touch in the Gowalla apps was the rainbow bar. Small wonder that fellow Gowalla alumni Mattt Thompson included one on the landing page for his collection of NSHipster essays that you can now buy as an eBook with cash money. Ed. apparently all the Gumroad pages have a rainbow bar. Mattt’s still awesome.


Database rivalry in the Valley

A couple years ago, Google released an embeddedable key-value database called LevelDB. There was much rejoicing. Recently, Facebook released their fork of LevelDB, RocksDB. There’s a slide deck comparing the two, but the amusing part is the “our way is better!” subtext. A little bit of Valley rivalry there. You can also learn a lot of interesting tidbits about the design of modern, high-performance database systems from the Architecture Guide and Table Format documentation of RocksDB.

Say what you will about tiny, highly-targeted ads. To some extent they are subsidizing a lot of interesting technology development and the open sourcing thereof.


The false bad guy

A pet peeve, in writing and thinking: introducing a false antagonist to create tension in a story. This is rampant in tech writing. Apple vs. Google, Ive vs. Forestall, Rails vs. Django, Ember vs. Angular, etc. But there’s no there, there. It’s only filling space.

I would love to have Ernest Hemingway weigh in on introducing a bad guy where one isn’t needed. I suspect there would be a lot of cursing involved.


Object-oriented relativism

When a Method Can Do Nothing, Michael Feathers:

If polymorphism means anything at all, it means that the object is in charge. We send it a message and it is up to it to decide what to do. That's core to OO and part of Alan Kay's original view of objects - that they are all about messaging. That said, it is not the dominant view today.
The majority of this article is on working with/around conditionals using intention-revealing method names or null objects. Yet, this paragraph smacked me in the face with "oh, yeah, obviously!". Lots of people view the moving parts in object-oriented languages as ways to group and share functionality. But to people who talk about OO a lot, read the history books, read the pattern books, know what SOLID is, etc. it's an entirely different thing.

Here’s a sports metaphor: the Dallas Cowboys are a widely disliked sports team, for various reasons. If I was from anywhere but Dallas, it would be “not cool” to count myself one a fan. But being from Dallas, I have an entirely different view on the Cowboys and can safely watch their mostly mediocre performances with occasional memories of greatness, safe from scorn.

I find that holding that tension in my head is important when talking to sports fans. It’s the same with OO: you haven’t read the books, watched the presentations, or worked the exercises I have. We’re on different pages, but we need to talk about the same code and how to structure it. There’s a tension between my understanding of OO and the next person, but it’s not a barrier. We have to get our language straight before we can talk about language!

In short, we have to establish what city in OO-land we’re from before we can effectively talk about OO.


Designing technological empowerment

Applied Discovery:

What future are we building, given that we play a role in such an important process?
On the role designers play, what they do as careers progress, and how design can positively enhance the world.

Reminder: if you tilt your head just so, developers do a lot of design activities too.


Friday at a Mexican restaurant

20131109-124843.jpg

Could be any Mexican restaurant. Could be any Friday. This one seemed special to me.


Currently intriguing me

A channel, a sewer, Alabama, and a sunset walk into a bar:

What’s intriguing you, dear reader?

Breakfast cannot wait, Prince

rd.io/x/QFWiK0E…

Look, Prince, I’m not sure if I can agree with you regarding “Breakfast Can Wait”. Cereal? Toast? English Muffins? Sure, those things can wait. Migas? Pancakes? Bacon? These things cannot wait. And don’t get me started on eggs; wait too long and delicious eggs can go rubbery and gross all too quickly.


A path through Enumerable

In Cocoa, you can poke inside object graphs (and more!) using dotted strings:

 NSDictionary *bestOfBeatles = @{@"paul": @{@"beatles": @"Hey Jude", @"solo": @"Jet"}};

NSString *solo = [bestOfBeatles valueForKeyPath:@"paul.solo"];
NSLog(@"Paul's Best solo song is: %@", solo);

Hey, did you notice that Objective-C sprouted some really handy literals for arrays and dictionaries lately? One could reasonably extrapolate that Apple has an interest in not breaking people’s fingers when they build for iOS and OS X.

There are libraries, e.g. Hashie, that make uniform access into object graphs, like you might get from an API response, as close to idiomatic Ruby as you probably want. Key paths, as implemented in Cocoa’s Key-Value Coding APIs, takes a different approach, using strings to define paths to traverse an object graph. I don’t really like “string programming”, but it’s an interesting approach, so let’s see where it takes us. Let’s add something like “key paths” to Ruby!

Hark, an implementation

Enumerable is an awesome thing about Ruby. Let’s build key path traversal on top of that. The goal is something close to the Objective-C snippet above:

 best_beatles = KVC.new({"paul" => {"beatles" => "Hey, Jude", "solo" => "Jet"}})
solo = best_beatles.for_path("paul.solo")
puts "Paul's best solo song is: #{solo}"

Turns out this isn’t hard to implement, even with a little error handling thrown in:

require 'delegate'

class KVC < SimpleDelegator

  def for_path(path)
    segments = path.split('.')

    segments.inject(self) do |value, s|
      if !value.respond_to?(:has_key?)
        raise ArgumentError.new("Expected #{value} to respond to has_key?")
      end

      if value.has_key?(s)
        value[s]
      else
        raise KeyError.new("Missing key #{s}")
      end
    end
  end

end

OK, first off, did you realize that SimpleDelegator makes it ridiculously easy to wrap objects with extra behavior? It sure does! Second, you could easily write this with a while loop or even a simple each, but why have local variables hanging around when you could use inject instead?![1] Third, this has more conditionals than I’d like, but it fits within 80 columns[2] so I’ll take it.

The pros and cons of using key paths

I’ve got this code, based on a whim. I’m not even sure it’s a good idea. Maybe it is!

  • It’s simpler to specify a traversal into a deep object graph with a string than with a bunch of key lookups or method chains. It’s slightly clearer too.
  • “Selector APIs”, like XPath or jQuery’s extensions to CSS, are an idea many developers have already wrapped their head around. I wouldn’t want to go anywhere near the complexity of those APIs, but an opinionated set of operations on an object graph might not get too complex.

Maybe it sucks?

  • Enumerable is pretty great, why wouldn’t you use that?
  • Programming by banging strings together is terrible.

Judgement

I can’t really tell you, definitively, if you should try this or not. I’ve barely even used KVC in Cocoa! It’s a nifty idea, though, and it’s pretty rad that you can implement something like it in Ruby so trivially.

Now you know!


  1. I realize this is a point of contention in the Seattle.rb ranks  ↩
  2. Forgive me now, Seattle.rb?  ↩

Football rules: not hard, even for the defense

The NFL is going through an awkward transition from laissez-faire bloodsport to something…less bloodsport-y. Players-turned analysts often rush to the side of the “victimized” defensive players who are now faced with…rules. It’s pretty dumb, on both sides:

  • It's not like these players learned different rules in high-school and college. Tackling is the same from age 12 onwards: you put your arms around a guy and pull him to the ground. Knocking a guy off his feet is just an impressive but dangerous form of bad tackling.
  • Defensive players already learn complicated blitzing and coverage schemes. To suppose they can't figure out how to hit a guy only between the knees and shoulders is a bit cynical.
  • All that defensive players do is react. React to a block, react to a ball-carrier cutting, react to a pass. Adding circumstances under which you can't clock another play is only a marginal increase to their rule-bound duties.
  • Football is always changing. New offenses, new defenses, new rules, new schemes, etc. Slightly changing how tackling works isn't going to turn football into badminton.
  • Players know what they're getting into in the short term: possible injuries. Not as many know what they're getting into on the long term: the possibility of being a zombie.
  • Some former-players have gone on to lead productive lives. Others have not, and a few have taken their own life rather than go on with the one football left them. Survivor bias is not a reason for inaction.
I think football can turn into something less about violence and more about strategy and skill, but only if those on the outside help those on the inside instead of helping those seeking the untenable status quo.