Mon May 9 09:07:50 EDT 2011

Abstraction isn't always the solution

It's hard to quantify this impression.  Some heterogenous examples:

* http://zwizwa.be/darcs/staapl/staapl/pk2/libusb.ss

  Originally, Jakub wrote this code with a naming scheme that's close
  to the C header file.  I changed it to have ``pretty''
  dash-separated scheme-ish names.  I later changed it back so that
  all entities that are direct wrappers of C functions and structures
  are verbatim copies of those names (<function> and struct:<struct>).
  Then only the functionality that is built on top of this hase the
  pretty scheme names.

  This has the advantage that libusb documentation remains valid.  In
  essence, the original (lower level) API remains visible.  In a 2nd
  layer this can then be abstracted out if necessary.

  Morale: Exposing the low-level names seems dirty at first (that's
  why I originally changed Jakub's naming) but seems to make a lot of
  sense from a documentation pov.  If you include the existence of
  libusb as a C library, and the fact that many people that would use
  it from scheme would also use it from C, then the overall complexity
  seems to be decreasing if the horribility of the the C API is leaked
  into the Scheme code.  ( Where it can be abstracted over later if
  necessary, but only app-specific, not wrapper-specific. )

* Exposing data structure internals in interfaces.

  C-specific: When you expose a structure in a header file, you
  forever break binary upgradability of the representation (apart from
  adding members to the end of the struct).

  For core data structures, exposing the internals is almost always a
  bad idea.  For mutable structures which need to respect data
  invariants accessors that explicitly maintain invariants are
  absolutely necessary.

  In some cases though it seems not such a big deal to just use a wide
  open struct and be done with it, instead of a pletora of constructor
  and accessor methods that do not add much value.  However, this
  seems to work only for "constant" structures: those that never
  change shape after they have been constructed.  Such a structure
  behaves as a "configuration file".
  ( In C, one additional reasons to expose internals of a struct is to
    allow temporary structured data alloced as local variables,
    avoiding malloc() issues. )

  Note that when the use of such a public configuration structure is
  limited to one or a handful of API methiods, upgrade is not such an
  issue.  Simply remove one method together with its configuration
  structure, and replace it with another method with another
  structure.  Here the binary linking issues are the same for
  structures and functions.

  ( The general idea seems to be that when structures are read-only,
  the difference with functions starts to look more blurry.  This is
  especially apparent in a pure functional language like Haskell
  [1]. )

[1] entry://../compsci/20110509-093238