Function calls are a user interface

· ddrake's blog

or, positional function arguments considered harmful

# Here's a picture of my microwave:

The control panel of a microwave, but all the buttons are blank

# Hah! No, that's silly. Here's my microwave.

The same microwave control panel, but with the usual labels on the

# Here's some code.

<LayoutContentPanel id="lcpReport" heightSizeMode={eccw.PanelSizeMode.fill}>
  <div style={{ height: "430px" }}>
    {(this.Data.AppliedCard) ?
      <div id={HTMLElements.AppliedReport}>{this.__loadReport(true, false)}</div> :
      <ZeroStateControl className="_full-height" message={Resources.NoCardApplied}
        ref={(zsc) => {; }} />}

# The __loadReport(true, false) is the same as the blank buttons on the microwave

In both cases, you ask: what does this do?

On the microwave, if I push one of the white oval buttons, what will that do?

In the code, when I load the report, and say true, what will that do?

# A programming environment is a user interface for understanding a program

See Read The Vocabulary from Bret Victor’s essay on Learnable Programming.

It’s a great essay, a sort of a mix of The Design of Everyday Things and Clean Code and its ilk. (You have read both, right? Right?)

# Not just nice-to-have. This causes actual bugs.

I work at a company that makes software for electronic health records. One thing it does is let doctors order medications for patients. We do things like check for duplicates, and so on.

Messing up those checks is not just a computer problem, it could possibly affect a patient's health. So we need to show messages correctly.

I once fixed a bug that came down to a line of code like this:

$$(this).showMessage(ClientResources.MedExactDuplicateMessage, ClientResources.MedDuplicateCaption, MessageBoxButtons.OK, MessageBoxIcon.Error, undefined, $$fcb(this, this.__undoDuplicateMedication, index, column), null, undefined, undefined, undefined, undefined, String.format(ClientResources.MedExactDuplicatePrimaryMessage, exactDuplicate + 1));

The problem came down to the original programmer missing a "true" in the 15th parameter above. Not a joke!

# Which is easier to read? A better user interface?

Forget about bikeshedding about whether boolean parameters are a code smell. Which is better?

this.__loadReport(true, false)


this.__loadReport({showExtraStuff: true, showDefaultThing: false})

# Code is a user interface to the reader

Make it a good user interface! Think about usability principles and your users -- fellow programmers reading the code.

# But good UI isn't always verbose or explicit

The above examples seem to favor naming and labeling everything, of being verbose. Very often, that's good, but keep in mind that not everything needs to be that way. For example, here's another user interface:

The shifter and brake handle of a bicycle

But think about what the user does with the above shifters and brake, the context in which they do it, and their needs when doing that -- compared with what a user -- a programmer -- does when reading code, and their needs when doing that.