Boost logo

Boost :

From: Brian McNamara (lorgon_at_[hidden])
Date: 2004-02-18 20:04:05


On Wed, Feb 18, 2004 at 05:04:11PM -0300, Fernando Cacciola wrote:
> Referencial Integrity and Side Effects:
> =========================
...
> 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:
... [ a number of good arguments, elided ]

A number of people have voiced similar complaints, and I am gradually
being worn down. I think one of the reasons I resist it is that I don't
like how boost::lambda has dealt with the issue. Notably, examples like

   // From 5.3.2 of the lambda docs
   // http://www.boost.org/libs/lambda/doc/ar01s05.html#sect:bind_expressions
   bind(&A::set_j, a, _1)(k); // a.j == 0, as a copy of a is modified
   bind(&A::set_j, _1, 1)(a); // a.j == 1

where reference-versus-copy depends upon the precise "timing" of binding
a function argument to a value, and

   // From 4.3 of the lambda docs
   // http://www.boost.org/libs/lambda/doc/ar01s04.html#sect:actual_arguments_to_lambda_functors
   (_1 + _2)(1, 2); // error (!)

which is just unfortunate, and the rules in section 4.4 (about when
reference-versus-copy happens "by default") all just seem a little too
ad-hoc to me. This isn't meant to disparage Jaakko's and Gary's work;
rather my intention is to point out that it's a difficult problem and I
don't think there is a "perfect" solution.

Overall, I just took the easy road with FC++: when everything is
by-value, you completely sidestep the reference-versus-copy issues.
The trade-off, of course, is that I've made it difficult to interoperate
with C++ code that uses reference parameters. In an attempt to banish
meaningless or error-prone code, I have thrown out part of the baby with
the bathwater.

It occurs to me today that there is some middle ground. Specifically,
when you aren't using partial application (that is, "currying" in FC++,
or "bind" in boost::lambda), I think that most of the reference issues
go away. Perhaps there's a way to implement things so that functoids
can have reference parameters, but trying to curry reference parameters
is a compile-time error. I'll have to think about that more deeply.
(There are behaviors I do want to banish because I am convinced they
are always meaningless/in-error, but perhaps there is a way to do this
without banishing reference parameters entirely.)

Furthermore, it also occurs to me that I could define a separate lambda
variable mechanism for FC++ to enable one to write stuff like

   lambda(X,ref(Y))[ ... some lambda expression involving X and Y ... ]

which would enable you to declare which lambda variables are supposed to
be by-reference in an FC++ lambda expression. Hmm. A lot of work
there, but it would be in the right "spirit".
   

In any case, thanks for the comments!

-- 
-Brian McNamara (lorgon_at_[hidden])

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