iterators must go
Interesting presentation: http://www.boostcon.com/site- media/var/sphene/sphwiki/attachment/2009/05/08/iterators-must-go.pdf
On May 10, 2009, at 9:24 AM, Neal Becker wrote:
Interesting presentation:
http://www.boostcon.com/site- media/var/sphene/sphwiki/attachment/2009/05/08/iterators-must-go.pdf
Does anyone know whether this session (and/or others) have been recorded as well? And if so....any chance it can be downloaded? Thanks. Ciao, Andreas
At 1:18 PM -0400 5/11/09, Andreas Masur wrote:
On May 10, 2009, at 9:24 AM, Neal Becker wrote:
Interesting presentation:
http://www.boostcon.com/site- media/var/sphene/sphwiki/attachment/2009/05/08/iterators-must-go.pdf
Does anyone know whether this session (and/or others) have been recorded as well? And if so....any chance it can be downloaded? Thanks.
Yes, it was recorded. [ I recorded it ] When I get the video converted, etc, we will announce where it is available. -- -- Marshall Marshall Clow Idio Software mailto:marshall@idio.com It is by caffeine alone I set my mind in motion. It is by the beans of Java that thoughts acquire speed, the hands acquire shaking, the shaking becomes a warning. It is by caffeine alone I set my mind in motion.
On May 12, 2009, at 11:08 PM, Marshall Clow wrote:
At 1:18 PM -0400 5/11/09, Andreas Masur wrote:
On May 10, 2009, at 9:24 AM, Neal Becker wrote:
Interesting presentation:
http://www.boostcon.com/site- media/var/sphene/sphwiki/attachment/2009/05/08/iterators-must-go.pdf
Does anyone know whether this session (and/or others) have been recorded as well? And if so....any chance it can be downloaded? Thanks.
Yes, it was recorded. [ I recorded it ] When I get the video converted, etc, we will announce where it is available.
Thanks Marshall....can't wait... ;) Ciao, Andreas
On Sun, May 10, 2009 at 09:24, Neal Becker
Interesting presentation:
http://www.boostcon.com/site- media/var/sphene/sphwiki/attachment/2009/05/08/iterators-must-go.pdf
Very persuasive, but it's careful to touch only the examples that look nice. Note, for example, that every range was a whole container. The three-iterators part was somewhat handwaved-over as well. Take this bit of current code, for example: auto i = find(c.begin(), c.end(), some_pred()); rotate(c.begin(), i, c.end()); How do you do that nicely with ranges, when he has find returning a range? (Since right now, it implicitly actually returns 2 ranges.) And how does insertion work? Do we still need to keep the iterators around for insertion position? I'd love to see the finicky bits worked out, though, since I do like the idea. ~ Scott
Scott McMurray wrote:
On Sun, May 10, 2009 at 09:24, Neal Becker
wrote: Interesting presentation:
http://www.boostcon.com/site- media/var/sphene/sphwiki/attachment/2009/05/08/iterators-must-go.pdf
Very persuasive, but it's careful to touch only the examples that look nice. Note, for example, that every range was a whole container.
The three-iterators part was somewhat handwaved-over as well. Take this bit of current code, for example:
auto i = find(c.begin(), c.end(), some_pred()); rotate(c.begin(), i, c.end());
This is just a guess, but I'd be disappointed if it's not something like this... Range const r1... // r1 = [b,e) Range const r2 = find(r1,pred); // r2 = [i,e) Range const r3 = r1 - r2; // r3 = [b,i) Range const rot = r2 + r3; // rot = [i,e) + [b,i) Louis.
On Wed, May 13, 2009 at 03:28, Louis Lavery
Scott McMurray wrote:
The three-iterators part was somewhat handwaved-over as well. Take this bit of current code, for example:
auto i = find(c.begin(), c.end(), some_pred()); rotate(c.begin(), i, c.end());
This is just a guess, but I'd be disappointed if it's not something like this...
Range const r1... // r1 = [b,e)
Range const r2 = find(r1,pred); // r2 = [i,e)
Range const r3 = r1 - r2; // r3 = [b,i)
Range const rot = r2 + r3; // rot = [i,e) + [b,i)
Well, op+ is the Chain he mentions on slide 38. But how would you implement the op-? I don't see how a - b could possibly be efficient with a list range, for example, since the ranges need not overlap, and one could be a subrange of the other. And the whole file copy example is strange, too, since programs do drastically different things. I sure wouldn't call the program on slide 16 a "file copy" as is implied by the previous slide. Especially since file copy is just int main() { return (std::cout << std::cin.rdbuf()).fail(); } BTW, has anyone ever actually wanted to do the inter-container partial sort of which the presentation is so proud (slide 42)? I'm not sure why I'd have the same data set in precisely two containers. (The Zero-One-Infinity rule comes to mind.)
2009/5/13 Scott McMurray
Very persuasive, but it's careful to touch only the examples that look nice. Note, for example, that every range was a whole container.
The three-iterators part was somewhat handwaved-over as well. Take this bit of current code, for example:
auto i = find(c.begin(), c.end(), some_pred()); rotate(c.begin(), i, c.end());
How do you do that nicely with ranges, when he has find returning a range? (Since right now, it implicitly actually returns 2 ranges.)
He claims that D's stdlib is a superset of the STL. It certainly supports this case: import std.algorithm; import std.stdio; void main() { int[] arr = [4,5,6,7,1,2,3]; bringToFront(arr, find(arr, 1)); assert(arr == [1,2,3,4,5,6,7]); writeln(arr); } http://www.digimars.com/d/2.0/phobos/std_algorithm.html#bringToFront The relevant point is that bringToFront's first range can step over the second range. Daniel
On Fri, May 15, 2009 at 17:15, Daniel James
The relevant point is that bringToFront's first range can step over the second range.
I'm very curious how that's supposed to work. What if, for example, the second range is a superset of the first? Or, since they can be two different types, what happens if I do the same thing as the above, but "retro" one or both of the ranges? It just sounds brittle to me. Or, even simpler, how do I do this? size_t strnlen(char *p, size_t n) { return find(p, p+n, '\0') - p; } That's the size of a range, but I don't know how to get that range. Perhaps it really means that find should be a certain kind of split, not a reducer: size_t strnlen(char *p, size_t n) { auto rr = find( make_range(p, n), '\0' ); return rr.first.size(); } But then what if I want the range before the k-th occurance of something? Then I'd have to somehow concat all the front ranges, which would give me who knows what type. It feels like n iterators gives you n*n different ranges, but that there's no obvious way to get them from n ranges.
2009/5/16 Scott McMurray
I'm very curious how that's supposed to work. What if, for example, the second range is a superset of the first? Or, since they can be two different types, what happens if I do the same thing as the above, but "retro" one or both of the ranges?
From the reference:
Preconditions: Either front and back are disjoint, or back is reachable from front and front is not reachable from back. It's not entirely clear what 'reachable' means - does it just mean that the front is at the same position, or does it mean that the ranges are identical. If you look at the code for bringToFront it uses a method called 'sameHead' (not sameFront for some reason) to detect this case, so I think it's referring to that. Here's a test: import std.algorithm; import std.range; import std.stdio; // Used to prevent bringToFront from using sameHead. struct ArrayRange { int[] x; this(int[] x1) { x = x1; } void popFront() { x.popFront(); } bool empty() { return x.empty(); } ref int front() { return x.front(); } } void main() { int[] arr = [0,1,2,3,4,5,6]; bringToFront(arr, arr[3..5]); writeln(arr); arr = [0,1,2,3,4,5,6]; bringToFront(arr, retro(arr[3..5])); writeln(arr); arr = [0,1,2,3,4,5,6]; bringToFront(arr, ArrayRange(arr[3..5])); writeln(arr); arr = [0,1,2,3,4,5,6]; bringToFront(arr, ArrayRange(arr[3..7])); writeln(arr); } Output: 3 4 0 1 2 5 6 4 3 0 6 5 1 2 3 4 0 5 6 1 2 3 4 5 6 1 2 0 Unsuprisingly, it only gets the first one right. How would the STL deal with cases that don't meet the preconditions?
It just sounds brittle to me.
Compared to what?
Or, even simpler, how do I do this?
size_t strnlen(char *p, size_t n) { return find(p, p+n, '\0') - p; }
That's the size of a range, but I don't know how to get that range.
Since you require a random access iterator: arr.length - find(arr, '\0').length But I suspect your point is more to do with partitioning forward and bidirectional ranges and that does seem a weakness. I suppose that when you've got 'sameHead', you've got a means for two ranges to define a subrange, although it's a little inefficient. There's a trade off here - he could have efficient partitioning if he implemented another range that remembers its original front and can return the range from that up to its current front but I suspect he doesn't want to have multiple range classes and doesn't want to have to store an extra index/pointer in his ranges. In the specific case of arrays, I was surprised to find out that the member functions aren't member functions at all, but just functions that operate on the built in arrays (in D, arr.popFront() is the same as popFront(arr)) - so you can implement this kind of thing quite easily yourself. FWIW, I don't know much about this, I looked at D 2.0 for the first time last night. You might be better of going to the source. Daniel
2009/5/16 Daniel James
Preconditions: Either front and back are disjoint, or back is reachable from front and front is not reachable from back.
It's not entirely clear what 'reachable' means - does it just mean that the front is at the same position, or does it mean that the ranges are identical. If you look at the code for bringToFront it uses a method called 'sameHead' (not sameFront for some reason) to detect this case, so I think it's referring to that. Here's a test:
My recollection for iterators of "a Reachable from b" means that after none or more b++, a == b. (Or whatever the equivalent thing with ranges is.)
Unsuprisingly, it only gets the first one right. How would the STL deal with cases that don't meet the preconditions?
It just sounds brittle to me.
Compared to what?
With iterators, rotate's precondition (m in [b,e]) means that the only way to fail to meet the criteria is to give an iterator of a different type or from outside the range. I find that far more obvious than the two-case range version.
Scott McMurray wrote:
On Fri, May 15, 2009 at 17:15, Daniel James
wrote: The relevant point is that bringToFront's first range can step over the second range.
I'm very curious how that's supposed to work. What if, for example, the second range is a superset of the first? Or, since they can be two different types, what happens if I do the same thing as the above, but "retro" one or both of the ranges? It just sounds brittle to me.
Or, even simpler, how do I do this?
size_t strnlen(char *p, size_t n) { return find(p, p+n, '\0') - p; }
That's the size of a range, but I don't know how to get that range.
You don't. Null-terminated strings, in Alexei's model, are ranges that have a fixed end point, which you can't modify. (There is no representation in the range for it.) You basically have to reinterpret the nts as an array with a known end-point, so you can treat it as a random access range. Now, for an rar, getting that range is easy. Sebastian
2009/5/16 Sebastian Redl
Or, even simpler, how do I do this?
size_t strnlen(char *p, size_t n) { return find(p, p+n, '\0') - p; }
That's the size of a range, but I don't know how to get that range.
You don't. Null-terminated strings, in Alexei's model, are ranges that have a fixed end point, which you can't modify. (There is no representation in the range for it.) You basically have to reinterpret the nts as an array with a known end-point, so you can treat it as a random access range. Now, for an rar, getting that range is easy.
That's why I used strnlen, not plain old strlen. I have a range(p, p+n), which is a full random-access, has_size, etc range. All I want to do is get the range before the first '\0'. The specific interpretation isn't the point. If you prefer, consider the case on tokenizing a string, where I want the range before the first space. It's the same problem.
participants (8)
-
Andreas Masur
-
Daniel James
-
Louis Lavery
-
Marshall Clow
-
Neal Becker
-
Roman Shmelev
-
Scott McMurray
-
Sebastian Redl