3 ms·
The more I think about it the more I'm convinced that the insistence of the C++ designers that basic data structures could be defined in the language itself was
by cageface 14y ago
The more I think about it the more I'm convinced that the insistence of the C++ designers that basic data structures could be defined in the language itself was a mistake. Only now in the most cutting edge C++11 compilers can you actually initialize a C++ vector directly like you can now in Obj-C, and the template machinery it takes to make that possible is truly terrible to behold. You still can't properly inspect most of the C++ containers in a debugger.
If instead they'd gone the Obj-C route and made the common data structures part of the language maybe they would have lost a little flexibility but the gain in programmer productivity would have been worth it, IMO. Hacking the Obj-C compiler instead to introduce a little more syntactic sugar results in much, much simpler language to use and understand.
It's a pity Obj-C doesn't really exist outside the Apple ecosystem. It gives you transparent access to native C code but also lets you get almost as dynamic as Smalltalk if you need to without all the baggage of a fullblown VM.
- kelnos 14y agoEr... what? The common ObjC data structures (I assume you're talking about NSArray, NSDictionary, etc.) are not a part of the language. They're a part of Foundation, which is the de-facto standard library of ObjC. Just like the STL is the standard library of C++. Initializing NSArray, NSDictionary, etc. with data in it has nothing to do with ObjC as a language. Those initializers are merely instance methods on the objects themselves. You could easily do that in C++ by writing a varargs function that initializes the object, something like: template<class T> vector<T> *vector_new_with_items(T first_item, ...) { vector<T> *v = new vector<T>(); va_list var_args; T item; v->push_back(first_item); va_start(var_args, first_item); while ((item = va_arg(var_args, T))) v->push_back(item); va_end(var_args); return v; } vector<const char *> *v = vector_new_with_items("one", "two", 0); ... or something like that. That's more or less what Foundation does when you do: NSArray *a = [[NSArray alloc] initWithObjects:@"one", @"two", nil];
- cageface 14y agoInitializing NSArray, NSDictionary, etc. with data in it has nothing to do with ObjC as a language. No longer true as of this release. There's now direct syntactic support in the compiler for them. See: http://weblog.bignerdranch.com/398-objective-c-literals-part-1/ http://weblog.bignerdranch.com/398-objective-c-literals-part... What you couldn't do until C++11 (and even then only in the bleeding edge compilers) is this: std::vector<int> foo = { 1, 2, 3 }; But the gnarly template mechanics it takes to make that work will poke through in error messages and the debugger etc.
- kelnos 14y agoGah, sorry, I didn't get the feeling that that's what you were referring to, though, since it felt like you were implying that ObjC has had this feature for a long time (which it hasn't), and this is something C++ has just gotten (which it has). I'm still not convinced that the standard data structures in ObjC are now really "a part of the language", though the distinction may be meaningless and just me splitting hairs. For instance, take NSString and the @"foo" literal syntax. With GNU gcc (not sure about Apple gcc), you can pass -fconstant-string-class=X to the compiler, and actually replace NSString (well, actually NSConstantString or NXConstantString, depending on if you're using the GNU or NeXT runtime) with another class to represent string literals (I assume it has to have the same memory layout). So I wonder if they're doing something similar with NSArray and NSDictionary. Are those particular classes actually a part of the language, or is just the concept of an array/vector and dict/map a part of the language, and it can be mapped to some arbitrary class with a particular memory layout using new syntactic sugar. Also telling is that you can't initialize globals/static globals with the new array/dict syntax. That implies to me that the compiler isn't actually generating an ObjC class in rodata, but is instead taking the new syntax and transforming it (I hesitate to say "preprocessing") by emitting code for the corresponding initializer method call (or something not entirely unlike that). But I guess in the end it mostly doesn't matter how it works under the hood: as long as the syntax is there, and the compiler can generate useful warnings/errors when you make mistakes, it might as well be a part of the language. (Also, thanks for the info on C++11; I didn't realize the new STL container intializers had made it in. I'm mostly a C++-hater, but good to know nonetheless.)
- agwa 14y agoWhat point are you trying to make that you need the "most cutting edge" compilers? C++11 just came out: of course you need a cutting edge compiler. That won't be true for that much longer though. The template machinery isn't that horrible. Certainly not so significant as to seriously impact programmer productivity. A brace-enclosed initializer list of ints (e.g. { 1, 2, 3, 4 }) is considered a std::initializer_list<int> and this is what a constructor taking such an initializer list looks like: T (std::initializer_list<int> l) { for (int i : l) { // Do something with i (e.g. copy it into the data structure) } } In fact, the C++ designers have created a basic data structure that's defined in the language itself: std::initializer_list. It's just so minimal that it's only used to initialize more complex, user-defined types. That way programmers have the benefit of the "syntactic sugar" even for data types that the C++ designers never could have envisioned.
- apaprocki 14y ago>That won't be true for that much longer though. Oracle Studio (now version 12) has not even started work on C++11 support. It will be a long time before their compiler comes anywhere close to gcc/Clang in support.
- agwa 14y agoAt some point, you have to stop saying "only in cutting edge compilers" and start saying "only in compilers that aren't archaic." Intel's compiler has pretty complete support and Microsoft is working diligently on Visual Studio's C++11 support.
- cageface 14y agoGet back to me when all the standard IDEs can also properly inspect these things in the debugger and give me an error message less than half a page long when I make a tiny syntactic mistake in my code.
- pcwalton 14y agoNot allowing user-defined data structures to have the same syntactic support as the "blessed" ones would have crippled C++ for many domains. Much of the reason C++ is used is that the flexibility of templates allows custom data structures to be maximally performance-tuned for the problem at hand. In Rust, the goal is to use macros for data structure literals, which results in a simpler surface language and the flexibility of C++ without the confusion of templates.
- cageface 14y agoWe're just talking about syntactic sugar here. You could still roll your own string class but without operator or initializer support.