    <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  :: Metaprogramming is Your Friend</title>
        <link>https://members.accu.org/index.php/articles/267</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 + Design of applications and programs + Overload Journal #66 - Apr 2005</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/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c67/">Design</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/c146/">66</a>
<br />

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

                    -                        <a href="https://members.accu.org/index.php/articles/c65+67+146/">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;Metaprogramming is Your Friend</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 12 April 2005 18:05:26 +01:00 or Tue, 12 April 2005 18:05:26 +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="d0e18" id=
"d0e18"></a>Introduction</h2>
</div>
<p>Whenever I create a new C++ file using Emacs a simple elisp
script executes. This script:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>places a standard header at the top of the file,</p>
</li>
<li>
<p>works out what year it is and adjusts the Copyright notice
accordingly,</p>
</li>
<li>
<p>generates suitable #include guards (for header files),</p>
</li>
<li>
<p>inserts placeholders for Doxygen comments.</p>
</li>
</ul>
</div>
<p>In short, the script automates some routine housekeeping for
me.</p>
<p>Nothing extraordinary is going on here. One program (the elisp
script) helps me write another program (the C++ program which needs
the new file).</p>
<p>By contrast, C++ template-metaprogramming is extraordinary. It
inspires cutting-edge C++ software; it fuels articles, newsgroup
postings and books [<a href="#">Abrahams_and_Gurotovy</a>]; and it
may even influence the future direction of the language.</p>
<p>Despite (or maybe because of) this, this article has little more
to say about template-metaprogramming. Instead we shall investigate
some ordinary metaprograms. For example, the elisp script - a
program to write a program - is a metaprogram. There may be other
metaprograms out there which, perhaps, we don't notice. And there
may be other metaprogramming techniques which, perhaps, we should
be aware of.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e47" id="d0e47"></a>What is
Metaprogramming?</h2>
</div>
<p>I like the definition found in the [<a href=
"#Wikipedia">Wikipedia</a>]:</p>
<div class="blockquote">
<blockquote class="blockquote">
<p>&quot;Metaprogramming is the writing of programs that write or
manipulate other programs (or themselves) as their data or that do
part of the work that is otherwise done at runtime during compile
time.&quot;</p>
</blockquote>
</div>
<p>Actually, it's the first half of this definition I like
(everything up to and including &quot;data&quot;). The second seems rather to
weaken the concept by being too specific, and in my opinion its
presence reflects the current interest in C++
template-metaprogramming - but a Wikipedia is bound to relect
what's in fashion!</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e60" id="d0e60"></a>Why
Metaprogram?</h2>
</div>
<p>Having established what metaprogramming is, the obvious
follow-up is &quot;Why?&quot; Writing programs to manipulate ordinary data is
challenging enough for most of us, so writing programs to
manipulate programs must surely be either crazy or too clever by
half.</p>
<p>Rather than attempt to provide a theoretical answer to &quot;Why?&quot; at
this point, let's push the question on the stack and discuss some
practical applications of metaprogramming.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e67" id="d0e67"></a>Editor
Metaprogramming</h2>
</div>
<p>I've already spoken about programming Emacs to create C++ files
in a standard format. We can compare this technique to a couple of
common alternatives:</p>
<div class="orderedlist">
<ol type="1">
<li>
<p>create an empty file then type in the standard header etc.</p>
</li>
<li>
<p>copy an existing file which does something similar to what we
want, then adapt as required.</p>
</li>
</ol>
</div>
<p>The first option is tough on the fingers and few of us would
fail to introduce a typo or two. The second is better but all too
often is executed without due care - maybe because a programmer
prefers to concentrate on what she wants to add rather than on what
she ought to remove - and all too often leads to a new file which
is already slightly broken: perhaps a comment remains which only
applies to the original file, perhaps there's an incorrect date
stamp.</p>
<p>The elisp solution is an improvement. It addresses the concerns
described above and can be tailored to fit our needs most exactly.
All decent editors have a macro language, so the technique is
portable.</p>
<p>Of course, there is a downside. You have to be comfortable
customising your editor. (Or you have to know someone who can do it
for you.)</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e85" id="d0e85"></a>Batch
Editing</h2>
</div>
<p>By &quot;batch editing&quot; I mean the process of creating a program to
edit a collection of source files without user intervention. This
is closely related to editor metaprogramming - indeed, I often
execute simple batch edits without leaving my editor (though the
editor itself may shell-out instructions to tools such as
<tt class="literal">find</tt> and <tt class=
"literal">sed</tt>).</p>
<p>Very early on in my career (we're talking early 80's) I worked
with a programmer who preferred to edit source files in batch mode.
His desk did not have a computer terminal on it. Instead, he would
study printouts, perhaps marking them up in pencil, perhaps using a
rubber to undo these edits, before finally writing - by hand - an
editor batch file to apply his changes. He then visited a computer
terminal to enter and execute this batch file.</p>
<p>Even then, this was an old-fashioned way of working, yet he was
clear about its advantages:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p><span class="bold"><b>Recordable:</b></span> the batch file
provides a perfect record of what it has done.</p>
</li>
<li>
<p><span class="bold"><b>Reversible:</b></span> its effects can
therefore be undone, if required.</p>
</li>
<li>
<p><span class="bold"><b>Reflective:</b></span> by working in this
reflective, careful way, he was less likely to introduce errors.
When system rebuilds can only be run overnight, this becomes
paramount.</p>
</li>
</ul>
</div>
<p>These days, builds are quicker and batch editing is more
immediate. With a few regular expressions and a script one can
alter every file in the system in less time than it takes to check
your email. As an example, in another article [<a href=
"#Guest1">Guest1</a>] I describe the development of a simple Python
script to relocate source files into a new directory structure,
taking care to adjust internal references to <tt class=
"literal">#include</tt>d files.</p>
<p>The benefits of using a script to perform this sort of operation
are a superset of those listed above. In addition, a scripted
solution beats hand hacking since it is:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p><span class="bold"><b>Reliable:</b></span> the script can be
shown to work by unit tests and by system tests on small data sets.
Then it can be left to do its job.</p>
</li>
<li>
<p><span class="bold"><b>Efficient:</b></span> editing dozens -
perhaps hundreds - of files by hand is error prone and tedious. A
script can process megabytes of source in minutes.</p>
</li>
</ul>
</div>
<p>Again, there is a downside. You have to invest time in writing
the script, which may well require a larger investment in learning
a new language. Many of us would regard proficiency in other
languages as an upside but it may be difficult to make that initial
investment under the usual project pressures.</p>
<p>So, once again, it may end up being a team-mate who ends writes
the script for you. Indeed, many software organisations have a
dedicated &quot;Tools Group&quot; which specialises in writing and
customising tools for internal use during the development of core
products. Perhaps this team could equally well be named a
&quot;Metaprogramming Group&quot;?</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e141" id=
"d0e141"></a>Compilation</h2>
</div>
<p>The compiler is the canonical example of a metaprogram: it
translates a program written in one language (such as C) into an
equivalent program written in another language (object code).</p>
<p>Of course, when we invoke a compiler we are not metaprogramming,
we are simply using a metaprogram, but it is important to be aware
of what's going on. We may prefer to program in higher-level
languages but we should remember the compiler's role as our
translator.</p>
<p>We lean on compilers: we rely on them to faithfully convert our
source code into an executable; we expect different compilers to
produce &quot;the same&quot; results on different platforms; and we want them
to do all this while tracking language changes.</p>
<p>In some environments these considerations are taken very
seriously. For safety critical software, a compiler will be tested
systematically to confirm the object code produced from various
test cases is correct. In such places, you cannot simply apply the
latest patch or tweak optimisation flags. You may even prefer to
work in C rather than C++ since C is a smaller language which
translates more directly to object code.</p>
<p>In other environments we train ourselves to get along with our
compilers. We accept limitations, report defects, find workarounds,
upgrade and apply patches. Optimisation settings are fine-tuned. We
prefer tried-and-tested and, above all, supported brands. We
monitor newsgroups and share our experiences.</p>
<p>One last point before leaving compilers alone: C and C++ provide
a hook which allows you to embed assembler code in a source file -
that's what the asm keyword is for. I guess this too is
metaprogramming in a rather back-to-front form. The asm keyword
instructs the compiler to suspend its normal operation and include
your handwritten assembler code directly. Its exact operation is
implementation dependent, and, fortunately, rarely needed.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e156" id=
"d0e156"></a>Scripting</h2>
</div>
<p>The program which follows is a short but non-trivial Python
script. It makes use of a couple of text codecs from the Python
standard library to generate a C++ function. This C++ function
converts a single character from ISO 8859-9 encoding into UTF-8
encoded Unicode.</p>
<pre class="programlisting">
def warnGenerated():
  '''Return a standard 'generated code' warning.'''
  import sys, time
  return (
    '// GENERATED CODE. DO NOT EDIT!\n'
    '// generated by %s, %s' %
    (' '.join(sys.argv),
     time.asctime(time.localtime()))
    )
def functionHeader(codec):
  '''Return the decode function header.'''
  return '''/**
* @brief Convert from %(codec)s into UTF-8
* encoded Unicode
* @param %(codec)s An %(codec)s encoded character
* @param it Reference to an output iterator
* @note If the input character is invalid, the
* Unicode replacement character U+FFFD will be
* returned.
*/
template &lt;typename output_iterator&gt;
void
%(codec)s_to_utf8(
  unsigned char %(codec)s,
  output_iterator &amp; it)''' % { 'codec' : codec }

def convertCh(ch, codec):
  '''Return the 'case' statement converting
  the input character using the supplied codec'''

  from unicodedata import name

  ucs = chr(ch).decode(codec, 'replace')
  utf = ucs.encode('utf-8')
  ucname = name(ucs, 'Control code')
  action = '; '.join(['*it++ = 0x%02x' % ord(c)
                      for c in utf])

  return '''case 0x%02x: // %s
  %s;
  break;''' % (ch, ucname, action)

def codeBlock(prefix, body, indent = ' ' * 4):
  '''Return an indented code block.
  This code block will be formatted:
  prefix
  {
    body
  }'''
  import re
  indent_re = re.compile('^', re.MULTILINE)
  return '''%s
{
%s
}''' % (prefix, indent_re.sub(indent, body))

codec = 'iso8859_9'
print warnGenerated()

print codeBlock(
  functionHeader(codec),
  codeBlock(
    'switch(%s)' % codec,
    # iso8859-* encodings are 8-bit
    '\n'.join([convertCh(ch, codec)
               for ch in range(0x100)]),
    indent = '' # don't indent case: labels
    )
  )
</pre>
<p>By now, it should go without saying that this script is a
metaprogram. Before discussing why I think it's a good use of
metaprogramming, some notes:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>The function <tt class="function">warnGenerated()</tt> is used
to place a standard warning in front of the generated C++ function.
If users of this C++ function edit it by hand, their changes will
be overwritten next time the script is run: hence the warning.</p>
</li>
<li>
<p>The generated code identifies the command which created it (this
information appears as part of the standard warning). This is to
help users regenerate the code, if required.</p>
</li>
<li>
<p>It is very important that the Python script is both maintained
and easy to locate. Ideally, the build system includes a rule to
generate the C++ from the script, though this behaviour may be hard
to integrate into some IDEs: it may prove more pragmatic to run the
script by hand and keep the dependent C++ code checked directly
into the repository.</p>
</li>
<li>
<p>Notice how Python's triple quoted strings allow us to create
neatly formatted C++ code from neatly formatted Python code without
needing lots of escaped characters.</p>
</li>
<li>
<p>It is perhaps ironic that, according to the Python
documentation, some of Python's builtin codecs are implemented in C
(presumably for reasons of speed). I haven't worked out if this
applies to the ones this script uses.</p>
</li>
</ul>
</div>
<p>I like this script since it makes use of the standard Python
library to create code we can use in a C++ program. The hard work
goes on in the calls to <tt class="function">encode()</tt> and
<tt class="function">decode()</tt> and we don't even have to look
at the implementations of these functions, let alone maintain them.
Their speed does not affect the speed of our C++ function and I am
willing to trust their correctness, meaning I don't have to locate
or purchase the ISO 8859 standards.</p>
<p>The second big win is that all the boilerplate code is generated
without effort. If, at some point in the future, we need a fuller
range of ISO 8859 text converters, then we tweak the script so the
final section reads, for example:</p>
<pre class="programlisting">
codecs = ['iso8859_%d' for n in range(1, 10)]

print warnGenerated()

for codec in codecs:
  print codeBlock(
    functionHeader(codec)
    ....
    )
</pre>
<p>and let it run. And should we decide on a different strategy for
handling invalid input data, again, the metaprogram is our
friend.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e198" id="d0e198"></a>Preprocessor
Metaprogramming</h2>
</div>
<p>As mentioned in passing, C++ has a sophisticated templating
facility which (amongst other things) makes metaprogramming
possible without needing to step outside the language.</p>
<p>C++ also inherits the C preprocessor: a rather unsophisticated
facility, but one which is equally ready for use by
metaprogrammers. In fact, careful use of this preprocessor can
allow you to create generic C algorithms and simulate lambda
functions.</p>
<p>For example:</p>
<pre class="programlisting">
#define ALL_ITEMS_IN_LIST(T, first, item, ...) \
do {                                     \
   T * item = first;                     \
   while (item != NULL) {                \
     __VA_ARGS__;                        \
     item = item-&gt;next;                  \
   }                                     \
} while(0)

#define ALL_FISH_IN_SEA(first_fish, ...) \
        ALL_ITEMS_IN_LIST(Fish, first_fish, \
                          fish, __VA_ARGS__)
</pre>
<p>The first macro, <tt class="function">ALL_ITEMS_IN_LIST</tt>,
iterates through items in a linked list and optionally performs
some action on each of them. It requires that list nodes are
connected by a next pointer called <tt class="varname">next</tt>.
The second macro, <tt class="function">ALL_FISH_IN_SEA</tt>,
specialises the first: the node type is set to <tt class=
"type">Fish *</tt> and the list node iterator is called <tt class=
"varname">fish</tt> instead of item.</p>
<p>Here's an example of how we might use it:</p>
<pre class="programlisting">
/**
 * @brief Find Nemos
 * @param fishes Linked list of fish
 * @returns The number of fish in the list called
 * Nemo
 */ 
int findNemo(Fish * fishes) {
  int count;
         
  ALL_FISH_IN_SEA(fishes,
     if(!strcmp(fish-&gt;name, &quot;Nemo&quot;)) {
       printf(&quot;Found one!\n&quot;);
       ++count;
     }
  );
  return count;
}
</pre>
<p>Note how simple it is to plug a code snippet into our generic
looping construct. I have used one of C99's variadic macros to do
this (these are not yet part of standard C++, but some compilers
may support them).</p>
<p>I hesitate to recommend using the preprocessor in this way for
all the usual reasons [<a href="#Sutter">Sutter</a>]. That
said:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>This is a technique I have seen used to good effect in
production code.</p>
</li>
<li>
<p>Techniques like these are used in highly respected C software -
Perl and Zlib, for example. All C/C++ programmers should be
familiar with it.</p>
</li>
<li>
<p>Although the preprocessor can be dangerous, the way it operates
is simple and transparent: use your compiler's -E option (or
equivalent) to see exactly what the preprocessor is up to. (I
sometimes wish I had an equivalent option for working out how the
compiler is handling templated code)</p>
</li>
<li>
<p>Template metaprogramming experts use every preprocessor trick in
the book. See, for example, some of Andrei Alexandrescu's
publications [<a href="#Alexandrescu">Alexandrescu</a>], or the
Boost preprocessor library [<a href="#">Boost</a>]. (This library's
documentation includes an excellent introduction to the
preprocessor's limitations, and techniques for working round
them.)</p>
</li>
</ul>
</div>
<p>One final point: the <tt class="literal">inline</tt> keyword
(intentionally) does not require the compiler to inline code. The
preprocessor can do nothing but!</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e261" id="d0e261"></a>Reflection
and Introspection</h2>
</div>
<p>Take a look at the following Python function which on my machine
lives in <tt class=
"filename">&lt;PYTHONROOT&gt;/Lib/pickle.py</tt></p>
<pre class="programlisting">
def encode_long(x):
  r&quot;&quot;&quot;Encode a long to a two's complement
  little-endian binary string.
  Note that 0L is a special case, returning
  an empty string, to save a byte in the
  LONG1 pickling context.
  &gt;&gt;&gt; encode_long(0L)
  ''
  &gt;&gt;&gt; encode_long(255L)
  '\xff\x00'
  &gt;&gt;&gt; encode_long(32767L)
  '\xff\x7f'
  &gt;&gt;&gt; encode_long(-256L)
  '\x00\xff'
  &gt;&gt;&gt; encode_long(-32768L)
  '\x00\x80'
  &gt;&gt;&gt; encode_long(-128L)
  '\x80'
  &gt;&gt;&gt; encode_long(127L)
  '\x7f'
  &gt;&gt;&gt;
  &quot;&quot;&quot;
  ....
</pre>
<p>The triple quoted string which follows the function declaration
is the function's docstring (and the <tt class="literal">r</tt>
which prefixes the string makes this a raw string, ensuring that
the backslashes which follow are not used as escape characters).
This particular docstring provides a concise description of what
the function does, fleshed out with some examples of the function
in action. These examples exercise special cases and boundary
cases, rather like a unit test might.</p>
<p>Python's <tt class="literal">doctest</tt> module [<a href=
"#Doctest">Doctest</a>] enables a user to test that these examples
work correctly. Here's how to <tt class="literal">doctest
pickle</tt> in an interactive Python session:</p>
<pre class="programlisting">
&gt;&gt;&gt; import pickle
&gt;&gt;&gt; import doctest
&gt;&gt;&gt; doctest.testmod(pickle)
(0, 14)
</pre>
<p>The test result, <tt class="literal">(0, 14)</tt>, indicates 14
tests have run with 0 failures. For more details try <tt class=
"literal">doctest.testmod(pickle, verbose=True)</tt>. In case
anyone is confused, 7 of the tests apply to <tt class=
"literal">encode_long -</tt> and unsurprisingly the other 7 apply
to <tt class="literal">decode_long</tt>.</p>
<p>Incidentally, if <tt class="filename">pickle.py</tt> is executed
(rather than imported as a library) it runs these tests
directly.</p>
<p>The <tt class="literal">doctest</tt> module is a metaprogram -
an example of Python being used to both read and execute Python. To
see how it works I suggest taking a look at its implementation. The
code runs to about 1500 lines of which the majority are
documentation and many of the rest are to do with providing
flexibility for more advanced use.</p>
<p>In essence, note that docstrings are not comments, they are
formal object attributes. Now, Python allows you to list and
categorise objects at runtime, so we can collect up the docstrings
for classes, class methods and for the module itself. Once we have
all these docstrings we can search them to find anything which
looks like the output of an interactive session using Python's text
parsing capabilities. The remaining twist is Python's ability to
dynamically compile and execute source code using the <tt class=
"literal">compile</tt> and <tt class="literal">exec</tt> commands.
So, we can replay the documentation examples, capturing and
checking the output.</p>
<p>The <tt class="literal">doctest</tt> module provides no more
than an introduction to metaprogramming in Python. Given a Python
object it is possible to get at the object's class, which is itself
an object which can be dynamically queried and even modified at
run-time. This isn't the sort of trick which is often required: I
haven't tried it myself so I'd better keep quiet and refer you to
the experts. See for example [<a href="#vanRossum">vanRossum</a>]
or [<a href="#Raymond">Raymond</a>].</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e331" id="d0e331"></a>Domain
Specific Extensions</h2>
</div>
<p>Sometimes the best way to solve a particular family of problems
is to create a domain specific language, which may be implemented
as an extension to a standard language For example (and once again,
quite early in my career), I worked for an organisation - I'll call
it Vector Products - which specialised in solid geometry software.
Vector Products developed and actively maintained a proprietary
extension to C - I'll call it C-cubed - which provided native
support for various domain-specific primitives: vectors (the sort
you find in 3D mathmematics, not <tt class=
"classname">std::vector</tt>), ranges, axis-aligned boxes; and for
domain specific operators to work with these primitives.</p>
<p>I should stress that this C extension pre-dated standard C++.
C++ classes and operator overloading can now handle much of what
C-cubed provided. Nonetheless, Vector Products' investment paid
off: C-cubed allowed programmers to write vector mathematics in a
clean and legible way, thereby freeing them to concentrate on the
real solid geometry problems they needed to solve.</p>
<p>I believe that the earliest incarnations of C++ were essentially
domain-specific extensions to C. For early C++, the domain would be
&quot;Object Oriented Programming&quot;. [<a href="#">Stroustrup</a>]</p>
<p>This again is metaprogramming, though (particularly with respect
to the supplied examples) it is closely related to compilation.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e348" id=
"d0e348"></a>Metaproblems</h2>
</div>
<p>Most of this article puts a positive spin on metaprogramming.
I'm happy enough to leave you with this impression, but I should
also mention some problems.</p>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e353" id=
"d0e353"></a>Trouble-shooting</h3>
</div>
<p>The first problem is to do with trouble-shooting. You have
problems with your program but the problem is actually in the
metaprogram which generated your program. You are one step removed
from fixing it.</p>
<p>I deliberately used the term &quot;trouble-shooting&quot; rather than
debugging. When you think about it, debug builds and debuggers are
there to help you solve these problems by hooking you back from
machine code to source code. It gives the illusion of reversing the
effect of the compiler. If you can provide similar hooks in your
metaprograms, then similarly the fix will be easier to find.</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e360" id="d0e360"></a>Quote Escape
Problems</h3>
</div>
<p>The second problem I refer to as the &quot;quote-escape&quot; problem. It
bit me recently when I converted a regular C++ program into one
which was partially generated by another C++ program. For details,
I refer you to [<a href="#Guest2">Guest2</a>].</p>
<p>For the purposes of this article, look at what happened when I
needed to generate C++ code which produces formatted output.</p>
<p>Here's the code I wanted to generate:</p>
<pre class="programlisting">
context.decodeOut()
  &lt;&lt; context.indent()
  &lt;&lt; field_name &lt;&lt; &quot; &quot;
  &lt;&lt; bitwidth
  &lt;&lt; &quot; = 0x&quot; &lt;&lt; value &lt;&lt; &quot;\n&quot;;
</pre>
<p>Here's the code I developed to do the generating:</p>
<pre class="programlisting">
cpp_file
  &lt;&lt; indent()
  &lt;&lt; &quot;context.decodeOut() &lt;&lt; context.indent() &lt;&lt; &quot;
  &lt;&lt; quote(field_name
        + &quot; &quot;
        + bitwidth 
        + &quot; = 0x&quot;)
  &lt;&lt; &quot; &lt;&lt; context.readFieldValue(&quot;
  &lt;&lt; quote(field_name) + &quot;, &quot;
  &lt;&lt; value 
  &lt;&lt; &quot;) &lt;&lt; \&quot;\\n\&quot;;\n&quot;;
</pre>
<p>It looks even worse without the helper function, quote, which
returns a double-quoted version of the input string.</p>
<p>I was able to defuse this problem with some refactoring but the
self-referential nature of metaprogramming will always make it
susceptible to these issues.</p>
<p>This is also part of the reason why Python is so popular as a
code-generator: as has been shown by some of the preceding
examples, its sophisticated string support can subvert most
quote-escape problems.</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e384" id="d0e384"></a>Build Time
Complexity</h3>
</div>
<p>I have already mentioned the problem of integrating
code-generators into your build system. Some IDEs don't integrate
them very well, and even if they do, we have introduced complexity
into this part of the system. In general we prefer to trade
complexity at build time for safety at run-time but we should
always check that the gains outweigh the costs.</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e389" id="d0e389"></a>Too Much
Code</h3>
</div>
<p>We're nearing the end of our investigation, and I hope the &quot;Why
Metaprogram?&quot; question I posed at the beginning has been addressed.
The [<a href="#Wikipedia">Wikipedia</a>] answers this question
rather more directly:</p>
<div class="blockquote">
<blockquote class="blockquote">
<p>&quot;[Metaprogramming] ... allows programmers to produce a larger
amount of code and get more done in the same amount of time as they
would take to write all the code manually.&quot;</p>
</blockquote>
</div>
<p>It's possible to interpret this wrongly. As we all know, we want
less code, not more (more software can be good, though). The
important point is that the metaprogram is what we develop and
maintain and the metaprogram is small: we shouldn't have to worry
about the generated code's size.</p>
<p>Unfortunately we do have to worry about the generated code, not
least because it has to fit in our system. If we turn a critical
eye on the ISO 8859 conversion functions we discussed earlier we
can see that the generated code size could be halved: values in the
range (<tt class="literal">0, 0x7f</tt>) translate unchanged into
UTF-8, and therefore do not require 128 separate cases. Of course,
the metaprogram could easily be modified to take advantage of this
information, but the point still holds: generated code can be
bloated.</p>
<p>See [<a href="#Brown">Brown</a>] for a more thorough discussion
of this issue.</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e412" id="d0e412"></a>Too Clever</h3>
</div>
<p>Good programmers use metaprograms because they are lazy. I don't
mean lazy in the sense of &quot;can't be bothered to put the right
header in a source file&quot;, I mean lazy in the sense of &quot;why should I
do something a machine could do for me?&quot;.</p>
<p>Being lazy in this way requires a certain amount of cleverness
and &quot;clever&quot; can be a pejorative every bit as much as &quot;lazy&quot; can. A
metaprogram lives at a higher conceptual level than a regular
program. It has to be clever.</p>
<p>Experienced C++ programmers are used to selecting the right
language features for a particular job. Where possible, simple
solutions are preferred: not every class needs to derive from an
interface, and not every function needs template-type parameters.
Similarly, experienced metaprogrammers do not write metaprograms
when they can, they do it when they choose to.</p>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e421" id="d0e421"></a>Concluding
Thoughts</h2>
</div>
<p>This article has touched on metaprogramming in a few of its more
common guises. I hope I have persuaded you that metaprogramming is
both ubiquitous and useful, and that it shouldn't be left to a
select few.</p>
<p>At one time, the aim of computer science seemed to be to come up
with a language whose concepts were pitched at such a high level
that software development would be simple. Simple enough that
people could program machines as easily as they could, say, send a
text message<sup>[<a name="d0e428" href="#ftn.d0e428" id=
"d0e428">1</a>]</sup>. Compilers would be intelligent and forgiving
enough to translate wishes to machine code.</p>
<p>This aim is far from being realised. We do have higher-level
languages but their grammars remain decidedly mechanical. Programs
written in low-level languages still perform the bulk of
processing. Perhaps a more realistic aim is for a framework where
languages and programs are compatible, able to communicate with
humans and amongst themselves, on a single device or across a
network.</p>
<p>In such a framework, metaprogramming is your friend.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e441" id="d0e441"></a>Credits</h2>
</div>
<p>Thanks to Dan Tallis for reviewing an earlier draft of this
article.</p>
</div>
<div class="bibliography">
<div class="titlepage">
<h2><a name="d0e446" id="d0e446"></a>References</h2>
</div>
<div class="bibliomixed"><a name="Abrahams_and_Gurtovoy" id=
"Abrahams_and_Gurtovoy"></a>
<p class="bibliomixed">[Abrahams_and_Gurtovoy] David Abrahams and
Aleksey Gurtovoy, <span class="citetitle"><i class="citetitle">C++
Template Metaprogramming: Concepts, Tools, and Techniques from
Boost and Beyond</i></span></p>
</div>
<div class="bibliomixed"><a name="Alexandrescu" id=
"Alexandrescu"></a>
<p class="bibliomixed">[Alexandrescu] Andrei Alexandrescu's
homepage is at <span class="bibliomisc"><a href=
"http://www.moderncppdesign.com/main.html" target=
"_top">http://www.moderncppdesign.com/main.html</a></span></p>
</div>
<div class="bibliomixed"><a name="Brown" id="Brown"></a>
<p class="bibliomixed">[Brown] Silas S Brown,
&quot;Automatically-Generated Nightmares&quot;, <span class=
"citetitle"><i class="citetitle">CVu</i></span> 16.6</p>
</div>
<div class="bibliomixed"><a name="Doctest" id="Doctest"></a>
<p class="bibliomixed">[Doctest] doctest - Test interactive Python
examples <span class="bibliomisc"><a href=
"http://docs.python.org/lib/module-doctest.html" target=
"_top">http://docs.python.org/lib/module-doctest.html</a></span></p>
</div>
<div class="bibliomixed"><a name="Guest1" id="Guest1"></a>
<p class="bibliomixed">[Guest1] Thomas Guest, &quot;A Python Script to
Relocate Source Trees&quot;, <span class="citetitle"><i class=
"citetitle">CVu</i></span> 16.2 (also available re-titled &quot;From A
to B with Python&quot; at [<span class="bibliomisc"><a href=
"#Homepage">Homepage</a></span>]</p>
</div>
<div class="bibliomixed"><a name="Guest2" id="Guest2"></a>
<p class="bibliomixed">[Guest2] Thomas Guest, A Mini-Project to
Decode a Mini-Language - Part 3, available at [<span class=
"bibliomisc"><a href="#Homepage">Homepage</a></span>]. (The first
two parts of this article appeared in Overloads 63 and 64).</p>
</div>
<div class="bibliomixed"><a name="Homepage" id="Homepage"></a>
<p class="bibliomixed">[Homepage] <span class="bibliomisc"><a href=
"http://homepage.ntlworld.com/thomas.guest" target=
"_top">http://homepage.ntlworld.com/thomas.guest</a></span></p>
</div>
<div class="bibliomixed"><a name="Raymond" id="Raymond"></a>
<p class="bibliomixed">[Raymond] Eric S. Raymond, <span class=
"citetitle"><i class="citetitle">Why Python?</i></span>,
<span class="bibliomisc"><a href=
"http://pythonology.org/success&amp;story=esr" target=
"_top">http://pythonology.org/success&amp;story=esr</a></span></p>
</div>
<div class="bibliomixed"><a name="Stroustrup1" id=
"Stroustrup1"></a>
<p class="bibliomixed">[Stroustrup1] Bjarne Stroustrup,
<span class="citetitle"><i class="citetitle">The Design and
Evolution of C++</i></span></p>
</div>
<div class="bibliomixed"><a name="Stroustrup2" id=
"Stroustrup2"></a>
<p class="bibliomixed">[Stroustrup2] Bjarne Stroustrup,
<span class="citetitle"><i class="citetitle">Did you really say
that?</i></span>, from Bjarne Stroustrup's FAQ <span class=
"bibliomisc"><a href=
"http://www.research.att.com/~bs/%20bs_faq.html#really-say-that"
target="_top">http://www.research.att.com/~bs/
bs_faq.html#really-say-that</a></span></p>
</div>
<div class="bibliomixed"><a name="Sutter" id="Sutter"></a>
<p class="bibliomixed">[Sutter] Herb Sutter, &quot;What can and can't
macros do?&quot;, <span class="citetitle"><i class="citetitle">Guru of
the Week 77</i></span> <span class="bibliomisc"><a href=
"http://www.gotw.ca/gotw/077.htm" target=
"_top">http://www.gotw.ca/gotw/077.htm</a></span></p>
</div>
<div class="bibliomixed"><a name="vanRossum" id="vanRossum"></a>
<p class="bibliomixed">[vanRossum] <span class=
"citetitle"><i class="citetitle">Unifying types and classes in
Python 2.2</i></span> <span class="bibliomisc"><a href=
"http://www.python.org/2.2/descrintro.html" target=
"_top">http://www.python.org/2.2/descrintro.html</a></span></p>
</div>
<div class="bibliomixed"><a name="Wikipedia" id="Wikipedia"></a>
<p class="bibliomixed">[Wikipedia] A free-content encyclopedia that
anyone can edit, <span class="bibliomisc"><a href=
"http://wikipedia.org/" target=
"_top">http://wikipedia.org/</a></span></p>
</div>
</div>
<div class="footnotes"><br>
<hr class="c2" width="100">
<div class="footnote">
<p><sup>[<a name="ftn.d0e428" href="#d0e428" id=
"ftn.d0e428">1</a>]</sup> Though maybe we aren't so far off. To
quote Bjarne Stroustrup [<a href="#Stroustrup2">Stroustrup2</a>]:
&quot;<span class="quote">I have always wished for my computer to be as
easy to use as my telephone; my wish has come true because I can no
longer figure out how to use my telephone.</span>&quot;</p>
</div>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
