From: Douglas Gregor (gregod_at_[hidden])
Date: 2001-12-15 12:49:10


On Saturday 15 December 2001 11:53 am, you wrote:
> * MPL tries to emulate the STL to the extent of using iterators into
> abstract sequences, and providing different 'containers' with their
> associated 'traits.' It even has a 'clear' function that returns a new
> empty 'container' of the same type.
>
> In contrast, Lisp builds everything out of pairs; its only data structure
> is the binary tree. A Lisp tree is nearly always a slist; nevertheless,
> sometimes a binary tree is a better fit for the concept being modeled.
>
> Both approaches have pros and cons. I prefer the traditional Lisp way.
> Without a motivating example to the contrary, I'm inclined to think that in
> this area MPL is over-generic.

We implemented an expression simplifier as a metaprogram, and to do it we
used the iterator abstraction to deal with user-defined sets of
simplification rules. For instance, let each simplification rule be some
user-defined class type. Now we might have libraries A and B that have
simplification rules, and user C wants to add more simplification rules. So
the total set of rules is the union of the rules added by A, B, and C, e.g.,

library A:
  struct matrix_matrix_simp {};
  struct matrix_vector_simp {};

library B:
  struct plus_equals_simp {};
  struct square_simp {};

user C:
  struct my_aggressive_simp {};

It's not trivial to build a list at compile-time when you don't know all the
elements in advance, so we settled for this:

// Keeps track of the current index into the list of simplification rules
#define CUR_RULE_INDEX 0

// to add a rule "matrix_matrix_simp":
template<>
struct rule_list<matrix_matrix_simp, CUR_RULE_INDEX> {
  typedef matrix_matrix_simp Rule;
};

// increment the value of CUR_RULE_INDEX with macro-hackery

However, the user can decide to add rules as a group (so matrix_matrix_simp
and matrix_vector_simp would be part of a group called "A_simplifications"),
and the group can have its members specified as a LISP-style list. Therefore,
the actual simplifier component had to deal with both the vector-like
interface and with a LISP-like list interface. We chose to use iterators for
this, and they worked very well.

        Doug