1. 4

Precise abstractions apply to exactly the right types and D allows to check for that.

  1.  

  2. 3

    I’m not super-convinced about the last few iterations being more or less “precise”.

    I think a more important distinction between ‘vague abstractions’ and ‘precise abstractions’ is when we get things like DocumentManager or ServiceInitialiser, which “abstract” by lumping together chunks of possibly-related code, which introduce new vocabulary but which have no precise meaning (e.g. it would be hard to write a non-trivial equation which is obeyed by every ServiceInitialiser). We can’t talk about, say, a DocumentManager in its own terms; we always have to keep in mind what roles and responsibilities happen to have been put in it, and which haven’t.

    In contrast, something like User is more precise: we can confidently say things like emailOf(x) = emailOf(y) implies x = y, or makeAdmin(makeAdmin(x)) = makeAdmin(x), etc. User gives us a meaningful, useful vocabulary in which to discuss and think; rather than merely pointing us to the right place to look in the source code.

    (I tried to pick examples which are intentionally more “business like”, rather than “math like” abstractions like monoids, rings, etc.)

    1. 1

      I think one problem with such business examples is that they are specified less precisely than math like stuff. What exactly is a document or a service? I have also come across systems where email addresses were not unique, because couples had two entries but a shared email address.

      It requires rigorous spec to be precise. Math delivers that. Business does not.