OCD is id, high standards are ego

As programmers, we have a powerful tool that we deploy often: OCD.

While the name connotes a ‘disorder’, certain obsessive behaviors make for very effective programmers. Remember, code that is 99% right is wrong. Crashingly, money-losingly wrong. OCD is made for this profession.

Its strength, however, is also its weakness: it monopolizes our attention. Our ability to dive deep, to focus, to simply not let things go, makes for amazing code and terrible time management.

To me, this makes programmers something you don’t hear often: visceral. We think we do big-brain work; perhaps we do. But our decision of what to prioritize in this moment, and for the next several moments, is often pure id.

Herein lies the confusion: obsession as a proxy for high standards. The difference is that high standards are defined by what we deliver to others; OCD is not.

OCD is entirely about the self. It is an urge to be assuaged.

‘High standards’ (for lack of a better expression) are closer to ethics, or ego. They describe the desire to do the right thing for others, regardless of reward. It is outward where OCD is inward.

The distinction is not binary, to be sure. OCD can be a great tool to be deployed in the service of high standards.

Think of it this way: you’re swinging a hammer. Are you building a bench, or pounding a nail?

A few thoughts on flat

I played with iOS7 today for a bit and discussed the flat design with a couple of Stack’ers. I also read Matt Gemmell’s review, and John Gruber’s take on flatness.

The unifying sentiment seems to be: in the early days of smartphones (say 2007), buttons needed to look like buttons so we know where to click. Since then, we’ve all become familiar with the idea of tapping icons, so perhaps we don’t need to make the affordances quite so obvious.

We can go less literal, in other words. Microsoft called this ‘authentically digital’ in its designs for Win Phone 7.

Users will tap. They don’t need training wheels. We’ve grown up.

Here’s the problem: this all needs explaining. If it needs explaining, perhaps it’s not as intuitive as we think.

Think of it as cognitive overhead. How hard does a user have to work to understand what is clickable or not? If it requires explaining, if it causes hesitation, or if something simply never gets clicked, that’s cognitive overhead, and a user is prevented from succeeding at the task. So perhaps dumb, obvious, unsophisticated buttons aren’t so bad,

But perhaps then iOS7 will obviate that notion too. The notion of a ‘click target’ will be de-emphasized. There are no buttons per se, just objects, like messages and pictures, to be manipulated. No affordances at all, just content. I wonder if that’s possible.

For want of parens in Ruby

Ruby is beautiful in many ways. The opportunities to create tight, readable code are impressive. More than other languages, it affords the opportunity to make code look like what it does.

One syntactic wart, however, is functions. I’ll make an analogy with JavaScript, where

myFunction()

executes myFunction, while

myFunction

is a variable that refers to the function, that can be passed as, say, a callback. In Ruby, parentheses around method arguments are optional, such that

my_thing.do_something one_argument, another_argument

is the same as

my_thing.do_something(one_argument, another_argument)

I can understand this as a cosmetic choice — fewer delimiters, less noise. However, it makes passing functions as arguments unfortunately ugly.

Because there is no distinction between parens and not, simply referring to a function becomes non-trivial. As a result, if one wants to use a functional style, there are hoops.

Now, I’m a noob (Nuby?) so there’s no doubt that I am missing something idiomatic. But I see no fewer than 4 ways in Ruby to pass a function, none of which strike me as pretty. There are blocks, which are good for anonymous functions, such as:

array.map{ |x| x * 2 }

That ain’t bad, but naming and reusing it is less than obvious. (Again, I’m a noob, correct me.) Another approach is a do block:

form_for my_model do |f|
 f.stuff
 f.things
end

There are Proc’s which explicitly say, make this a function:

my_func = Proc.new { |x| x * 2 }

And not least, a lambda keyword:

my_lamb = lambda { |x| x * 2 }

Further, for lack of parens, we can’t simply my_func(5), we have to my_func.call(5).

There are subtle and reasonable differences for these things. A method is not a proc, is not a lambda. And there are idioms for hiding the ugly.

But for a language a beautiful as Ruby, and for a person coming from C# or JavaScript, this is surprisingly baroque.

Fasctimidating

Chris Baus laments that developers are rarely impressed by other developers. It’s often true. But why are developers hard to (outwardly) impress?

For many of us, we base our identity on being special in a particular way: that we can see meaning in things that others find to be gibberish, like, say, computer code or big piles of raw data.

It is a direct tweak to our pleasure center when we have insights that others don’t. Being among normals, with their normal social skills, is often boring or intimidating. Our specialness derives from having something that most people don’t. It’s not surprising that this part of our identity comes to be disproportionate.

When we see good work by another developer, the specialness seems to evaporate. I know I feel it. But this egocentrism — nerd macho, if you will — is a path to joylessness.

Fascination and intimidation are two sides of the same coin: the feeling we get when we look at a piece of work and think, I don’t know how you did that.

We live in a time of highly available fascination/intimidation. Just over the last few months, these things have given my brain a lot to chew on:

  • Go’s type system
  • Rails’ new caching
  • Arbitrary languages between <script> tags

Early in my career, ideas that would change my brain came along every two or three years. Now it’s several per year. Fasctimidating.

Alerts as spam

I went to a talk last night by John Allspaw at Etsy, about alerts and how they are hard to get right.

The short story is, signal-to-noise. Most alerting systems don’t alert, because they are largely false-positive. Due to sheer volume, the recipients of those alerts start inventing their own subjective algorithm as to what deserves attention.

Those human factors are the hard part. Alerts require serious design, and need to be designed with the knowledge that they will be consumed in the context of several other alerting systems.

(By my definition, anything feed-like is an alerting system if you let it be. Error logs, emails, Twitter.)

If an alert does not require action, why was I alerted? It’s literally spam at that point.

It’s understandable why we put up with this. A false positive is low cost, but a false-negative (the alert you needed but didn’t get) is high cost. So we err on the side of more.

See the problem? Bad alerts become non-alerts, but there are some we can’t afford to miss. Conundrum.

Solutions include semi-obvious things like improved UI, where the alert tells you why it alerted and what it expects you to do. Graphs. Sounds. There are interesting ideas.

My idea is that change is what we care about, and what we should work to define. That means calculating not just levels of (say) RAM usage, but velocity, acceleration, and even jerk.

I also think there is an opportunity for ML-type learning within the alert system. Every alert you get, you respond ‘useful’ or ‘not’. Then you classify. Not unlike spam.

discuss on hacker news

What if ‘source code’ were a serialized syntax tree?

At the risk of revealing my lack of a CompSci degree: what if ‘source code’ were replaced by serialized syntax trees?

What if the canonical ‘source’ of an application were not source code, as created by humans, but rather a serialized format of the syntax tree?

The workflow would go like this. You check out the repository. You make changes, and debug, to your satisfaction. Your local changes are still ‘source code’ as we currently understand it.

Then, instead of committing your changes, you feed your source code to the complier/interpreter, which creates a naive syntax tree. This syntax tree preserves the names of your symbols, and does no optimization.

The syntax tree is then decompiled into new source code, and written out. It is logically and semantically the identical to the original text, but style choices you may have made are swept away.

The generated source code is still meant for human consumption. It would need to preserve things like names and comments.

Among the things that are obviated: formatting, obviously, but also storage. The serialization includes rules for how the tree is persisted to disk.

It also means that changesets consist solely of logical & semantic changes. Syntactic and formatting changes are eliminated. IDE’s could facilitate a lot of this. Heck, perhaps this process could happen right inside source control, with the appropriate plugins.

The idea would be to eliminate a class of friction within teams. Fewer subjective decisions.

(This might remind you of whitespace-significant languages, which are good for disposing of formatting arguments among programmers.)

I don’t doubt this would require a fair amount of work so that it functions for humans. My question is, is there a logical dealbreaker in this idea? I suspect it’s been attempted, and would love to hear stories.

discuss on hacker news

Addendum: it didn’t take long for it to be pointed out that this is a thing, and that Lisp is the canonical example. So a further question: what human factors prevent it from becoming common?

Debugging is debugging

I use CoffeeScript here and there. And JavaScript everywhere else.

Depending on the scenario, and this is a matter of taste, CoffeeScript is more elegant, readable, and usable.

When offering this notion, inevitably there is a complaint about “debugging.” CS is generating code, it’s a layer of abstraction, which will lead to frustration, etc.

The question is, compared to what? When JavaScript is not behaving as you wish, what do you do?

You debug it. You log, you hit breakpoints, and most importantly, you build a mental model of how the program is behaving.

Did you learn about truthiness and ‘this’ in JS by logic? Ex post facto maybe. But you debugged your way to that understanding.

CoffeeScript is identical in this regard. It has syntax, and semantics. You write code, see what it does, change it, see what it does. You build a mental model.

CoffeeScript doesn’t make a program easier to debug; it also doesn’t make it harder. Semantics. Behavior. Mental model. Rinse and repeat.

What CoffeeScript does do, in my experience, it make trivial debugging less likely.

Because it’s whitespace-significant, you are unlikely to miss a closing brace. Because it has sensible iterators, you are not going to fuck it up Google it for the 50th time. Because it has ?, you are not going to choose among false, falsy, null, undefined, typeof, instanceof. For the 50th time.

Maybe I’m projecting. I am sure you’re adept with the above issues. You’ve memorized them over time, hammered JS’s behaviors into your head, experimented and built a robust mental model. Which is great!

But there might be a bit of challenge accepted in there, if we’re honest. JS is tedious and idiosyncratic — which is how normals see programming in general. Our ability to reason through that stuff to make something useful is where we derive our reward.

For me, and more so over time, shipping is where I derive my reward. Correctness is rewarding. Code that looks like what it does, is rewarding. So CoffeeScript, for me, is rewarding.

A couple of addenda — in terms of the ‘taste’ thing, I’ve settled on CS on the server (if using node) and plain JS on the client. The difference is that the latter requires a build step while the former does not. coffee app.coffee just works, no hint of JS.

And source maps are a nice tool, so I can imagine that objection to the CS abstraction. Looks like CS got support for that as well, but haven’t yet tried it.