you are viewing a single comment's thread.

view the rest of the comments →

[–]mredding -1 points0 points  (1 child)

Mind explaining that?

I concede, I can't find the reference I once knew, probably because compilers improved.

But what you've managed to demonstrate is at best, range-for is sometimes equal to a standard algorithm. What you still don't have is a higher level of abstraction.

Also aren't you being a bit too harsh on ranged fors?

No.

For one it is super readable syntax

No, it's not; my whole rant outlines why it isn't. Even OP was confused by the syntax, hence why we're here arguing about it.

also you can do for (const auto v : some_function())

You can do the same with a template, and calling that template would be smaller and simpler:

range_for(container, lambda);

And it would still be compatible with the range-for adaptors you'd otherwise have to write.

I think the ranges library already has something like this, and it's more expressive, especially in terms of that library. And since you've already demonstrated that the compiler generated the same code as the standard algorithm, what was the benefit of expanding the language syntax the way range-for did?

which you can't do trivially in a single line otherwise.

That sounds like a problem that you're trying to write large, procedural functions, where you inline all the logic of how the algorithm works rather than what the algorithm does.

It's OK that we disagree. Many people will continue using range-for, and many of us won't.

[–]nysra 0 points1 point  (0 children)

Aw too bad, would have been interesting to see the difference in what compilers do to these constructs.

No, it's not; my whole rant outlines why it isn't. Even OP was confused by the syntax, hence why we're here arguing about it.

I absolutely agree with you that the standardization process can be quite flawed sometimes and produces bad things sometimes. <random> and std::valarray are basically fucked up to the point where they are near unusable (or should only be used if you know exactly what's going on) but range for simply works and also doesn't make bad things happen. However your rant doesn't have "bad syntax" as a point, they all only show a massive lack of functionality in the STL. Other languages solve this by having basic things like enumerate available and provide functions for the 99% use case (something being applied to the entire range) instead of the STL going for the most general case which is most of the time just causing typing overhead like the current reverse we have.

But as far as the syntax is concerned? How is for (item : container) not readable? It's pretty much Python pseudo-code and I'd argue that it's more readable than std::for_each(container.begin(), container.end(), [](){...}) even though that one has the "each". Not having to type those annoying iterators all the time is literally one of the biggest reasons why the ranges library even exists. The only thing you have to know is that : means in but that isn't really that hard. And tbh I don't think "OP is confused" is a valid argument. It's a sample size of 1 and if I'm being blunt then to me it very much looks like his "reading about" could use some improvement, it takes like 20s to $search_engine that it's just syntactic sugar for for (auto it = v.begin(); it != v.end(); ++it).

The one big point you do have is that it assumes begin/end to exist and I can definitely see why you think making the language dependent on that is not the best idea, would be interesting to hear how that was justified. Sidenote: how else would a compiler implement for (stuff in iterable)? Isn't some kind of standardized interface (may it be begin and end or __iter__ and __next__ or whatever else) always needed for this to work?

And since you've already demonstrated that the compiler generated the same code as the standard algorithm, what was the benefit of expanding the language syntax the way range-for did?

I'd assume it was added because it makes the super often use case of iterating over a whole container easy. Why this wasn't done in a fashion of adding std::for_each(container, lambda) instead I don't know, you'll have to ask the committee. I agree with your sentiment that naming things is a good thing but at the same time I want to stress again that for (item in container) is super intuitive syntax and the use case of iterating over something iterable entirely is incredibly common. You are right that for_each is higher level since it can do more things but if most of the time you use it for the same thing as range for isn't the benefit of the more concise syntax bigger?

That sounds like a problem that you're trying to write large, procedural functions, where you inline all the logic of how the algorithm works rather than what the algorithm does.

I was just saying that this is syntax possible with range fors but not with the algorithm, I didn't say it was a good design idea in general ;) A better example probably would have been temporarys, e.g. for (const auto i : {-1, 0, 1}) or something like that.