Sit on the fence between abstraction and practice

Theory and Practice is about a fence. It’s tempting to steer all the way towards the abstract, academic side, or all the way towards cutthroat practical side. Some of the most intriguing, productive people I’ve known sit on either side. Both sides like to accuse the other of not producing results, but that’s subjective. An academic’s results are wholly different from a practitioner’s results.

On occasion, you’ll run into someone who can actually explain complicated theory stuff to you in an accessible way. If you find someone like this, make sure to hold onto them closely, as they’re really rare. But they can help provide you with some insight that will really boost your productivity, without having to invest all the time in figuring out all that wankery that the priests of theory love.

This is a really nice way of explaining why someone like Richard Feynman is awesome. He was equal parts discoverer and explainer (plus another equal part mischief). This is exactly the thing I aim to achieve when I write here, make code, or present at conferences. There’s a whole bunch of ideas that aren’t in practice but, presented and packaged properly, can help move a lot of practitioners forward while recognizing the work of academics and nudging them to keep working in that area.

A lot of good things come out of connecting the people on opposite sides of the fence. Sitting on a fence isn’t exactly graceful, but sometimes it’s the only way to move ideas along. Don’t be afraid to eschew purity or pride for progress.


Marginal pennies and dollars

The give a penny, take a penny jar is a logical conundrum. It is not, on its surface, a rational thing. I have no data, but I suspect very few people who put money into them are doing so because they plan on taking money out later. A bank is different from a give/take a penny jar.

Personally, I put money in because I can and because I fancy myself not a jerk. The latter is what makes more rational sense. I put money in because it’s utility to me is marginal, but the utility of feeling better about myself is non-marginal.

In My Blue Heaven, Steve Martin plays a semi-reformed mobster in the witness protection program. He starts compiling a book of his truisms for living life. One is “it’s not so much tipping I believe in as over-tipping.” His character does this partially because he’s a little flashy, and partially, I think, because he has to be a likable protagonist.

I’d like to be a likable protagonist too, but I like over-tipping whenever possible for another reason. Pretty much anyone who works for tips is working really hard for every dollar they make. An extra dollar here or there is trivial to someone with a desk-job like myself, but less trivial to tip-earners who are technically paid less than minimum wage. An extra five or ten percent on a single tip won’t change their life, but it probably doesn’t hurt either.

I like making people’s day better with laughs and smiles, but I’m not above buying a tiny fraction of a better day for someone else. Marginal pennies and dollars add up.


Ruthlessness and fighting for it

You Are Not Ruthless Enough:

Being ruthless to yourself means every time you say “oh, I’ll just open up this internal bit over here…” use that moment to give yourself whatever negative feedback you need to go back and write the correct interface. Imagine the bugs you’ll get later. Give yourself a 12 volt shock through your chair. Picture the sleepless nights chasing down an issue that only happens for that one guy but it’s the guy who signs your paycheck.

I dropped this in my drafts folder months ago and came back to it today. It’s still something I need to hear. Get it working, and then ruthlessly edit and refactor until it’s code that won’t cause you to cringe when others bring it up.

In improv and code, I’ve recently come across the notion that there are things we need to fight for. Fight, not in the sense of conflict, but in the sense that there is an easy or natural way to do something, and then there is the way that maintains our sense of pride and quality. Not necessarily the “right” or high-minded way to do something, but the way that does not leave us feeling compromised as a creative person.

Your homework is to write down the qualities important to you, the ones that make you proud of your work and happy to share it. Then work from this checklist every day:

  1. Write the code, rehearse the scene, play the song, etc.
  2. <li>Decide whether it expresses your qualities.</li>
    
    <li>If it does, ship it. If it doesn't, edit ruthlessly until it does.</li>
    

Rinse/repeat/tell everyone about it.


Follow the smells

It’s handy to know a lot about programming langauges, patterns, “best” practices, and anecdotal experience in applying those ideas. But premature application of ideas can lead to its own bad experiences and new anecdotal evidence. How can you apply ideas without falling into the premature architecture/optimization trap?

Follow the smells.

You know what a bad method looks like. You know what slow code looks like and how to find it. You can tell when a class is doing too many things. Follow those smells.

Once you’ve smelled it, you’ve dealt it. Kidding!

Once you’ve found a culprit that is imminently making your life as a developer harder, you have to explain it to someone else. Tell them why it’s slow, badly coupled, or too much architecture. Once they’re convinced, then you can reach into that deep knowledge of languages, patterns, practices, and experience to fix the problem.

You commit the code, push it to production, and do a happy dance. You’re not done.

Now you need to share it. Write down what you did and share it with your team, lest the problem happen again. Show your co-workers how to find the problem elsewhere and quickly dispatch it.

If you do it this way, you’re helping yourself three times:

  1. You fixed the original problem
  2. You showed your colleagues how to fix the problem or how to avoid creating the problem
  3. You showed your colleagues how to make measurable, if minor, progress in making your application better without the need for drastic projects

Follow the smells. Fix the smell. Put the fix in everyone else’s brain. Repeat.


Know a little hardware

Consider:

  1. Google's intricate and massive data center operations, wherein Google is not only leading the pack in building distributed computing and database infrastructure, but building massive operations to run those systems.
  2. <li>"People who are really serious about software should make their own hardware." Alan Kay, creator of Smalltalk, object-oriented programming, and many other things that are good in your software development life, said that.</li>
    

I think Alan Kay’s quote could be rewritten for modern times to say, “Those who are really serious about large applications should make their own datacenters”. Assembling hardware, putting it into racks, putting the racks into data centers, and building out your own data centers are the analog of building your own hardware for software service companies these days.

You probably don’t need expert-level knowledge of these disciplines to write software today (e.g. I know diddly-squat about how packets find their way through the modern internet). You will, however, have a leg up if you’re aware of the possibilities and know how to take advantage of them. Even if you’re building applications with modest capacity needs, knowing how to set up a failover database and when to pay for physical hardware instead of virtualized hosts is a thing that will make your customers and clients happy.

More concisely: when it comes to running your software on hardware, one size does not fit all; know how and when to tailor your application to the hardware, no matter what size your application wears.


A kingdom of concerns

When doing object-oriented programming and following SOLID principles, there is sometimes a concern that classes will proliferate and you end up with a Kingdom of Nouns.

I find it more concerning when there is a proliferation of concepts. Too many layers, too many patterns, too many frameworks. The best designs I’ve seen provide just one or two concepts that manage to tie everything together without breaking orthogonality.

The great thing about Rails and Sinatra was that they boiled previously conceptually heavy domains down to a simpler, better set of ideas. In doing so, they move you up the hierarchy of needs, so to speak, and you still end up inventing your own concepts and nouns. More on that soon!


Invent the right thing

You have to invent the right thing. Some things you might invent:

  1. A solution to a problem. Nothing novel, just an answer for a question. Eg. any Rails/Django/etc. application.

  2. An application of some existing techonologies in a novel way. Eg. integrating a library to avoid inventing your own solution.

  3. An incrementally better, specific kind of mouse trap. Eg. building on top of existing infrastructure to solve a problem better than any existing solutions.

  4. An entirely new kind of mousetrap. Eg. building wholly new infrastructure because you face a high quality, unique problem that you are imminently required to solve.

Inventing the wrong thing means you’re operating at the wrong level. If you’re too high, you’re spinning your wheels on problems you hope to have. If you’re too low, you’re spinning your wheels on building something that isn’t sufficient to solve your problems. If you’re at the right level, you’re mostly solving problems you actually face and not solving too my coincidental problems.

This doesn’t mean new problems shouldn’t be tackled and new techonologies should not be invented. It applies mostly to reinventing wheels. That is, a project starts with level 1, not level 3 or 4. Apply a technology and improve it before you push the edge. In fact, you must push the limits of an extant technology before level 4 is the right answer. No skipping allowed.

Don’t let imposter syndrome lead you to the wrong technology decision. I’ve tried to build at the wrong level in the past because I felt like I had to fit in with the level of what others working on larger systems were building. Wrong answer.

It’s OK to build a scooter instead of a spaceship if all you need to do is go pick up the mail.


A better shared space

Remote teams are hard. Not impossible hard, but running uphill hard. It’s hard because people are used to interacting face-to-face. Given the opportunity, they’ll interact with those around them rather than those in virtual spaces.

The trick, I think, is to make a better shared space for a remote/local team than the physically shared space they already have. A space that is just as fluid, fun, and useful as a physical space and available anytime, everywhere is more compelling because it affords its occupants (aka team members) more hours in their day (no commuting, flexible hours) and permits all sorts of non-traditional work locations (coffee shops, trains, sofas at home, a summer trip to Europe).

Decoupling work from location and time is a big deal. I hope more companies, in software and outside of it, attempt to solve it.


I got Clojure stacks

Here’s a Sunday afternoon hack. It’s a “stack” machine implemented in Clojure. I intended for it to be a stack machine, no airquotes, but I got it working and realized what I’d really built was a machine with two registers and instructions that treat those two registers as a stack. Pretty weird, but it’s not bad for a weekend hack.

I’m going to break my little machine down, and highlight things that will feel refreshingly different to someone, like me, who has spent the past several years in object-oriented languages like Ruby. What follows is observations; I’m still very new to Clojure, despite familiarity with the concepts, so I’ll pass on making global judgements.

Data structures as programs as data

I’ve seen more than one Rubyist, myself included, say that code-as-data, a concept borrowed from Lisp’s syntax, is possible and regularly practiced in Ruby. DSLs and class-oriented little languages accomplish this, to some degree. In my experience, this metaprogramming is really happening at the class level, using the class to hold data that dynamic code parses to generate new behaviors.

In contrast, Clojure, being a Lisp, programs really are data. To wit, this is the crux of my stack machine; the actual stack machine program is a Clojure data structure that in turn specifies some Clojure functions to execute:

    (def program
      [['mpush 1]
       ['mpush 2]
       ['madd]
       ['mpush 4]
       ['msub]
       ['mhalt]])

    (run program)

If you’ve never looked at Clojure or Lisp code, just squint and I bet you’ll keep up. This snippet defines a global variable, of sorts, program, whose value is a list of lists (think Arrays) specifying the instructions in my stack machine program. In short, this program pushes two values on the stack, 1 and 2, adds them, pushes another value 4, subtracts 4 from the result of the addition, and then halts, which prints out the current state of the “stack” registers.

I’ve got a function named run which takes all these instructions, does some Clojure things, then hands them off to instruction functions for execution.

Some familiar idioms

Let’s look at run. It’s really simple.

    (defn run [instructions]
      (reduce execute initial-state instructions))

This function takes one argument, instructions, a Clojure collection (generally called a seq; this one in particular is a vector). Clojure has an amazing library of functions that operate on collections, just as Ruby has Enumerable. In fact, reduce in Clojure is the same idea as inject in Ruby (reduce is aliased to inject in Ruby!). The way I’m calling it says “iterate over a collection instructions, calling execute on each item; on the first iteration, use initial-state as the initial value of the accumulated collection”.

initial-state is another global variable whose value is a mapping (in Ruby, a hash) that maintains the state of the machine. It has two keys, op-a and op-b, representing my two stack-ish registers.

    (def initial-state
      {:op-a nil :op-b nil})

Now you’d expect to find an execute function that takes a collection plus a value and generates a new version of the collection, just like Ruby’s inject. And here that function is:

    (defn execute [state inst]
      (let [fun (ns-resolve *ns* (first inst))
            params (rest inst)]
        (apply fun [params state])))

This one might require extra squinting for eyes new to Clojure. execute takes two arguments, the current state of the stack machine, state, and the instruction to execute, inst. It then uses let to create local variables based on the values of function’s parameters. I use Clojure’s mechanism for turning a quoted variable name (quoting, in Lisp, means escaping a variable name so the interpreter doesn’t try to evaluate it) into a function reference. Because the instruction is of the form [instruction-name arg arg arg ...], I use first and rest to split the instruction into the function name, bound to fun and argument list, bound to params.

The meat of the function “applies” the function I extracted in the let block to the arguments I extracted out of the instruction. Think of apply like send in Ruby; it’s a way to call a function when you have a reference to it.

The sharp reader would now start searching for a bunch of functions, each of which implements an instruction for our stack machine. And so…

Some boilerplate arrives

Here is the implementation for mpush, madd, and mhalt:

    (defn mpush [params state]
      (let [a (state :op-a)
            b (state :op-b)
            v (first params)]
        {:op-a v :op-b a}))

    (defn madd [params state]
      (let [a (state :op-a)
            b (state :op-b)]
        {:op-a (+ a b) :op-b nil}))

    (defn mhalt [params state]
      (println state))

Each instruction takes some arguments and the state of the machine. They do some work and return a new state of the stack machine. Easy, and oh-so-typically functional!

These instructions are where I’d introduce something clever-ish in Ruby. That let where the register values are extracted feels really boilerplate-y. In Ruby, I know what I would do about that: a method taking a block, probably.

I’m not sure how I’d clean this up in Clojure. A macro, a function abstraction? I leave it as an exercise to the reader, and to myself, to find something that involves less copypasta each time a new instruction is implemented.


I found some pleasant surprises in this foray into Clojure:

  • Building programs from bottom-up functions in a functional language is at least as satisfying as doing the same with a TDD loop in an object-oriented language. It is just a conducive to dividing a problem into quickly solved blocks and then putting the whole thing together. It does, however, lack a repeatable verification artifact as a secondary output.
  • At first I was a little skeptical of the fact that Clojure mappings (hashes) can be treated as data structures, by passing them to functions, or as functions, by calling them using a key to extract as the parameter. In practice, this is a really awesome thing and it’s a nice way to write one’s own abstractions as well. There’s something to using higher-order functions more prevalently than Ruby does.
  • The JVM startup isn’t quick in absolute terms, but at this point it’s faster than almost any Rails app, and many pure Ruby apps, to boot. Damning praise for the JVM and Ruby, but the take-away is I never felt distracted our out-of-flow due to waiting around on the JVM.

Bottom line: there’s a lot to like in Clojure. It’s likely you’ll read about more forays into Clojure in this space.


Faster, computer program, kill kill!

Making code faster requires insight into the particulars of how computers work. Processor instructions, hardware behavior, data structures, concurrency; it’s a lot of black art. Here’s a few things to read on the forbidden lore of fast programs:

Fast interpreters are made of machine sympathy. Implementing Fast Interpreters. What makes the Lua interpreter, and some JavaScript interpreters, so quick. Includes assembly and machine code details. Juicy!

Lockless data structures, the easy way. A Java lock-free data structures deep dive. How do those fancy java concurrent libraries work? Fancy processor instructions! Great deep dive.

Now is an interesting time to be a bottleneck. Your bottleneck is dead. Hardware, particularly IO, is advancing such that bottlenecks in code are exposed. If you’re running on physical hardware, especially if you have solid-state disks, your bottleneck is probably language-bound or CPU-bound code.

Go forth, read a lot, measure twice (beware the red herrings!), and make faster programs!


Designing for Concurrency

A lot is made about how difficult it is to write multi-threaded programs. No doubt, it is harder than writing a CRUD application or your own testing library. On the other hand, it’s not as difficult as writing a database or 3D graphics engine. The point is, it’s worth learning how to do. Skipping the hubris and knowing your program will have bugs that require discipline to track down is an enabling step to learning to write multithreaded programs.

I haven’t seen much written about the experience of writing a concurrent program and how one designs classes and programs with the rules of concurrency in mind. So let’s look at what I’ve learned about designing threaded programs so far.

The headline is this: only allow objects in consistent states and don’t rely on changing state unless you have to. Let’s first look at a class that does not embody those principles at all.

class Rectangle
  attr_accessor :width, :height

  def orientation
    if width > height
      WIDE
    else
      TALL
    end
  end

  WIDE = "WIDE".freeze
  TALL = "TALL".freeze
end

Just for fun, mentally review that code. What are the shortcomings, what could go wrong, what would you advise the writer to change?

For our purposes, the first flaw is that new Rectangle objects are in an inconsistent state. If we create an object and immediately call orientation, bad things will happen. If you’re typing along at home:

begin
  r = Rectangle.new
  puts r.orientation
rescue
  puts "whoops, inconsistent"
end

The second flaw is that our object allows bad data. We should not be able to do this:

r.width = 100
r.height = -20
puts r.orientation

Alas, we can. The third flaw is that we could accidentally share this object across threads and end up messing up the state in one threads because of logic in another thread. This sort of bug is really difficult to figure out, so designing our objects so it can’t happen is highly desirable. We want to make this sort of code safe:

r.height = 150
puts r.orientation

When we modify width or height on a rectangle, we should get back an entirely new object.

Let’s go about fixing each of these flaws.

Encapsulate object state with Tell, Don’t Ask

The first flaw in our Rectangle class is that it isn’t guaranteed to exist in a consistent state. We go through contortions to make sure our databases are consistent; we should do the same with our Ruby objects too. When an object is created, it should be ready to go. It should not be possible to create a new object that is inconsistent.

Further, we can solve the second flaw by enforcing constraints on our objects. We use the “Tell, Don’t Ask” principle to ensure that when users of Rectangle change the object’s state, they don’t get direct access to the object’s state. Instead, they must pass through guards that protect our object’s state.

All of that sounds fancy, but it really couldn’t be simpler. You’re probably already writing your Ruby classes this way:

class Rectangle
  attr_reader :width, :height

  def initialize(width, height)
    @width, @height = width, height
  end

  def width=(w)
    raise "Negative dimensions are invalid" if w < 0
    @width = w
  end

  def height=(h)
    raise "Negative dimensions are invalid" if h < 0
    @height = h
  end

  def orientation
    if width > height
      WIDE
    else
      TALL
    end
  end

end

A lot of little things have changed in this class:

  • The constructor now requires the width and height arguments. If you don’t know the width and height, you can’t create a valid rectangle, so why let anyone get confused and create a rectangle that doesn’t work? Our constructor now encodes and enforces this requirement.
  • The width= and height= setters now enforce validation on the new values. If the constraints aren’t met, a rather blunt exception is raised. If everything is fine, the setters work just like they did in the old class.
  • Because we’ve written our own setters, we use attr_reader instead of attr_accessor.

With just a bit of code, a little explicitness here and there, we’ve now got a Rectangle whose failure potential is far smaller than the naive version. This is simply good design. Why wouldn’t you want a class that is designed not to silently blow up in your face?

The crux of the biscuit for this article is that now we have an object with a narrower interface and an explicit interface. If we need to introduce a concurrency mechanism like locking or serialization (i.e. serial execution), we have some straight-forward places to do so. An explicit interface, specific messages an object responds to, opens up a world of good design consequences!

Lean towards immutability and value objects whenever possible

The third flaw in the naive Rectangle class is that it could accidentally be shared across threads, with possibly hard to detect consequences. We can get around that using a technique borrowed from Clojure and Erlang: immutable objects.

class Rectangle
  attr_reader :width, :height

  def initialize(width, height)
    validate_width(width)
    validate_height(height)
    @width, @height = width, height
  end

  def validate_width(w)
    raise "Negative dimensions are invalid" if w < 0
  end

  def validate_height(h)
    raise "Negative dimensions are invalid" if h < 0
  end

  def set_width(w)
    self.class.new(w, height)
  end

  def set_height(h)
    self.class.new(width, h)
  end

  def orientation
    if width > height
      WIDE
    else
      TALL
    end
  end

end

This version of Rectangle further extracts the validation logic into separate methods so we can call it from the constructor and from the setters. But, look more closely at the setters. They do something you don’t often see in Ruby code. Instead of changing self, these setters create an entirely new Rectangle instance with new dimensions.

The upside to this is, if you accidentally share an object across threads, any changes to the object will result in a new object owned by the thread that initiated the change. This means you don’t have to worry about locking around these Rectangles; in practice, sharing is, at worst, copying.

The downside to this side is you could end up with a proliferation of Rectangle objects in memory. This puts pressure on the Ruby GC, which might cause operational headaches further down the line. Clojure gets around this by using persistent data structures that are able to safely share their internal structures, reducing memory requirements. Hamster is one attempt at bringing such “persistent” data structures to Ruby.

Let’s think about object design some more. If you’ve read up on domain-driven design, you probably recognize that Rectangle is a value object. It doesn’t represent any particular rectangle. It binds a little bit of behavior to a domain concept our program uses.

That wasn’t so hard, now was it

I keep trying to tell people that, in some ways, writing multithreaded program is as simple as applying common object-oriented design principles. Build objects that are always in a sensible state, don’t allow twiddling that state without going through the object’s interface, use value objects when possible, and consider using immutable value objects if you’re starting from scratch.

Following these principles drastically reduces the number of states you have to think about and thus makes it easier to reason about how the program will run with multiple threads and how to protect data with whatever form of lock is appropriate.


Three application growth stories

First you grow your application, then you grow your organization, and then you get down to the metal and eek out all the performance you can.

Evolution of SoundCloud’s Architecture, this is how you grow an application without eating the elephant too soon. I would love to send this back to Adam from two years ago. Note that they ended up using RabbitMQ as a broker instead of Resque as a job queue. This nuanced position put them in a pretty nice place, architecturally.

Addicted to Stable is equal parts “hey, you should automate things and use graphs/monitoring to tell you when things break” and “look at all of GitHub’s nifty internal tools”. Even though I’ve seen the latter a few times already, I like my pal John Nunemaker’s peak into how it all comes together.

High Performance Network Programming on the JVM explains how to choose network programming libraries for the JVM, some pro’s and con’s to know about, and lays out a nice conceptual model for building network services. Seems like this is where you want to start once you reach the point where your application needs to serve tens of thousands of client concurrently.

I’m going to keep posting links like these until, some day, I feel like I’m actually doing it right. Until then, stand on other people’s shoulders, learn from experience.


One part mechanics, one part science

One black-and-white perspective on building software is that part of it is about mechanics and part of it is about science. The mechanics part is about wiring things up, composing smaller solutions into bigger ones, and solving any problems that arise in the process. The science part is taking problems that don’t fit well into the existing mechanisms and making a new mechanism that identifies and solves all the right puzzles.

You could look at visual and interaction design in the same way. The mechanical part is about using the available assets and mechanisms to create a visual, interactive experience on screens that humans interact with. The science is about solving a problem using ideas that people already understand or creating an idea that teaches people how to solve a problem.

The mechanical case is about knowing tools, when to use them, and how they interact with each other. The scientific case is about holding lots of state and puzzle in your head and thinking about how computers or people will interact with the system.

I’ve observed that people end up all long the spectrum. Some specialize on mechanics, others on science. The rare case that can work adeptly on both sides, even if they’re not the best at either discipline, is really fun to watch.


Constructive teamwork is made of empathy

We nerds are trained from an early age to argue on the internet, hone our logical skills, and engage with people based on data instead of empathy.

twitter.com/gotascii/…

It’s so hard to divorce reason, emotion, and making progress on a project. Letting a logical inconsistency go is harder than forcing someone to see the flaw in their reasoning. Getting angry or worked-up feels more powerful than a supportive attitude. There are so many disasters to avoid, it’s hard to not to force everyone to listen to all the things you’ve been burned by previously and how you want to avoid them at all costs.

Take a deep breath. Fire up your empathy muscles. Figure out how to say “yes” to the work of your teammates while using your experience to guide that work to an even better place. This is what they call “constructive teamwork”.


Futures, Features, and the Enterprise-D

A future is a financial instrument (a thing you invest in) where you commit to paying a price today to receive something tomorrow. The price could go up or down tomorrow, but you’re locked into today’s price. Price goes up, you profit; price goes down, you eat the difference.

A feature is a thing that software does. For our purposes, we’ll say it’s also work that enables a feature: setting up CI, writing tests, refactoring code, adding documentation, etc. The general idea behind software development is that you should gain more time using a feature than the time you spent implementing it.

The Enterprise-D is a fictional space ship in the Star Trek: The Next Generation universe. It can split into two spaceships and is pretty well armed for a ship with an exploratory mission.


Today, Geordi and Worf (middle management) are recalibrating the forward sensor array. It takes them most of the day, but they get the job done. Captain Picard is studying ancient pan-flutes of the iron-age Vulcan era. Data (an android), as an experiment on his positronic net, is trying to learn how to tell an Aristocrat joke.

Tomorrow, in a series of events no one could predict, our friends find themselves in a tense situation with a Romulan Bird of Prey. Luckily, Worf detected it minutes before it decloaked, thanks to the work he and Geordi had performed the day before. This particular Bird of Prey is carrying ancient Romulan artifacts dating back to their own iron age. Amazingly, Picard is able to save the day by translating the inscriptions, which aren’t too different from Vulcan pan-flutes, and prevents an ancient doomsday weapon from consuming the Bird of Prey and Enterprise alike.

Data’s Aristocrat joke is never used. That’s good, because this is a family show.


Our friends on the Enterprise are savvy investors who look at their efforts in terms of risk and reward. They each invest time today into an activity (an instrument, in financial terms) which they may or may not use tomorrow. We can say that if they end up using the instrument, it pays off. We can then measure the pay-off of that instrument by assigning a value to the utility of that instrument. If the value of the instrument exceeds the time they invested in “acquiring” it, there is a profit.

Geordi and Worf’s investment was clearly a profit-bearing endeavor. Few other uses of their time, such as aligning the warp crystals or practicing Klingon combat moves, could have detected an invisible ship before it uninvisibles itself. In Wall Street terms, Geordi and Worf are getting the fat bonus and bottle of Bollinger champagne.

Picard’s investment seems less clear cut. It did come in handy in this particular case, but it probably wasn’t the only activity that would have saved the day. He could have belted out some Shakespeare or delegated to one of his officers to reconfigure the deflector dish. We’ll mark Picard as even for the day.

Data totally blew this one. His Aristocrat joke went unused. Even if he had used it, the best outcome would be that it’s a lame, sterile groaner that only ends up on a DVD extras reel. Data is in the red.

In terms of futures, we can say that the price of working on the foward sensor array went up, the price of pan-flute research was largely unchanged, and the price of Aristocrat jokes plummeted. Our friends on the Enterprise implicitly decided what risks are the most important to them and hedged against three of them. Some of them even came out ahead!


I’m working on software. Today, I can choose to do things on that software. I could 1) start on adding a new feature, 2) shore up the test suite, or 3) get CI setup and all-green. Respectively, these are futures addressing 1) the risk of losing money due to missing functionality, 2) losing money because adding features takes too long to get right, or 3) losing money because things are broken or not communicated in a timely manner.

Like our Enterprise episode, it’s hard to value these futures. If I deliver the feature tomorrow and it generates more money than the time I put into implementing, testing, and deploying the code, we’re looking at a clear profit. Revenue minus expense equals profit, grossly speaking.

Shoring up the test suite might make another feature easier to implement. It might give me confidence in moving code around to facilitate. It could tell me when I’ve broken some code, or some code is poorly designed and holding me back. But, these values are super hard to quantify. Did I save two hours on some feature because I spent one hour on the test suite yesterday? Tricky question!

Chore-ish tasks, like standing up a CI server or centralizing logs, are even harder to quantify. Either one of these tasks could save hours and days of wasted time due to missed communication or troubleshooting an opaque system. Or, they might not pay off at all for weeks and months.


I’m going to start writing down what I worked on every day, guess how many hours I spent on it, and then revisit each task weekly or monthly to guess if it paid out. Maybe I’ll develop an intuition for risk and reward for the things I work on. Maybe I’ll just end up with a mess of numbers. Almost certainly, I will seem pretty bookish and weird for tracking these sorts of things.

You should look bookish and weird too. Let me know what you find. I’ll write up whatever we figure out. Maybe there’s something to this whole “finance” thing besides nearly wrecking the global economy!


A romantic comedy: OO and FP

My magic ball predicts that OO and FP are going to take something of a “romantic comedy” path of evolution.

Act I. OO and FP are introduced at dinner parties and they could not seem more dissimilar and hilarious arguments ensue. No one goes home together. Despite the initial miss, the end of Act I finds OO and FP separately talking to friends about how they want the same things.

Act II. OO and FP run into each other at the coffee shop, and then again at the gym. OO is reading a book on ideas that FP loves. One of their friends invites them both to a bar, they get a little sauced and end up making out a bit. OO starts wearing FP’s jacket around town, even finding it a little comfortable. Towards the end of Act II, OO and FP are a bonfide thing, both borrowing ideas from each other. It’s pretty cute.

Act III. Open with a fight between OO and FP. It seems they just can’t come to agree on some important topic like mutability or the nature of behavior and state. Unfortunate and emotional words are uttered. The internet is abuzz with talk of the drama. They go back to their respective friends and rant about the shortcomings of the other. But, late at night, OO finds that not having FP around is less awesome than having FP around. OO cooks up a cooky plan to get FP back into their life. Hilarity, and a little awkwardness ensue. In the end, FP and OO go great together and we end with a montage of “everyone lived happily after” and see a clip that alludes to an OO/FP baby on the way.

If you’re playing at home, we’re already in Act II. Ruby and Python borrow various ideas on iteration from FP languages. We might be towards the end of Act II; Scala is very much wearing ML’s jacket around town. Surely there will be fallout at some point, someone ranting about how OO FP hybrids are too large, too poorly designed, too complicated, etc. The dust will settle, and someone will build an even better OO FP hybrid. Act III will play repeatedly until no one thinks of languages as OO FP hybrids, they just think of them as another language.

Then something different from OO or FP will become obviously useful and this whole romantic comedy will play again. It’s the way of Hollywood, and the way of software development. Everything old is new again; everything new is old again. Rinse, repeat.


Rediscovery: OO and FP

I’ve noticed some of the sharpest developers I know are doing one or both of these things:

  • Rediscovering object oriented design. Practicing evolving a design, often driven by the pain points illuminated by automated tests. Thinking about coupling and cohesion. Trying to encapsulate the right behaviors and find decide which principles are the most appropriate to the languages and systems they’re using.

  • Rediscovering functions. Applying functional programming to everyday programming problems. Using the features of functional languages as an advantage to build concurrent and distributed systems. Finding the differences in functional design and writing more idiomatic code.

The first is a cyclical thing. It happened in Java, it happened in .NET, it’s happening in Ruby now. People come to a language for what makes it different, write a lot of stuff, and keep bumping into the same problems. They (re-)discover OO, start refactoring things and shaping their systems differently. Some people dig it, others dismiss it as too much effort or ceremony. A new thing comes along, and it all happens again.

The second is harder for me to read. I’ve spent a fair amount of time studying FP, though I have yet to apply it to production software. Despite that, I have come across a lot of good ideas that are already part of the code I work with daily, or that I wish was part of the code I work with. FP has good answers to composing systems, reasoning about state, and handling concurrency. It has often suffered from a lack of pragmatism, overly dense literature, and rough tooling. The ideas are worth stealing, even if they haven’t broadly succeeded.

Both of these trends are crucial to moving the practice of software development forward. We need to keep rediscovering and sharpening old ideas whilst experimenting with new ideas to find out which ones are good and which ones less so.


Three kinds of distributed systems

Little-d distributed systems: the accidental sort. You built a program, it ran on one server. Then you added a database, some caches, perhaps a job worker somewhere. Whoops, you made a distributed system! Almost everything works this way now.

Big-D distributed systems: you read the Dynamo paper, maybe some Lamport papers too, and you set out to build on the principles set forth by those who have researched the topic. This is mostly open source distributed databases, but other systems surely fall under this category.

Ph.D distributed systems: you went to a top CS school, you ended up working with a distributed systems professor, and you wrote a system. You then graduated, ended up at Google, Facebook, Amazon, etc. and ended up writing more distributed systems, on a team of even more Ph.D’s.

If you’re building a little-d distributed system, study the patterns in the Big-D distributed systems. If you’re building a Big-D distributed, study what the Ph. D guys are writing. If you’re a Ph. D distributed system guy, please, write in clear and concise language! No one knows or cares what all the little greek symbols are, they just want to know what works, what doesn’t work, and why.


Protect that state: locks, monitors, and atomics

You need to protect a piece of data, like a counter or an output stream, from getting garbled by multiple threads.

Three choices, hot shot:

  • Explicit locks (aka mutexes): acquire a lock around the “critical section”, munge the data, release the lock. You have to manage the lock yourself. Multiple threads accessing the lock will not run concurrently anymore.
  • Implicit locks (aka monitors): annotate methods that modify important data. The monitor library manages the lock for you. Threads still serialize around the lock, reducing concurrency.
  • Atomic objects (aka compare-and-swap): use data structures that take advantage of runtime or processor semantics to guarantee that competing threads never interfere with each other. No locks! Much less serializing! Not broadly applicable, but I highly recommend them when you have the means.

Mutexes, aka lock “classic”

Mutexes are the lowest level of locks, at least in Ruby. They are the ur-locks, the most primitive of locks; everything is built on top of them. With any luck, you won’t ever need to use them directly, but it helps knowing how they work.

Eighty percent of what you need to know is synchronize. You create a lock, and then you use it to protect a piece of code that would go sideways if multiple threads hit it at the exact same time. Here’s a little class that locks around printing to standard output:

class Output

  def initialize
    @lock = Mutex.new
  end

  def log(msg)
    @lock.synchronize { puts msg }
  end

end

Using Output#log instead of puts will prevent the output of your multithreaded program from getting jumbled and confused by everyone writing to stdout at the same time. You could manually lock and unlock a Mutex if you had special needs.

Let’s talk counters

For the next couple examples, we’re going to implement a counter. Multiple threads will update said counter, so it needs to protect itself. Here’s how we use the counter:

    require 'thread'

    CORES=2
    ITERS=1_000

    threads = CORES.times.map do |n|
      Thread.new do
        ITERS.times do |i|
          out.log("Thread #{n}: Iteration: #{i} Counter: #{counter.value}") if i % 100 == 0
          counter.incr
        end
      end
    end

    threads.each(&:join)
    p counter.value

My Macbook Air has two real cores (don’t believe the hype!) and we’ll increment the counter a thousand times in each thread. Every hundred times through the loop, we’ll show some progress. At the end, we join each thread and then print the value of our counter. If all goes well, it will be CORES * ITERS.

All would not go well with this naive implementation:

class WildCounter

  def initialize
    @counter = 0
  end

  def incr
    @counter = @counter + 1
  end

  def value
    @counter
  end

end

If two threads execute incr at the same time, they will misread @counter or unintentionally overwrite a perfectly good value that was incremented behind their back.

We could protect this counter with a mutex, but I want to show you two other ways to go about it.

Monitors, aka intrinsic locks

Turns out, a well-designed class will tend to isolate state changes to a few methods. These “tell, don’t ask” methods are what you’ll likely end up locking. It would be pretty rad if you could just wrap a lock around the whole method without having to create variables and do a bunch of typing, don’t you think?

Those are a thing! They’re called monitors. You can read a bunch of academic stuff about them, but the crux of the biscuit is, a monitor is a lock around an entire instance of an object. You then declare methods that can only execute when that lock is held. Here’s a counter that uses a monitor:

require 'monitor'

class MonitorCounter

  def initialize
    @counter = 0
    # No idea why this doesn't work inside the class declaration
    extend(MonitorMixin)
  end

  def incr
    synchronize { @counter = @counter + 1 }
  end

  def value
    @counter
  end
end

It doesn’t look too much different from our naive counter. In the constructor, we extend Ruby’s MonitorMixin, which imbues this class with a lock and a synchronize method to protect mutator methods. (Ed. if anyone knows why the extend has to happen in the constructor instead of in the class declaration, I’m extremely stumped as to why!)

In incr, where we do the dirty work of updating the counter, all we need to do is put the actual logic inside a synchronize block. This ensures that only thread may execute this method on any given object instance at a time. Two threads could increment two counters safely, but if those two threads want to increment the same counter, they have to take turns.

A brief note on terminology: many Java concurrency texts refer to monitors as “intrinsic” locks because, in Java, they are part of every object. Mutexes are referred to as “extrinsic” locks because they aren’t tightly associated with any particular object instance.

Atomics, aka “wow that’s clever!”

It turns out that, in some cases, you can skip locks altogether. Amazing, right?!

Unfortunately, Ruby doesn’t have core support for atomic objects. Fortunately, Charles Nutter’s atomic library provides just that. It exploits operations provided by the underlying platform (the JVM in the case of JRuby, atomic compare-and-swap operations on Intel in the case of Rubinius) to implement objects that are guaranteed to update within one processor clock cycle. These operations work by taking two parameters, the old value and the new value; if the current value matches the old value, it’s safe to update it to the new value. If it doesn’t match, the operation fails and you have to try again.

Phew! Now you know a lot about atomic processor operations.

“Show me right now, Adam!” you say. Much obliged.

require 'atomic'

class AtomicCounter

  def initialize
    @counter = ::Atomic.new(0)
  end

  def incr
    @counter.update { |v| v + 1 }
  end

  def value
    @counter.value
  end

end

Luckily, Atomic encapsulates all the business of comparing and swapping and knowing about how to use atomic instructions. It maintains the value of the object internally and handles all the swapping logic for you. Call update, change the object in the block, and go on with your life. No locks necessary!

If that doesn’t make you love modern computer hardware, you are a programmer who does not know joy.

Tread carefully

Congratulations, you are now somewhat conversant on the topic of locking in concurrent Ruby programs. You know what the tools are, but, unfortunately, I haven’t the space to educate you on all the ways you are now equipped to shoot yourself in the foot. If you’re curious, you can read up on deadlock, livelock, starvation, priority inversion, and all the failure cases for dead processes left holding a lock.

The principle I try to follow, when I’m presented with a problem that needs locking, is to ask if I can work around the need for locking somehow. Could I use a Queue or atomic? Could I isolate this state in one thread and obviate the need for the lock? Is this state really necessary at all?

To anti-quote Ferris Buehler’s Day Off, when it comes to adding locks, “I highly unrecommend it, if you have the means”.


Chronologic, a piece of software history

It’s long past time to call Chronologic a project at it’s end-of-life. About a year ago, it went into serious use as the storage system for social timelines in Gowalla. About six months ago, the Gowalla servers were powered down; no epilogue was written. In my work since then, I haven’t had the need for storing timelines and I haven’t been using Cassandra much at all. So, what purpose can Chronologic serve now that it’s not actively moving bits around in production?

A pretty OK Ruby/Cassandra example application

If you’re curious about how to use Cassandra with Ruby, Chronologic is probably an excellent starting point. This is doubly so if you’re interested in building your own indexes or using the lower-level driver API instead of CQL. If you’re interested in the latest and greatest in Cassandra schema design, which you should be, Chronologic won’t help you learn how to use CQL, secondary indexes, or composite columns.

Chronologic is also an acceptable take on building service-oriented, distributed systems with Ruby. It is a good demonstration of a layered, if not particularly OO, architecture. That test suite is fast, and that was nice.

A source of software archaeology

Chronologic started out as a vacation hack that Scott Raymond put together in the winter of 2010. I picked it up and soft launched parts of it in early 2011. As Gowalla went into a drastic product push in the summer of 2011, the development of Chronologic accelerated drastically. A couple other developers started making contributions as Chronologic become a bigger factor in how we built our application and API.

Within the branches and commits, you can probably see design decisions come and go. Dumb bugs discovered and fixed. Sophisticated bugs instrumented, fixes attempted, final solutions triumphantly committed. An ambitious software historian might even glean the pace of development within the Gowalla team and infer the emotional rollercoaster of a big product push through the tone and pace of commits to Chronologic.

An epilogue for Chronologic

I’m a little sad that Chronologic couldn’t become a more general thing useful to a lot of people. I’m a lot sad that, by the time Gowalla was winding down, I was sufficiently burnt out that I wanted little to do with the Chronologic code. All that said, I’m very glad that Scott Raymond encouraged me to work on it and that the team at Gowalla worked with me as I blundered through building my first distributed, high-volume system. It was stressful and challenging, but I’m proud of the work I did and what I learned.