The importance of user interface, illustrated by the Go flag package
Chris's Wiki :: blog/programming/GoFlagUIImportance
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.)
