
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_l... (_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@cc.gatech.edu)