LWN.net Logo

Advertisement

Fast storage & processing: iSCSI, NFS, SMB/CIFS, clusters for financial, media, HPC, research, virtualization

Advertise here

How Do I Make This Hard to Misuse?

How Do I Make This Hard to Misuse?

Posted Mar 31, 2008 18:53 UTC (Mon) by ajross (subscriber, #4563)
Parent article: How Do I Make This Hard to Misuse?

I'm surprised to find a huge one missing: Don't provide two ways to do the same thing if one of them is wrong.

Rusty is talking about kernel code, so I guess he might be assuming a higher quality of developer than I am. But misunderstandings of "thick" APIs is probably the source of more "API misuse" (and other bugs and misfeatures) than anything else I'm aware of.

All library code has this disease to some extent or another (Java has it like the plague), and what it means in the real world is that coders with limited understanding of the library as a whole go thumbing through the documentation looking for a gadget that does what they want, and then plug it in, all the while failing to realize that another gadget would have been a much better choice. And since they don't understand the library as a whole, they don't have a prayer of understanding the tradeoffs and misfeatures that result from their choice.

The solutions to this are either (1) make developers understand the design of the libraries they use at a deep level, or (2) write libraries with a minimal but complete feature set, such that developers don't get stuck using the wrong tool for the job. Choice 1 is clearly preferable but very expensive -- there aren't many such developers.

Option 2 seems like a much better choice. The only downsides are that more "boilerplate" code must be written to make up for the lack of "convenience" (ugh) functionality. And, I guess, there will be objections from people who don't understand this "minimal" aesthetic and want to choose the wrong solution from the choices offered by a much larger library.

Personal plug: here's my take on "minimal but complete" functionality as expressed in a small embeddable scripting language: http://plausible.org/nasal.


(Log in to post comments)

How Do I Make This Hard to Misuse?

Posted Mar 31, 2008 20:43 UTC (Mon) by nix (subscriber, #2304) [Link]

Hear, hear, indeed. Forget Java: Win32 is the truly horrible example in 
this area, with dozens of ways to do some fundamental things, all with 
different (often poorly documented) shortcomings.

How Do I Make This Hard to Misuse?

Posted Mar 31, 2008 21:11 UTC (Mon) by i3839 (subscriber, #31386) [Link]

Nasal looks interesting.

> Small! 146k source code.

Is that in lines of code? ;-)

How Do I Make This Hard to Misuse?

Posted Mar 31, 2008 21:24 UTC (Mon) by ajross (subscriber, #4563) [Link]

Goodness no: kilobytes of C code.  And it includes only the core library stuff, and ignores
extension code (currently readline, pcre, sqlite, gtk and cairo) and soft-coded libraries
(there's an XML parser and a few other gadgets).  The current code in CVS is a little bigger
now, at 158k.

Looking at line endings as the LOC metric I count 5507 lines.  Lines with semicolons are an
easy trick to use if you want a measure that ignores comments (i.e. code complexity, not
verbosity), and there are 2620 of those.  I'm sure there are others out there, but I don't
much care.  The point is that it's small. :)

How Do I Make This Hard to Misuse?

Posted Mar 31, 2008 21:31 UTC (Mon) by rgmoore (subscriber, #75) [Link]

what it means in the real world is that coders with limited understanding of the library as a whole go thumbing through the documentation looking for a gadget that does what they want, and then plug it in, all the while failing to realize that another gadget would have been a much better choice. ... The solutions to this are either (1) make developers understand the design of the libraries they use at a deep level, or (2) write libraries with a minimal but complete feature set,

I think that you're missing an important possibility: write really good documentation. Sometimes you really want a dozen gadgets, each of which is different from the others in some small but important way. That's a lot less likely to trip up your users if you:

  1. Group closely related functions in the documentation, so that it's easy for users to compare the different functions and pick the best one,
  2. Cross-reference the functions, so that anyone who reads the documentation for functionA also knows that there are closely related functionA1, functionA2, etc., and/or
  3. Provide a high level overview of the functional category, complete with a discussion of the differences between the functions and when you might want to use one instead of another.

I know that when I'm writing documentation for closely related functions, I try to do some or all of these. It's very helpful when coming back to use something I wrote a few years ago to find notes like "function_A does not guarantee that data will be written in any particular order. If output order is important, use function_B instead."

How Do I Make This Hard to Misuse?

Posted Mar 31, 2008 21:44 UTC (Mon) by ajross (subscriber, #4563) [Link]

I think that you're missing an important possibility: write really good documentation.

I limited my treatment to techniques that have been proven to actually work in practice. :)

Seriously: what you describe would be great. I've just never seen anything like it. At best (or at least the best I've seen), you get documentation like what Sun provides for the JDK: a very clean, readable, hyperlinked guide to a true rats nest of a library that only a tiny elite class of Java gurus actually understand.

The core problem being that great documentation does nothing for those who don't read it, and the sheer size of modern libraries guarantees that users won't read the documentation. You can get around this by finding developers who can read and distill only the core architecture from the effusive documentation, but then you're basically implementing a version of my "option 1" above.

For that matter, good developers tend to get the least relative benefit from all that "convenience code" anyway, and are happy to write the 2-3 lines of boilerplate needed to turn their iterator output into an array, or vice versa, etc... Which means that even given a guarantee that only talented developers will use your library, you're still better off making it minimal than you are adding functionality.

How Do I Make This Hard to Misuse?

Posted Mar 31, 2008 22:12 UTC (Mon) by nix (subscriber, #2304) [Link]

Oh, believe me, even when I describe exactly what functions do in the 
header files, complete with examples... they *still* don't get read, or 
people read the first line and ignore the DO NOT DO THIS in screaming 
flashing red with associated MIDI of a screaming police siren (or the 
closest I can get to that in source code). If I make whateveritis not 
compile if misused, it gets hacked by someone else so that it *does* 
compile when misused, because 'that was easier'. (No it bloody wasn't.)

Given that I work in the financial sector I'm tempted to see if I can 
write something which if misused in an unlikely way transfers the contents 
of the misuser's bank account into mine, and document this as a failure 
mode. I'd be rich within the week! ;}

Copyright © 2008, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds