## Kicking the tires on C++0x

Quote by D H
 Quote by Jocko Homo I am very curious to know how on God's green Earth it could "appear" as if I'm talking about the auto keyword. Can you please explain this to me?
Because it didn't look like you were talking about the for keyword. I still don't understand your objection.
That doesn't answer my question... at all...

Obviously it didn't appear to you that I was talking about for loops. I asked how didn't it appear so? What did I specifically say that made you rule out the possibility that I was talking about for loops and rule in the possibility that I was talking about auto? I'm baffled by this and I'm curious to see the train of logic...

 The entirety of C++ libraries are implemented using the preprocessor? Where did you get that idea? Most of the C++ library is in the form of templates. The preprocessor doesn't know beans about templates.
You had to use the preprocessor to use template libraries in your code with the use of the include directive, which is basically just one giant macro. If you happen to have a text file named "include_me.idontcare" and it contained this:
Code:
for (i = 0; i < whatever; ++i) {
printf("%i\n", i);
}
...and you compiled this code:
Code:
#include <stdio.h>

int main() {
int i;
int whatever = 4;

#include "include_me.idontcare"
}
...the compilation will succeed and the executable will run! ...yet we all recognize that this code is terribly Wrong. Why? Because it's a poorly behaved macro... yet the include directive is the underlying mechanism of C++ library implementation. It's the reason we put up with pre-compiled headers and all that jive...

There's no getting around how integral a part of C++ the preprocessor is so its use can't be shunned that badly. All you can do is ask that people write well behaved macros and good programmers try to do just that...

 Quote by TylerH Is it worth it to keep with conventions if they limit the convenience of using the language? Consistency is impossible in a complete language.
It depends on what you mean by "consistency." The reason I bring up range-based for loops is because, before this change, C++ was consistent in its lack of identifier enforcement. To say that this is impossible is an exaggeration...

Is it worth it? The committee seems to think so. I guess I tend to agree although I suppose I'm somewhat conflicted on the issue...
All I wanted to point out was that it's a little wrong...

 Quote by Jocko Homo It depends on what you mean by "consistency." The reason I bring up range-based for loops is because, before this change, C++ was consistent in its lack of identifier enforcement. To say that this is impossible is an exaggeration...
It's not enforced. You can implement them if you want your class to work with the new for loop, just like you have to implement operator+ if you want your class to work with the + operator.

Impossible is far from an exaggeration. http://en.wikipedia.org/wiki/G%C3%B6...teness_theorem You can either be complete or consistant. C++ chose to strive for completeness, apparently.

Recognitions:
Gold Member
Staff Emeritus
 Quote by TylerH Is it worth it to keep with conventions if they limit the convenience of using the language? Consistency is impossible in a complete language.
 Quote by TylerH Impossible is far from an exaggeration. http://en.wikipedia.org/wiki/G%C3%B6...teness_theorem You can either be complete or consistant.
Don't troll.

Recognitions:
Gold Member
Staff Emeritus
 Quote by Jocko Homo It depends on what you mean by "consistency." The reason I bring up range-based for loops is because, before this change, C++ was consistent in its lack of identifier enforcement.
Also, before c++0x, the language was consistent in its lack of range-based for loops, its lack of lambda expressions, its lack of variadic templates, its requirement for the type of a variable to be explicit at declaration, ....

Seriously, I find this an odd thing to get worked up over. I honestly don't understand how someone can find this important or even merely notable. Doubly so, given the slew of operator foo functions that various language constructs invoke.

It's also not like begin and end came out of nowhere -- this usage had already been established in the standard libraries.

 Quote by TylerH It's not enforced. You can implement them if you want your class to work with the new for loop, just like you have to implement operator+ if you want your class to work with the + operator.
That's really not a fair comparison...

You obviously have to implement something to get your containers to work with range-based for loops but if you want these new loops, you do have to use certain identifier names, which is weird. Before, it didn't matter what aspect of the language you used, you never had to do this. This has changed...

Your operator comparison makes no sense. That's like trying to compare what I'm saying to the fact that, in order to use while loops, you have to test a condition. Yes, you have to do certain things to do certain other things. It's hard to get around that. How is operator overloading the same as enforcing identifier names?

 Impossible is far from an exaggeration. http://en.wikipedia.org/wiki/G%C3%B6...teness_theorem You can either be complete or consistant. C++ chose to strive for completeness, apparently.
In programming, when people refer to "completeness," they're usually referring to Turing completeness. I'm trying to give you the benefit of the doubt (something you didn't appear to give me!) but I'm really not sure how Gödel's incompleteness theorems apply to programming languages. We're not proving theorems with our languages and "consistency" in this context is not referring to the uniformity of function or behavior. Could you please elaborate?

 Quote by Hurkyl Also, before c++0x, the language was consistent in its lack of range-based for loops, its lack of lambda expressions, its lack of variadic templates, its requirement for the type of a variable to be explicit at declaration, .... Seriously, I find this an odd thing to get worked up over. I honestly don't understand how someone can find this important or even merely notable. Doubly so, given the slew of operator foo functions that various language constructs invoke.
I wouldn't characterize my attitude as "worked up." Is that what it looks like to you?

None of the new features you mentioned enforce identifier names on the programmer. Also, operator overloading is not the same thing as identifier enforcement...

 It's also not like begin and end came out of nowhere -- this usage had already been established in the standard libraries.
They're established conventions in the standard libraries but that's all they were. Previously, the C++ compiler knew nothing of the standard libraries. They were completely divorced. You could delete them off your drive or even replace them with something else and still compile code just fine...

For example, I could do a search and replace for all instances of "begin" and "end" and replace them with "beginner" and "endorino" respectively and everything will work exactly the same because C++ never enforced identifier names on the user. Everything was user defined convention...

Now, in C++0x, if you did this and your code used range-based for loops, it would curiously break. That's weird, no?

Mentor
 Quote by Jocko Homo You had to use the preprocessor to use template libraries in your code with the use of the include directive, which is basically just one giant macro.
That is nonsense. #include and #define are very different beasts. Macros are what #define creates, not #include. Conflating #include and #define is trolling. BOOST_FOREACH is a macro, something to be eschewed. Many people / many programming standards deem macros to be so inherently bad that they should never, ever be used, even something as simple as NULL. The vast majority of the C++ and Boost libraries are in the form of templates, which are very useful things.

 Quote by Jocko Homo I wouldn't characterize my attitude as "worked up." Is that what it looks like to you?
That is exactly what it looks like to me. You are trying to create an issue where the only issue is that a number of languages have this exact feature and the current C++ does not. This is an incredibly compact and rather handy capability. Yes, it may be a bit of syntactic sugar, but it is sweet ...

I don't get your issue at all with current C++ not saying anything about the semantics of identifiers. It most certainly does! You raised two examples of where it does exactly that: constructors and destructors. The existing standard has quite a bit to say and semantics of constructors and destructors.

 Quote by Jocko Homo That's really not a fair comparison... You obviously have to implement something to get your containers to work with range-based for loops but if you want these new loops, you do have to use certain identifier names, which is weird. Before, it didn't matter what aspect of the language you used, you never had to do this. This has changed... Your operator comparison makes no sense. That's like trying to compare what I'm saying to the fact that, in order to use while loops, you have to test a condition. Yes, you have to do certain things to do certain other things. It's hard to get around that. How is operator overloading the same as enforcing identifier names?
I've already explained how they're related. They're related in how they are both required for an optional feature. How else could it be done? Is it only the fact that they require a specific symbol name(begin and end) your only complaint? If so, what alternative would you propose, and why is it better?

 Quote by Jocko Homo In programming, when people refer to "completeness," they're usually referring to Turing completeness. I'm trying to give you the benefit of the doubt (something you didn't appear to give me!) but I'm really not sure how Gödel's incompleteness theorems apply to programming languages. We're not proving theorems with our languages and "consistency" in this context is not referring to the uniformity of function or behavior. Could you please elaborate?
It applies in that the language can either be consistent in functionality or complete in functionality. You're arguing for consistency; I'm saying completeness is just as good.

Recognitions:
Gold Member
Staff Emeritus
 Quote by TylerH It applies in that the language can either be consistent in functionality or complete in functionality.
If you're going to continue down this line of thought, you need to make a connection to Gödel's theorem more substantial than using homonyms of some of the words involved.

Recognitions:
Gold Member
Staff Emeritus
 Quote by Jocko Homo For example, I could do a search and replace for all instances of "begin" and "end" and replace them with "beginner" and "endorino" respectively and everything will work exactly the same because C++ never enforced identifier names on the user.
Your experiment wouldn't work if you replaced "operator+" with "plus", or of you replaced "int" with "integer".

 Quote by D H That is nonsense. #include and #define are very different beasts. Macros are what #define creates, not #include. Conflating #include and #define is trolling. BOOST_FOREACH is a macro, something to be eschewed. Many people / many programming standards deem macros to be so inherently bad that they should never, ever be used, even something as simple as NULL. The vast majority of the C++ and Boost libraries are in the form of templates, which are very useful things.
Just when I thought I was walking away from The Twilight Zone...

I mean... "trolling..." really?

I started by reminding us all that the include directive, which is necessary for library implementation, is a preprocessor function and has nothing to do with C++ syntax. Remember this?
 Quote by D H The entirety of C++ libraries are implemented using the preprocessor? Where did you get that idea? Most of the C++ library is in the form of templates. The preprocessor doesn't know beans about templates.
I compared them to macros because... well, they're similar. I don't see how pointing this out is trolling but if you really feel this way then you should press the "report" button beside my post...

The include directive is a macro in the general sense and do behave similarly to C++ macros. I even gave a detailed example of what I meant. You deny my claim but you gave no specific argument other than that they use different keywords and declaring by fiat that they are "different beasts." Can you please be more specific than this?

Hey, you never did explain how you concluded that I must have been referring to the auto keyword instead of for. You're pretty evasive...

 That is exactly what it looks like to me. You are trying to create an issue where the only issue is that a number of languages have this exact feature and the current C++ does not. This is an incredibly compact and rather handy capability. Yes, it may be a bit of syntactic sugar, but it is sweet ...
Now that I think about it, I am enjoying this thread so, I guess in that sense, I'm getting worked up. It's just that Hurkyl made it sound like I was upset or something...

A number of languages don't have the values and priorities of C++. Languages that have range-based for loops, like Python or Ruby, are high level languages. They know nothing about the hardware they run on. C++, on the other hand, is a low level language. It's crazy how much C++ knows about the hardware. It's almost assembler language!

...not that that's the issue here. I just wanted to point out that different languages have different goals and values. Iterating over containers without the verbosity of C for loops (which is really what they are) is nice but how it was done is rather uncharacteristic of C++...

 I don't get your issue at all with current C++ not saying anything about the semantics of identifiers. It most certainly does! You raised two examples of where it does exactly that: constructors and destructors. The existing standard has quite a bit to say and semantics of constructors and destructors.
I'm having trouble understanding what you mean in this paragraph here but I'll take a guess and run it. This is another example of how a little specificity might have been helpful...

C++ does force you to declare your constructor and destructor with the same name as your class but it did not dictate what the name of your class should be: only that they match. This is in stark contrast to range based for loops where you must declare your iterator functions to specifically "begin" and "end." That's it. Otherwise, they're not iterators. Not even "rbegin" and "rend" work...

 Quote by TylerH I've already explained how they're related. They're related in how they are both required for an optional feature. How else could it be done? Is it only the fact that they require a specific symbol name(begin and end) your only complaint? If so, what alternative would you propose, and why is it better?
That's a good question. I think someone earlier in this thread mentioned a range-based for loop implementation made using just the previous C++ specification. I think it was part of the Boost library...

Kidding aside, I'm not sure that BOOST_FOREACH is really any better but I do find it very interesting that such an implementation can be done without altering the language...

I'm really not sure what they could have done if they wanted range-based for loops built into the language... which is probably why they tolerated this change but I'm sure there were some people on the committee who cringed as much as I did...

 It applies in that the language can either be consistent in functionality or complete in functionality. You're arguing for consistency; I'm saying completeness is just as good.
In regards to Gödel's incompleteness theorems, given any axiomatic system sufficiently powerful enough to describe the natural numbers, "consistent" means that there exists no true statement whose negation is also true, and "complete" means that every true statement in said system is provable.

Can you see why I still can't see the application?

Okay, try answering this. If C++ was consistent before C++0x then, by your understanding, it wasn't "complete." Can you give an example of its lack of completeness?

 Quote by Hurkyl Your experiment wouldn't work if you replaced "operator+" with "plus", or of you replaced "int" with "integer".
I'm not sure what point you're trying to make here. If I replaced "{" with "(" then my experiment would also not work but I don't place special meaning to that fact...

"int" is a keyword. It has special meaning which is why you can't simply replace it with an identifier. "operator +" is an operator. It also has special meaning which is why you can't simply replace it with an identifier. If you use range-based for loops then "begin" and "end" also have special meaning... despite they not being keywords... Instead, they're identifiers that you may or may not use... except in range-based for loops where you'd better be using them!

Now, BOOST_FOREACH also requires the existence of a "begin" and "end" method for non-built-in types but, because it's not part of the language, you can change this as a programmer if need be. In fact, it happens to be extensible!

 Sorry, been busy for the last little bit and haven't had time to participate. Jocko, I fail to see a problem in ranged for that warrants this level of discussion. Is it a nice feature that makes code clearer? Yes. Is it likely to cause problems/bugs in code? No. Is there a problem associated with adding support for it in your own lists? No. In short, no problem. It's a fine feature and I'm glad they added it. Wish this whole digression could be moved to it's own thread and not take up space in this one. Sorry, but it seems rather pointless to me.

Recognitions:
Gold Member