The importance of user interface, illustrated by the Go flag package

March 15, 2015

I have previously railed about Go's flag package (and why it's wrong). Recently a small but in practice really important change to how it works landed in the Go tip (what will become Go 1.5) and in the process illustrated how important small UI things are, even in command line programs, and how a modest change can cause a sea change in how I at least feel about them.

One of the quiet irritations with Go's flag package was the usage help information it gives. Here's the usage of my call program, as the current Go 1.4 shows it:

; call -h
Usage of call:
  -B=131072: the buffer size for (network) IO
  -C=0: if non-zero, only listen for this many connections then exit
  -H=false: print received datagrams as hex bytes
  -P=false: just print our known protocols
  -R=false: only receive datagrams, do not try to send stdin
  -T=false: report TLS connection information
  -b="": make the call from this local address
  -l=false: listen for connections instead of make them
  -q=false: be quieter in some situations
  -v=false: be more verbose in some situations

This is accurate but it is both ugly and not particularly like how the rest of Unix does it. All of those '-H=false' switches are flag switches, for example, but you have to know the Go flag package to know that you can use them that way and you don't have to write '-H=true' or the like, just '-H'.

The recent change changes the flag package to a much more Unixy version of this and gives you a simple way to tweak the output a bit to be more useful. Now your program, with a tiny bit of message tweaking, print something like this:

; call -h
Usage of call:
  -B bytes
        the buffer size for (network) IO, in bytes (default 131072)
  -C connections
        if non-zero, only listen for this many connections then exit
  -H    print received datagrams as hex bytes
  -P    just print our known protocols
  -R    only receive datagrams, do not try to send stdin
  -T    report TLS connection information
  -b address
        make the call from this local address
  -l    listen for connections instead of make them
  -q    be quieter in some situations
  -v    be more verbose in some situations

This actually looks like a real Unix program. The help output is not immediately ugly (and does not immediately betray that it was written in Go using the flag package). And I could make it read better for a Unix program with some more message tweaks (all of those flag descriptions should now really start with a capitalized word, for example). And it doesn't require special Go knowledge to decode how to use it; for example, it's now clear that you can use flags like -H as plain option flags without an argument.

It really amazes me how much this little change has improved my opinion of the flag package. I still don't like its differences from Unix getopt, but simply having decent help output makes it much more tolerable (and makes me much happier). Perhaps it's that I no longer feel embarrassed by the help output of my Go programs.

(I know, most people won't get this improvement until Go 1.5 comes out, and then only if they recompile programs with it. But I use the Go git tip so I get it right away, which makes me happy enough. And you'd better believe that I rebuilt everything in sight when I saw this in the change logs.)


Comments on this page:

By Paul Tötterman at 2015-03-15 06:28:45:

I like docopt enough that I stray outside the standard library just to have it.

Written on 15 March 2015.
« Using an automounter doesn't always help with bad NFS servers
Our difficulties with OmniOS upgrades »

Page tools: View Source, View Normal, Add Comment.
Search:
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Sun Mar 15 02:33:57 2015
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.