He’s no Don Draper

Anyone who has seen Don Draper’s iconic Carousel speech knows that nostalgia is a terribly effective agent for emptying consumers’ pockets. Apparently, a reader at Daring Fireball saw a correlation between Don’s work and a recent advertisement for Internet Explorer.

Take a moment to watch both the Carousel speech and the Internet Explorer ad before you move ahead. I’ll wait.

I don’t doubt that the agency responsible for the advertisement had this in mind when they scripted this piece. Unfortunately, the ad falls flat for me.

I grew up in the 90s. I saw a lot of things I remember fondly when I watched the ad; if not with a chuckle at the absurdity of the 90s aesthetic. I did feel connected with the images, but why didn’t I feel connected to the product?

Don Draper tells us we should be nostalgic, but not because we have a strong sentimental attachment to film slides. We feel what we do because of what the Carousel delivers. We insert our slides, dim the lights, and we are taken back to “a place where we know we are loved”.

Sob.

Unfortunately, yeterday’s Internet is gone. Internet Explorer cannot bring it back. Therefore, the product fails to deliver on the promise of the ad. That, I think, is the disconnect, and it’s the reason the ad falls flat for me.

Why be evil.rb?

Caius Durling shared some “hax” with the Ruby community that inspired some discussion over at Hacker News. I commented there, but it seemed like a decent topic for a blog post. One of the examples illustrates a means to define a method-local variable in the argument definition list:

  def output name=((default=true); "caius")
    "name: #{name.inspect} -- default: #{default.inspect}"
  end

  output() # => "name: \"caius\" -- default: true"
  output("fred") # => "name: \"fred\" -- default: nil"

Have a closer look at the method definition line. This code works because of the way parenthesis are handled. Much like in math, when parenthesis are encountered, we evaluate from the inside out. Fire up an IRB session and run this code:

((default=true); "caius")
default.inspect

The return value given for the first line is “caius”, which gets assigned to “name” in our argument list, but you can also see that default is set to “true”. Using the semi-colon statement separator only works because we’ve wrapped the whole thing in parenthesis. That’s why the return value is “caius”. We leverage Ruby’s last-line return value feature.

This might all seem trivial to you if you’ve been programming in Ruby for a while, but therein lies the crux of the discussion. If we only ever wrote code for ourselves, this would be a non-argument. If we expect other people to read and use our code, we should write in a way that is easy to interpret.

Like many viewpoints, the “wrongness” of this example is not black & white; it’s shades of gray. On one hand, you have the “anything that will eval is valid Ruby” view, and on the other you have the “If it’s not immediately obvious to a beginner, you shouldn’t do it” view. There may be better ways to express those two sides of the matter, but that’s the general idea.

The problem with this code (from the latter viewpoint) is that it crams too much program logic in to the argument definitions. This example uses parenthesis to force the evaluation of default=true; "caius" in the argument definition list. That’s only two statements, but it violates some common expectations:

  1. We generally expect argument definitions to be clear and readable, so that method definitions are self documenting (to some degree); this approach clutters the argument definitions.

  2. We expect argument definitions to sometimes assign default values.

  3. We expect program logic to appear in the body of a method, or to be DRY’d up in separate methods.

In this way, the example is not “incorrect” but awkward. To borrow an idea from the literate programming camp, I’d say that just because you can write awkward sentences with valid grammar, it doesn’t mean you should.

Side note: In Caius’ defense, he does say never to use these.