Boost logo

Boost :

From: Dave Abrahams (abrahams_at_[hidden])
Date: 2000-03-12 01:49:41


on 3/10/00 11:46 AM, Gary Powell at Gary.Powell_at_[hidden] wrote:

> What we'd like is comments on code review, design review, usefulness,
> forward direction suggestions, etc. (I'd ask for peer review, but I'm not
> sure I qualify to be a peer after reading all your posts.) (Shameless
> flattery.)

Having looked at the documentation, but not the code, I think this is
beautiful work. If I thought this could have been carried to a conclusion
anywhere nearly this satisfactory I would have pursued it myself months ago.

The things I can find to criticize so far are:

1. It's a little disturbing that you can write 'obvious' things which
compile and 'should' work, but fail only at runtime, e.g.
> for_each(a.begin(),a.end(), cout << ", " << free1); //valid, but wrong
> for_each(a.begin(),a.end(), cout << constant(", ") << free1); //ok

Incidentally, wy doesn't the first one work, if your example "free1+5" does
work? How does the user know when she must write constant()?

2. Naming: It's best to avoid abbreviations, so I don't like 'var'. I think
'argument' would be much more descriptive than 'free'. 'create_ptr' doesn't
create a pointer, it creates an object on the heap (maybe 'new_object'?)

3. Documentation. You've done a remarkably thorough job of documenting this,
especially for an alpha release, but:
 a. I'd like to see you qualify all names with their respective namespaces.
That will give a much better picture of how it would look in real,
best-practices C++ code.
 b. Occasionally, you reveal implementation details which only seem to
confuse the issues, without giving the user additional expressive power:

> int i = 0;
> int j;
> for_each(a.begin(),a.end(), (var(j) = free1, free1 = var(i), var(i) =
> var(j)));
>
> The delayed variables and constants can be defined outside the labmda
> expression as well:
> int i = 0; int j;
> var_type<int>::type vi(var(i)), vj(var(j));
> for_each(a.begin(),a.end(), (vj = free1, free1 = vi, vi = vj));
>
> constant_type<int>::type five(constant(5));
> for_each(a.begin(),a.end(), (vi = five, free1 = vi * constant(6) ));

Why would anyone want to write it that way? It's much harder to read than
the original.

Your control-flow examples could benefit from some well-chosen line breaks:

Control flow examples:
for_each(a.begin(),a.end(),
  if_then(free1 > 5,
          free1 = 5) );

for_each(a.begin(),a.end(),
   if_then_else(free1 > 0,
       free1 = bind(sqr, free1),
       0) );

By the way, this one isn't a very compelling case for if_then_else, is it?

> int i;
> var_type<int>::type vi(var(i));
> for_each(a.begin(),a.end(), (vi = 0,
> while_loop(vi < free1, cout << constant("-"), ++vi ) ) );

Isn't this clearer?

int i;
for_each(a.begin(),a.end(),
(
    var(i) = 0,
    while_loop(var(i) < free1,
        cout << constant("-"),
        ++var(i)
    )
)
);

Incidentally, aren't there some parens missing around the suboordinate
clauses of the while_loop?

for_each(a.begin(),a.end(),
    for_loop(vi = free1, vi > 0, --vi,
        cout << (free1 - vi)
    )
);

int c[10][5];
for_each(c, c+5,
    for_loop(vi = 0, vi < 10, ++vi,
        cout << free1[vi] << ", "
    )
);

4. I would think a lambda version of ?: would be more important than
if_then_else... how 'bout it?


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