
Hi, the library is so big that I will post the review in chunks. Referencial Integrity and Side Effects: ========================= I never really bought the pure FP argument about no side effects. I'm unconvinced that all programming tasks can be _elegantly_ solved without side effects. In particular, one common task that always seems to bend this intended principle is Outputing. For example, FC++ itself claims to adhere to that principle by promoting that functoids take only non-mutable arguments, but then it finds itself beding that claim when it comes to output: the insertion functoid takes a _mutable_ argument (it has a side effect). IMO, this exception is actually indicating that no-side-effects cannot, and should not be taken to the extreme, because real-life programming cannot get away without mutable states (or takes a mindset so radically different that a "C++" programmer can't leave without it) What I'm trying to say is that I don't like the current design were functoids are prescribed to take only reference to const parameters, for a variety of reasons: 1) As I expressed above I don't think that the restrictive paradigm is actually useful. I like the _guideline_, but I dislike to clutter the design in order to prevent me from doing what I know is actually right. I myself tend to be overprotective, but with Boost.Optional I came to learn to "Trust the Programmer" 2) It turns out that being C++ an "impure" language (from the FP POV), there's actually no way for FC++ to really disable mutable arguments (I can always pass a pointer), so the restriction is there only to communicate a principle rather than to enforce it. However, that fact that FC++ cannot really avoid mutable arguments will in practice result on a mechanical code pattern were each mutable argument will be passed as a pointer (as in the old C days) instead of a reference; but mutable arguments will still exist. Ultimately, badly designed functoids won't really be prevented at all -which is the actual intention of the restricted design-, yet well designed functoids (such as FC++ insertion) will have to pay for an unnatural syntax. 3) FC++ is for C++ programmers, not Haskell programmers. Most of us know how to follow code patterns to avoid the common pitfalls. There was a time were many C++ programs were caught by implicit conversions, aliasing subtelties, life time and memory managment problems, etc... yet we learnt how to deal with that by means of idioms. With FC++, we will eventually discover the idioms that will help us avoid referencial integrity mistakes, so I don't think the library itself should bend the design too much in order to guarantee that. 4) Referencial integrity is anyway tricky enough to break even into a library specially designed to protect it. For example, FC++ uses reference to const objects in order to avoid mutable arguments, all in the name of referencial integrity. However, a "const&" parameter is not totally inmune to such problems the way a _true_ by-value parameter is, because it is after all still a reference, and references alias. Consider the following aparently contrived example: inline point transform ( point const& p ) { return point(2.0* p.x * p.y, 0.5 * p.x * p.y); } void foo() { point p (..whatever...); p = transform(p); } On many C++ implementations, the code above will yield an incorrect result because the return object will actually be constructed in place, producing an actual code equivalent to: p.x = 2.0 * p.x * p.y ; p.y = 0.5 * p.x * p.y ; and you can see how the aliasing resulted in the _argument_ "p.x" being modified inside the function. That example is not too uncommon because any non-linear transformation that use a linear combination of the coordinates can fail because of the aliasing if a const& parameter is used instead of a true by-value argument. ... to be continued... Fernando Cacciola SciSoft