Re: PING: Lambda Documentation Problem

[Jaakko Jarvi]
I'm reading the standard back and forth and I do not agree with you.
The Standard is not very well written when it comes to this point, yes. However, I am right, and in the course of this E-mail, you will be convinced that I am right. :->
What do you mean by "inherently mutating sequences"?
Algorithms which always modify the sequences that they are given.
Does std::replace inherently modidfy sequences?
Yes, because its purpose is to write NewValue in every place that OldValue occurs. In contrast, for_each does not necessarily have to modify sequences, if given a functor that inspects its argument and mutates itself. However, the functor can modify the sequence. This caused me some confusion (I thought, as you do, that conforming implementations could implement for_each in such a way as to disallow functors from mutating the values, and hence that for_each was morally bankrupt) until I read something that cleared it up for me. http://www.cuj.com/documents/s=7998/cujcexp1902langer/ "the function object may produce an effect by modifying the input sequence, and it can produce a useful result by mutating itself in the course of its invocations" for_each is special, because all of the other "non-modifying sequence operations" are /really/ non-modifying. If you are still unconvinced, see Library DR 290, where Angelika Langer (coauthor of the above article) complains that there are insufficient restrictions on for_each's functor. Note that she asks that the functor be required to not invalidate iterators or subranges. The DR is still open, but note that the LWG's response so far is "we think this should be a blanket statement", not "what are you talking about, for_each's functor cannot mutate its argument period, much less invalidate iterators". Finally: http://www.research.att.com/~bs/3rd_printing5.html "pg 524 add at the end of the page: "The for_each() algorithm is classified as nonmodifying because it doesn't explicitly modify a sequence. However, if applied to a non-const sequence for_each() may change the elements of the sequence. For an example, see the use of negate() in 11.9." (recent standards resolution)." If your TC++PL3 is 5th printing or higher (or if it's any printing of Special), you can look on page 524, and there it is. Spoken by the Bearded One himself. Stephan T. Lavavej http://nuwen.net

On May 21, 2004, at 11:50 AM, Stephan T. Lavavej wrote:
[Jaakko Jarvi]
I'm reading the standard back and forth and I do not agree with you.
The Standard is not very well written when it comes to this point, yes. However, I am right, and in the course of this E-mail, you will be convinced that I am right. :->
What do you mean by "inherently mutating sequences"?
Algorithms which always modify the sequences that they are given.
Does std::replace inherently modidfy sequences?
Yes, because its purpose is to write NewValue in every place that OldValue occurs.
I'm reading more from the standard, and getting more confused... All other algorithms in the non-modifying category either take a Predicate argument, (which is specified to not call any non-const function through the dereferenced iterator) or perform equality comparisons. for_each is the only one that takes a 'free-form' function object. If side effects are allowed, I don't understand why for_each is classified as a non-modifying sequence. It sure can modify the elements of the sequence. What is (philosophically) different in the way that, say, std::replace, modifies the elements of the sequence? Compare these: std::replace(a.begin(), a.end(), 1, 2); std::for_each(a.begin(), a.end(), boost::lambda::if_then(_1 == 1, _1 = 2)); Regarding Langer's paper, I'm not convinced that the standard can, at the moment, be interpreted in that way. I'm convinced that the description is ambiguous. Maybe for_each should be just moved to mutating sequence operators.
If you are still unconvinced, see Library DR 290, where Angelika Langer (coauthor of the above article) complains that there are insufficient restrictions on for_each's functor. Note that she asks that the functor be required to not invalidate iterators or subranges. The DR is still open, but note that the LWG's response so far is "we think this should be a blanket statement", not "what are you talking about, for_each's functor cannot mutate its argument period, much less invalidate iterators".
I read LWG's response as it says, it should be a blanket statement for all algorithms.
Finally: http://www.research.att.com/~bs/3rd_printing5.html
"pg 524 add at the end of the page: "The for_each() algorithm is classified as nonmodifying because it doesn't explicitly modify a sequence. However, if applied to a non-const sequence for_each() may change the elements of the sequence. For an example, see the use of negate() in 11.9." (recent standards resolution)."
Do you know what Bjarne is referring to with the 'recent standards resolution'? The sgi STL documentation (predecessor of what is currently in the standard) says: UnaryFunction does not apply any non-constant operation through its argument. UnaryFunction refers to the type of the function object to for_each. Here's the relevant link: http://www.sgi.com/tech/stl/for_each.html This must be the initial reason why for_each is in the category of non-modifying sequences. the categorization came from Stepanov et al., but the requirements did not follow unchanged. In sum, I think the footnote is justified (I don't believe I'm putting this much mental energy to justifying a presence of a footnote :), at least until the standard is clarified. A DR would be in place: either explicitly mention that side-effects (of the sort that modify the values in the sequence) are not allowed, or move for_each to mutating algs. Volunteer to raise that and provide wording? Best, Jaakko
participants (2)
-
Jaakko Jarvi
-
Stephan T. Lavavej