    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: minimalism</title>
        <link>https://members.accu.org/index.php/articles/432</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>




<div class="xar-mod-head"><span class="xar-mod-title">Programming Topics + Overload Journal #45 - Oct 2001</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c65/">Programming</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c78/">Overload</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c159/">45</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/c65-159/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/articles/c65+159/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;minimalism</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 26 October 2001 17:46:07 +01:00 or Fri, 26 October 2001 17:46:07 +01:00</p>
<p><strong>Summary:</strong>&nbsp;</p>
<p><strong>Body:</strong>&nbsp;<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e20" id="d0e20"></a></h2>
</div>
<p>The appeal to &quot;omit needless words&quot; is made by Strunk and White
[<a href="#Strunk-2000">Strunk-2000</a>] concerning written
composition:</p>
<p><span class="emphasis"><em>Vigorous writing is concise. A
sentence should contain no unnecessary words, a paragraph no
unnecessary sentences, for the same reason that a drawing should
have no unnecessary lines and a machine no unnecessary parts. This
requires not that the writer make all sentences short, or avoid all
detail and treat subjects only in outline, but that every word
tell.</em></span></p>
<p>Whilst we may muse about engineering, architectural or craft
metaphors for software development, there is no denying that, in
essence, programming is writing. It is a form of communication that
has two distinct audiences: us and the machine. Although there are
times when it might not feel this way, the machine is easily
pleased, demanding little more than well-formed code. We, however,
are a little more complex and discerning: we demand that our
communication communicate.</p>
<p>As a discipline of composition much of what can be said for
writing natural language is directly applicable to code. There is
no virtue in long-windedness and, by way of balance, there is also
no virtue in code that is unreadably terse. As ever the appeal is
for well-written code. Code that is simple and clear, brief and
direct.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e34" id="d0e34"></a>motivation</h2>
</div>
<p>Minimalism was the subject and title of my ACCU Spring
Conference 2001 keynote [<a href="#Henney2001a">Henney2001a</a>].
In reflection of the topic I dispensed with the usual parade of
slides and detailed notes, making do with just two slides: the
title and the agenda. As with an iceberg, this was just the tip: I
personally had no shortage of material. Whether it was cool or not
is another matter, but the feedback was good and I have had many
requests for my notes or some written form on the topic. This
column is a response, albeit a little delayed, to those
requests.</p>
<p>We encounter creeping featurism in software on a regular enough
basis, most tangibly in our role as application users: many
options, many ways to set them, many ways to lose track of them,
many cunningly hidden defaults - many subtleties. Sometimes we seem
to be slaves to the application-fattening tedium of common but
ineffective idioms.</p>
<p>My laptop, for example, is physically well designed: functional
but appealing, lightweight but robust, minimal but complete. Not a
trace of surplus anywhere, and certainly the best laptop I have had
to date. But there's always something that lets the side down. At
the time of the conference, the laptop was a very recent
acquisition. I had only just set it up; there were still a few
applications and personalisations outstanding when I went to give
it its first public outing.</p>
<p>In performance it has been said that you should never work with
animals and children. You can add computers to that short list.
Part way through the keynote a dialog box cheerfully popped up to
inform me that the batteries were now fully charged. Of course,
being the presenter - with my back turned to the projection - I was
in the privileged position of being the last to know. However, it
did serve to illustrate a point: the subtle difference between a
feature and something that is useful.</p>
<p>What an astonishingly useless notification to have set up by
default. Why, in a logged-on existence already clogged with the
dismissal of a seemingly never-ending procession of dialog boxes,
would I want to be notified with any urgency that the batteries
were full? Am I about to lose data? Has something crashed? Has a
connection to a device or a network been established? Or dropped?
Attention! Attention! Something not very significant has happened!
... OK? (The standard, but intent free, appeal gracing the lone
button on such junk dialog boxes.) If you listen carefully enough,
you can probably hear the late great Douglas Adams chuckling to
himself in the background.</p>
<p>Well, yes, there is always the outside chance that I might find
the information useful, but let's stop and think for a moment about
how outside that chance is. Let's do some design. How is a laptop
with a battery and power-saving features likely to be used?
Typically either at a desk and plugged in or on the road and
unplugged. In the latter case you are going to need to plug it in
again at some point. If you are just going to be sitting at a desk
all day, you really don't care when the battery fills up. Why would
you? You're plugged into the mains concentrating on your work (or
avoiding it, as the case might be): the battery doesn't matter. And
if it does, that's why there's at least one helpful battery
indicator in clear view: on the laptop itself or the (virtual)
desktop. So there's already enough display information for both the
bored casual user and the twitchy concerned power user.</p>
<p>If you're in a hurry and you need to pack up your bags and go,
97% is as good as a 100%. The 100% mark does not have the same
(show-stopping) magic as 0%, where the difference between 3% and 0%
really is important. After you've been hacking away on a train for
a couple of hours and have just turned up to a meeting to give a
presentation - in a room fitted with such modern gimmickry as mains
electricity - it is entirely likely that the battery charge is of
no interest whatsoever. As with over-helpful colleagues, it is more
likely to be an irritating hindrance.</p>
<p>So, &quot;battery full&quot; notification is useful in perhaps a handful
of situations and for a minority of people. As demonstrated through
the exploration of usage scenarios, it will be the exception rather
than the rule. It is certainly not a reasonable default. However,
now that its discovery had been thrust upon me, I was strongly
motivated to disable the default... but first I had to find it.</p>
<p>When I eventually found a moment for a
get-to-know-your-laptop-better session, some rummaging around
revealed that power management options were scattered across many
different small applications, dialog boxes and menus. Some of the
available options seemed to complement one another, some seemed to
contradict one another, and some just wanted to tell you their
copyright details - &quot;OK&quot;? That's the thing about features: if you
don't watch out, they creep. Creep with all the coherence,
supervision and elegance of most things on the planet that creep.
And no, that's not &quot;OK&quot;.</p>
<p>There is a moral to all this, and it's not &quot;don't take new-born
laptops to conferences&quot; (it proves to be quite difficult to test
out a conference situation in the comfort of your own home). Try to
design for use rather than for features. As a guideline this advice
is especially useful when applied to the ordinary and everyday, as
opposed to the novel and groundbreaking. As an aside, there is a
certain irony that the associated accessories web site for what is
a highly usable laptop borders on the unusable. In spite of its
gloss and featurism, plain hand-written HTML with simple CGI usage
- think classic mid-1990s style - would have been a marked
improvement on the song and dance on offer. It has been said that
techies are not necessarily good web designers; let the same be
said of marketing departments.</p>
<p>Features are important, but in the absence of unbounded
development resources, something often has to be sacrificed on the
altar of schedule. With the basic four variables you have to play
with - scope, resources, quality and time - it is more reasonable
to take the knife to features than either developers or quality, or
indeed knocking over the altar. Understanding the model of usage is
what informs this selection. So, given the choice, make specific
common use simpler and more direct at the expense of generalised
unproven utility. Design to be used. One consequence of making
things more usable is that you work to identify and meet the need,
thereby omitting the needless.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e62" id="d0e62"></a>intent</h2>
</div>
<p>My aim is not so much to explore software as executed as to
examine software as written. Tales from the end user are useful and
their lessons can be redirected.</p>
<p>At a previous keynote, I offered a definition of design that I
have found useful [<a href="#Henney1999">Henney1999</a>]: &quot;Design
is a creational and intentional act: conception and construction of
a structure on purpose for a purpose&quot;. In other words not only is
design an act carried out with intent - whether at the keyboard, on
a whiteboard, on the back of an envelope or wherever - it is also
about embodying the structure with intent. These are the two sides
of the word intentional. Programming is about expression, which is
about intent, which is about meaning. Hence clarity and brevity are
significant.</p>
<p>Verbosity often represents a loss of intent, a loss of design
information. I have found that many verbose coding practices are
justified by claiming simplified debugging. It becomes the case
that when programmers are so focused on debugging - what happens
when things go wrong - that their attention is not focused on
getting it right in the first place. It is often said that
prevention is better than cure. No matter how laudable and well
meant the cure is, choosing your practices is a matter of priority
and perspective.</p>
<p>I recently read a list, from a GUI and software-development
specialist, of top skills that should be required of developers:
debugging was listed, but testing was not. I believe that this is
symptomatic of the industry as a whole. Of course, debugging skills
are not useless, but you will learn - and offer - a lot more from
honing your unit-testing skills and understanding design by
contract than you will sitting in a debugger.</p>
<p>I generally regard the use of this tool as a last resort; to
some degree an admission of failure. This is not some kind of macho
posturing (&quot;real programmers don't need debuggers&quot;) but quite the
opposite: there is an anti-intellectual machismo associated with
reliance on stepping through code. Intellectualism is far from
being a virtue in its own right, but, given that programming can be
considered a matter of applied thought, revelling in
anti-intellectualism seems somewhat inappropriate. I have heard the
point of view supported by liberal use and abuse of the word
practical. Let me put it to you this way: bugs are not practical;
preventing them is more practical than finding them. I would
suggest that the debugger exists to solve a smaller class of
problems than it is normally used to solve.</p>
<p>For example, consider the following code fragment:</p>
<pre class="programlisting">
if(enabled == false)
{
  enabled = true;
}
else 
{
  enabled = false; 
}
</pre>
<p>and contrast it with:</p>
<pre class="programlisting">
enabled = !enabled;
</pre>
<p>This is not heavy number crunching code that requires a good
understanding of advanced applied mathematics and numerical
computing techniques. This is simple Boolean algebra, the bread and
butter of programming: the toggling (or even, flipping) intent is
clearer in the second and shorter fragment. It does not have
redundant checks for equality against Boolean constants (for
consistency, surely the result of such a check should in turn be
compared against true, and then that result in turn...), expressing
the idea of toggling directly and succinctly. If programmers cannot
work at this level, why should companies entrust them with anything
as important as development that will affect their assets and
future revenue stream?</p>
<p>As programmers we learn to read through - by which I mean into
more than I mean down - code to uncover the intent. We get so used
to such reading that sometimes we forget to question alternatives,
drawn in by habit to uncover the intent at perhaps a lower level
than is strictly necessary. Consider loops. They are both the
dynamo and motor of almost all programs, whether explicit or
hidden. And oh how we love to write them:</p>
<pre class="programlisting">
std::vector&lt;std::string&gt; items;
... // populate items
for(std::size_t at = 0; at != items.size(); ++at)
  std::cout &lt;&lt; items[at] &lt;&lt; std::endl;
</pre>
<p>In C++, the received orthodoxy is that we should be writing in
terms of iterators and not indices:</p>
<pre class="programlisting">
std::vector&lt;std::string&gt; items;
... // populate items
for(std::vector&lt;std::string&gt;::iterator
    at = items.begin();
    at != items.end(); ++at)
  std::cout &lt;&lt; *at &lt;&lt; std::endl;
</pre>
<p>Hmm, impressively less readable. Certainly orthodox, but the
intent now seems buried deeper beneath the debris of syntax. When
we &quot;express coordinate ideas in similar form&quot; [<a href=
"#Strunk-2000">Strunk-2000</a>] we have the benefit of uniformity
and ease of recognition. For instance, the loop logic remains
unchanged should we change the container type. So why has this
advice seemingly backfired? Pulling in std can make some
difference, but not as much as you might hope. Perhaps it is a
matter of avoiding some obvious repetition, factoring out
commonality in the form of a better type name:</p>
<pre class="programlisting">
typedef std::vector&lt;std::string&gt; strings;
strings items;
... // populate items
for(strings::iterator at = items.begin();
    at != items.end(); ++at)
  std::cout &lt;&lt; items[at] &lt;&lt; std::endl;
</pre>
<p>Now, not only will the loop logic remain unaffected by a change
in container, but the text of the loop will also remain
unchanged:</p>
<pre class="programlisting">
typedef std::set&lt;std::string&gt; strings;
strings items;
... // populate items
for(strings::iterator at = items.begin(); at != items.end(); ++at)
  std::cout &lt;&lt; *at &lt;&lt; std::endl;
</pre>
<p>But we can do better. The main source of repetition is the
source of repetition. Part of the point about C++'s STL and those
nested iterator names is that it is not really our job to spell out
all the types: let the compiler do it for you. Algorithm-based
functions are templated to do just this. They encapsulate loops and
iterator types. With the assistance of function objects, they can
even make other type differences irrelevant. Decoupling through
templates can be applied all the way through, making the code more
general. Starting with the loop body:</p>
<pre class="programlisting">
class print {
public:
  print(std::ostream &amp;out) : out(out) {}
  template&lt;typename argument_type&gt;
  void operator() (const argument_type &amp;to_print) const
  {
    out &lt;&lt; to_print &lt;&lt;  std::endl;
  }
private:
  std::ostream &amp;out;
};
</pre>
<p>and then the loop:</p>
<pre class="programlisting">
std::vector&lt;std::string&gt; items;
... // populate items
std::for_each(items.begin(), items.end(), print(std::cout));
</pre>
<p>Something to notice: thanks to the idioms and names involved,
the intent of the loop is clearer. In fact, the loop housekeeping
is hidden. It's irrelevant; it does not clarify the intent. Of
course, if you don't know STL, then what I have just said may not
appear to hold water. That too is irrelevant. Why? I am writing it
for an audience that can read STL. If the reader is not in that
audience, then they are not in that audience. I am not writing it
for C programmers, Visual Basic programmers, Java programmers or
classic-C++ programmers. Code is not written to be read by
everyman: it needs an audience, and will be better off for having
one in mind.</p>
<p>Something else to notice: the code has been made more general
and, in consequence, there is more up-front code to be written. Is
this a good thing? If the problem had been to generalise stream
output as a function object, it is a fine solution... but it
wasn't. The challenge was to make the intent of the loop clearer.
Scope drift and overgeneralisation are common problems. I happen to
like the style of the print solution [Henney2001b], but that's the
solution to a slightly different problem. Let's try again:</p>
<pre class="programlisting">
std::vector&lt;std::string&gt; items;
... // populate items
typedef std::ostream_iterator&lt;std::string&gt; out;
std::copy(items.begin(), items.end(), out(std::cout, &quot;\n&quot;));
</pre>
<p>Now the code is short, without any up-front extras, and is both
quite specific and sufficiently general. This generality comes free
with the standard abstractions we are using: we can work in terms
of iterators independently of the container (or non-container)
type. We didn't have to write any extra code to achieve this
generalisation, so it is a bonus. The STL is general so that we can
be specific. To the STL literate the code captures the intent
clearly and crisply.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e123" id=
"d0e123"></a>compression</h2>
</div>
<p>This sentence no verb. The previous sentence is an example of
compression. It could not have been made more direct by adding
anything as its structure is intimately bound up in its meaning. In
fact, its structure is its meaning. Taking time out to add things
would only weaken it and miss the point entirely. This is
compression; it is about intent, it is about sufficiency, and it is
about time it was considered a valuable property of code. It is not
a question of style versus substance: the style is the
substance.</p>
<p>So what is the relationship between compression and that other
popular code quality, abstraction? Well, first of all, what is
abstraction? Jim Coplien's response - &quot;Abstraction is evil&quot; - is
perhaps provocative, but it is certainly thought provoking
[<a href="#Milne2001">Milne2001</a>]. Jim Coplien can be found
wielding this soundbite at many a conference. It is a reaction to
the devaluation the word has suffered - abstraction has just become
another word for good, just another hype term - and an invitation
to consider compression in contrast to abstraction. In misuse,
abstraction is often used as a hand wave to avoid necessary detail
and specifics in the consideration of detailed code with a specific
purpose. &quot;Abstraction is evil&quot; is also a soundbite, and all
soundbites are abstractions - a self-referential irony not lost on
Cope.</p>
<p>More conventional answers to the question include &quot;selective
ignorance&quot; and &quot;omission of unnecessary detail&quot; which are, like the
title of this article and Cope's slogan, fine soundbites, but are
framed in the negative and are somewhat lacking in detail. Useful
iconic forms that act as placeholders for deeper understanding, but
on their own are essentially useless for motivating or informing
actual development. Unlike technology, any advice that is
insufficiently advanced is indistinguishable from magic.</p>
<p>Dijkstra offers perhaps the best motivation behind abstraction
[<a href="#Dijkstra1972">Dijkstra1972</a>]:</p>
<p>In this connection it might be worthwhile to point out that the
purpose of abstraction is not to be vague, but to create a new
semantic level in which one can be absolutely precise.</p>
<p>Compare this with Dick Gabriel's description of compression
[<a href="#Gabriel1996">Gabriel1996</a>]:</p>
<p>Compression is the characteristic of a piece of text that the
meaning of any part of it is &quot;larger&quot; than the piece has by itself.
This is accomplished by the context being rich and each part of the
text drawing on that context - each word draws part of its meaning
from its surroundings. A familiar example outside programming is
poetry whose heavily layered meanings can seem dense because of the
multiple images it generates and the way each new image or phrase
draws from several of the others.</p>
<p>Thus compression complements abstraction, but is not necessarily
its opposite. Compression is often a result of appropriate
identification and application of abstractions. In other words,
abstraction considered as an artefact rather than as a process. For
example, STL iterators and iterator ranges are abstractions. As we
have seen, iterators can result in compression... or not. The
difference comes from the &quot;appropriate identification and
application&quot;. Even good abstractions will not automatically bless
your code with clarity and grace. We are back to intent and design:
compression and abstraction are not just about leaving bits out,
they are about expressing yourself with a directness, strength and
clarity that could not necessarily be achieved by other means. They
are about effect, but without drama or melodrama.</p>
<p>Consider an alternative abstraction to iterators for position:
integers as indices. These work fine for array-like containers,
such as std::vector or std::deque, but are quite inappropriate for
linked lists or content-based containers, such as std::list and
std::map. And fully beyond their grasp is the ability to represent
access to non-containers meaningfully, such as iteration over
streams.</p>
<p>As an example, the common task of counting words in a text file
or stream can be reduced to a single statement of executable C++
code [<a href="#Henney2001c">Henney2001c</a>] when built on the
appropriate abstractions:</p>
<pre class="programlisting">
typedef std::istream_iterator&lt;std::string&gt; in;
std::cout &lt;&lt; std::distance(in(std::cin), in());
</pre>
<p>Want to count characters instead?</p>
<pre class="programlisting">
typedef std::istreambuf_iterator&lt;char&gt; in;
std::cout &lt;&lt; std::distance(in(std::cin), in());
</pre>
<p>or lines?</p>
<pre class="programlisting">
typedef std::istreambuf_iterator&lt;char&gt; in;
std::cout &lt;&lt; std::count(in(std::cin), in(), '\n');
</pre>
<p>These fragments are all compact and fluffless, crisp and
essential. STL iterators are not the only appropriate abstraction;
different abstractions give rise to dissimilar constructs that can
be similarly elegant and direct. For example, language support for
closures - such as block objects and lambda functions found in
Smalltalk, Lisp, Ruby, Python and others - gives rise to an
alternative, inverted enumeration method style of iteration
[<a href="#Beck1997">Beck1997</a>]. With anonymous inner classes
this style can be mimicked in Java, although not as cleanly and
effectively as one might wish. In C++ the convenience of this
alternative style is inaccessible, although such inversion of
control flow can still have a role to play.</p>
<p>In all fields of communication we must recognise the importance
of idiom. Compression appeals to common idiom (e.g. the use of the
+ operator to represent addition or concatenation) without
resorting either to private language (e.g. <tt class=
"literal">#define</tt> your own 'keywords' and certain bizarre
applications of operator overloading) or to lowest common
denominator baby talk - don't write code for novices unless you are
writing code for novices.</p>
<p>Operator overloading is a case in point: the fact that some
people misuse it was the motivation for leaving it out of Java; the
fact that it is also used to make code clearer and briefer was
ignored. An example of solving the wrong problem that has
disappointingly left Java with weaker powers of abstraction and
compression for value-based concepts than either its immediate
family, C++ and C#, or indeed scripting languages such as Ruby and
Python. The effect of operator overloading, or the effect of its
absence, is particularly noticeable when working with objects of
numeric, date or currency type. Consider the merits of <tt class=
"literal">a + b - c</tt> versus <tt class=
"literal">a.add(b).subtract(c)</tt>.</p>
<p>I don't really want to focus on language design except where it
significantly affects programmer expressiveness. It is worth
pointing out that children generally understand the use of - for
subtraction before they can spell subtraction. What happens to them
between the years of early schooling and taking up a job as a
programmer is anyone's guess, but experience suggests that their
ability to comprehend arithmetic operators does not fall below
their ability to spell. The utility of operator overloading has
been recognised and perhaps this convenience will be added to Java
in the future [<a href="#Gosling">Gosling</a>].</p>
<p>On inappropriate use of overloading there is also a lot you can
say. To counterbalance the elegance and minimalism of the STL one
has to look no further in C++ than std::auto_ptr. A triumph of
subtlety over expectation, of obscurity over clarity. Ordinary
copying semantics make no sense for <tt class=
"literal">auto_ptr</tt>, so what look like copying operations - the
copy constructor and the copy assignment operator - have been
overloaded misleadingly as move operations. Fundamentally different
semantics dressed in sheep's clothing. For the problem being
solved, this has led to a ridiculously complex and narrow design
that has proven to be a hotspot for specification errors. However,
<tt class="literal">auto_ptr</tt> alone does not build a sufficient
case for rejection of overloading in any of its forms. It instead
emphasises the necessity of respect for idiom: the distinction
between feature and usage, mechanism and method.</p>
<p>Compression is neither an invitation to write WORN code (Write
Once, Read Never) nor an incitement to write tightly coupled goo.
Quite the opposite. The density arises from necessity, sufficiency
and expression. The result is a certain brevity, which &quot;is a
by-product of vigour&quot; [<a href="#Strunk-2000">Strunk-2000</a>], the
result of making it stronger. Brevity is categorically not the same
as obfuscation [<a href="#Henney1995">Henney1995</a>]: it should be
no shorter than is strictly necessary. If it looks like line noise
- and you're familiar with the language - then it's too short.</p>
</div>
<div class="bibliography">
<div class="titlepage">
<h2><a name="d0e207" id="d0e207"></a>references</h2>
</div>
<div class="bibliomixed"><a name="Beck1997" id="Beck1997"></a>
<p class="bibliomixed">[Beck1997] Kent Beck, Smalltalk Best
Practice Patterns, Prentice Hall, 1997.</p>
</div>
<div class="bibliomixed"><a name="Dijkstra1972" id=
"Dijkstra1972"></a>
<p class="bibliomixed">[Dijkstra1972] Edsger W Dijkstra, &quot;The
Humble Programmer&quot;, Communications of the ACM 15(10), October
1972.</p>
</div>
<div class="bibliomixed"><a name="Gabriel1996" id=
"Gabriel1996"></a>
<p class="bibliomixed">[Gabriel1996] Richard P Gabriel, &quot;Patterns
of Software: Tales from the Software Community&quot;, Oxford, 1996.</p>
</div>
<div class="bibliomixed"><a name="Gosling" id="Gosling"></a>
<p class="bibliomixed">[Gosling] James Gosling, &quot;The Evolution of
Numerical Computing in Java&quot;, <span class="bibliomisc"><a href=
"http://java.sun.com/people/jag/FP.html" target=
"_top">http://java.sun.com/people/jag/FP.html</a></span>.</p>
</div>
<div class="bibliomixed"><a name="Henney1995" id="Henney1995"></a>
<p class="bibliomixed">[Henney1995] Kevlin Henney, &quot;The Elements of
Style: Brevity is the Soul of Wit&quot;, CVu 7(2), January 1995, also
available from <span class="bibliomisc"><a href=
"http://www.curbralan.com" target=
"_top">http://www.curbralan.com</a></span>.</p>
</div>
<div class="bibliomixed"><a name="Henney1999" id="Henney1999"></a>
<p class="bibliomixed">[Henney1999] Kevlin Henney, &quot;Design:
Concepts and Practices&quot;, JaCC, September 1999, also available from
<span class="bibliomisc"><a href="http://www.curbralan.com" target=
"_top">http://www.curbralan.com</a></span>.</p>
</div>
<div class="bibliomixed"><a name="Henney2001a" id=
"Henney2001a"></a>
<p class="bibliomixed">[Henney2001a] Kevlin Henney, &quot;Minimalism&quot;,
ACCU Spring Conference 2001, March 2001.</p>
</div>
<div class="bibliomixed"><a name="Henney2001b" id=
"Henney2001b"></a>
<p class="bibliomixed">[Henney2001b] Kevlin Henney, &quot;The
Miseducation of C++&quot;, Application Development Advisor 5(3), April
2001, also available from <span class="bibliomisc"><a href=
"http://www.curbralan.com" target=
"_top">http://www.curbralan.com</a></span>.</p>
</div>
<div class="bibliomixed"><a name="Henney2001c" id=
"Henney2001c"></a>
<p class="bibliomixed">[Henney2001c] Kevlin Henney, &quot;If I Had a
Hammer...&quot;, Application Development Advisor 5(6), July-August 2001,
also available from <span class="bibliomisc"><a href=
"http://www.curbralan.com" target=
"_top">http://www.curbralan.com</a></span>.</p>
</div>
<div class="bibliomixed"><a name="Milne2001" id="Milne2001"></a>
<p class="bibliomixed">[Milne2001] Ewan Milne, &quot;A Touch of
Abstraction&quot;, CVu 13(1), February 2001.</p>
</div>
<div class="bibliomixed"><a name="Strunk-2000" id=
"Strunk-2000"></a>
<p class="bibliomixed">[Strunk-2000] William Strunk Jr and E B
White, The Elements of Style, Fourth edition, 2000.</p>
</div>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
