Boost logo

Boost :

From: Vesa Karvonen (vesa_karvonen_at_[hidden])
Date: 2004-10-31 21:55:21


Hi,

I have made some optimizations (resulting in an order of magnitude (10x)
improvement in compile-time in some cases on GNU g++) to the library
and implemented a couple of new metafunctions. The latest snapshot can
now be downloaded from the Files Section (both zip and tar.bz for your
convenience):

  http://groups.yahoo.com/group/boost/files/LazyMPL/

Please note that the library is only a proof-of-concept made in about 2
days.
It should be quite possible to provide a more comprehensive library of lazy
metafunctions and provide facilities like the lambda-facility of Boost MPL.
(Also, you shouldn't worry about the upper case naming used in the library.)

Lazy template metaprogramming, as shown by the lazy metaprogramming
library, eliminates the number one stumbling block of template
metaprogramming as described by every introduction or guide to template
metaprogramming (e.g. http://www.boost.org/libs/mpl/doc/#applyif and
Generative Programming section 10.11.1.3 Taking Advantage of Lazy
Behavior (particularly pages 441-443... "You should remember this when
writing static code" ;)).

In lazy template metaprogramming, invocations (::type) are only needed
when a value needs to be explicitly examined (e.g. to extract the head
of a list). Use of the typename-keyword can be practically eliminated and
forwarding (use of inheritance) is the usual way to implement functions.

Explicit invocations can (are) also be used for optimizing lazy
metafunctions,
but optimizations are just optimizations. There is no need to optimize
unless
the metaprogram executes too slowly. It is likely that user metacode can
rely on optimized library primitives for the most part.

Regards,
  Vesa Karvonen

<--- README-file --->

Lazy Metaprogramming Library
============================

                                                       Vesa Karvonen
                                           vesa_karvonen_at_[hidden]

  This is a minimal proof-of-concept library that shows how one can
  implement lazy template metaprograms.

Problem
-------

  Most contemporary template metaprogramming libraries are strict,
  which means that the result of a metafunction call is evaluated
  completely once the metafunction is invoked. Furthermore,
  metafunctions are written so that the arguments they receive are
  assumed to be completely evaluated.

  In addition to strictly evaluated function calls, most strict
  programming languages provide lazy control structures, such as
  `if' and `while', that evaluate their subexpressions only when
  needed.

  In contemporary template metaprogramming libraries, the separation
  between lazy control structures and strict metafunctions is often
  quite fuzzy, which can make programming quite confusing and
  burdensome. Basically, a programmer using a contemporary template
  metaprogramming library has to explicitly annotate the evaluation
  order of the metacode by carefully selecting when to invoke and
  when not to invoke a metafunction. The invocations can not simply
  be completely left out, because strict metafunctions do not accept
  uninvoked arguments.

Solution
--------

  The metaprogramming style used in this library is different.
  Metafunctions and metadata structures (type lists) in this library
  are designed to be lazy. In particular, metafunctions assume that
  the arguments they receive are only delayed promises to compute
  the value of the argument once explicitly invoked. This change of
  style eliminates the need to constantly think about evaluation
  order. Metafunction invocations are only needed when a value
  explicitly needs to be examined. For example, the metafunction
  `HEAD<l>' evaluates to the head of the given list `l'. In order to
  do that, `HEAD' needs to explicitly invoke the parameter `l' to
  expose the list constructor `CONS' for pattern matching. However,
  and most importantly, callers of `HEAD' do not need to invoke the
  actual parameter for `HEAD'. (Explicit invocations can also be
  used for optimization, but it isn't strictly necessary.)

  In theory, the style used in this library could be the ideal way
  to implement template metaprograms, because the C++ standard
  almost requires template instantiations to be cached, which means
  that delayed promises are actually computed only once, saving CPU
  time. In other words, C++ implementations are almost required to
  perform memoization. In practice, however, the representation of
  type information may take a lot of memory and access to the
  instantiation cache isn't necessarily implemented efficiently.
  This can make lazy metaprograms less efficient in terms of time
  and space than their strict counterparts.

Contents of the package
-----------------------

  The `inc/lazy_mpl' directory contains the library implementation.
  Only a minimal core plus a few higher-order functions on lists are
  provided. The list functions imitate the Haskell 98 standard
  prelude functions. The `test' directory contains a couple of ad
  hoc tests demonstrating the lazy programming style and the use of
  lazy lists.

  To get most out of the code, you should take a look at the
  unoptimized implementations of the higher-order list manipulation
  metafunctions `MAP', `FOLD[R|L]', `APPEND', `TAKE', `DROP',
  `ITERATE', `FILTER', and `ZIP_WITH'. As you can hopefully see,
  they are very cleanly expressed. That is how lazy metaprogramming
  would look like to a casual user.

Future work
-----------

  This library is only a proof-of-concept. The intention is to show
  that lazy template metaprogramming is not only possible, but can
  yield both powerful and readable metaprograms.

  One important remaining issue would be to implement a lambda
  mechanism of some sort, which would make the use of higher-order
  metafunctions more convenient.

  Another issue would be to study how to best optimize lazy
  metafunctions. Many of the metafunctions in the library have been
  manually optimized by considering which of their arguments are
  strict (always invoked) and then making the implementation take
  advantage of the strictness by invoking the arguments early. The
  optimizations do not change the way the metafunctions are used
  (assuming the optimizations are correct), but can have a
  significant effect (order of magnitude) on performance. (I have
  not proven that the manually introduced optimizations are
  correct---I wouldn't be surprised if some of the optimization were
  incorrect.) Hopefully a good selection of optimized lazy
  metafunctions can practically eliminate the need for library users
  to manually optimize their code. At any rate, optimizations are
  only needed when a metaprogram evaluates too slowly.

Copyright
---------

  (C) Copyright Vesa Karvonen 2004.

  Distributed under the Boost Software License, Version 1.0.
  (See accompanying file LICENSE.)

_________________________________________________________________
Don't just search. Find. Check out the new MSN Search!
http://search.msn.com/


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk