7 ms·
The lack of destructors and constructors makes Objective C miss an entire galaxy of functionality. That the language authors and programmers don't sorely miss t
by cplusoop 15y ago
The lack of destructors and constructors makes Objective C miss an entire galaxy of functionality. That the language authors and programmers don't sorely miss this feature is a testimony to the limited understanding they have of programming. Lack of destruct-when-I-leave-scope makes real exception semantics impossible, and no "smart" objects that clean up after themselves meaning it's impossible to create abstract data types with such limited features. Programmers who don't miss these features I call "flat programmers" because they are missing an entire dimension in their code. They are forever having to understand the details of their implementations instead of being able to package up functionality from initialization to destruction in abstract terms. Don't bother trying to explain any of this to them. People don't understand what they don't understand. They don't even know what they are missing. But I suppose this is appropriate for Apple programmers who are more concerned about which pixels appear in a drop down list box than the overall job their program is attempting to do.
- SeanLuke 15y agoYour diatribe would have been slightly less absurd had you realized that this article described what Objective-C was like fifteen years ago: indeed the article predates OS X. Things have changed.
- wtallis 15y agoI'm not an expert on Objective-C, but I think this article was bad and dated even in 1997. It doesn't mention reference counting, uses -free instead of -dealloc, and seems to consider ANSI C as relatively new and optional, which means the author was either years out of date, or was arbitrarily ignoring some language features that he considered to be part of the NextStep system instead of the core Objective-C language.
- blago 15y agoThis is like saying that C++ developers are shallow because the language doesn't have closures.
- Figs 15y agoC++11 has closures... :)
- blago 15y agoWelcome to the future. We'll through you a party :-)
- thurn 15y agoOnly for lambdas. There's still no ability to define nested functions as closures, which is arguably more important.
- Figs 15y agoWhat do you mean? You can do this just fine: #include <cstdio> #include <functional> using std::printf; using std::function; function<int ()> f(int x) { function<int ()> g = [x]() { return 2 * x; }; return g; } int main() { auto f1 = f(5); auto f2 = f(6); printf("f1() = %d, f2() = %d\n", f1(), f2()); return 0; } (Which prints `f1() = 10, f2() = 12`) Or did you mean nested functions in the sense of being able to form named closures so that they can call themselves with a headache? It is admittedly more or a pain to do that (if you want to return a closure), but it is still doable, using new and delete: #include <cstdio> #include <functional> using std::printf; using std::function; function<int (int)>* f(int x) { function<int (int)>* g = new function<int (int)>(); *g = [g, x](int n) { if(n <= 0) return 1; else return x + n * (*g)(n-1); }; return g; } int main() { auto f1 = f(0); auto f2 = f(1); printf("f1() = %d, f2() = %d\n", (*f1)(5), (*f2)(5)); delete f1; delete f2; return 0; } Or did you mean something else? Edit: Or, you could do something Y-combinator-ish like this: http://rosettacode.org/wiki/Y_combinator#C.2B.2B http://rosettacode.org/wiki/Y_combinator#C.2B.2B but yeah, it is a bit of a hassle compared to named nested functions.
- sipefree 15y agoAd hominem attacks aside, let me address your points. Firstly, destruction upon leaving scope in Objective-C would add some magic unexpected behavior that doesn't conform to what we expect from standard C stack-based functions. In C++, when an object is normally declared, it exists on the stack, therefore it will disappear when the scope ends. The fact that the destructor is called is nice. In Objective-C, all objects exist solely on the heap. All object-orientation is done at runtime, not at compile time, which leaves it open to be a lot more dynamic and open to fiddling at run time than C++ is. This of course loses a lot of the speed that C++ has, but it's not a big deal in most standard applications. Since creating an object requires specifically allocating it on the heap, having it destruct when the pointer leaves scope is no good. That kind of magic behavior is exactly what would lead to awful bugs in Obj-C. If you want short-lived objects, you call their autoreleased constructors, which means they will self-destruct next time the thread's event loop ticks. It's an extremely common pattern, and happens so often in code that you don't, as you claim, 'have to understand the details of the implementation'. And there's absolutely no need for the derision in your post. Please make your points and defend them like a civilized person.
- vilya 15y ago> Since creating an object requires specifically allocating it on the heap, having it destruct when the pointer leaves scope is no good. It is actually possible for compilers to help out with this in many cases: http://en.wikipedia.org/wiki/Escape_analysis http://en.wikipedia.org/wiki/Escape_analysis
- deleted 15y ago[deleted]
- frou_dh 15y agoDeclaring a specific approach in C++ the difference between "flat programmers" and the enlightened higher-dimensional master-race is ridiculous.
- jronkone 15y agoThis must be the 9001st time I read a post by a C++ programmer that doesn't understand that the problem isn't that other languages don't have RAII. The problem is that C++ doesn't have finally/unwind-protect and thus requires RAII to approximate it.
- makecheck 15y agoI would use RAII even if it weren't required for C++ exception safety. RAII is convenient and it allows you to write code that is smaller and more solid than it would otherwise be (with or without a "finally").
- masklinn 15y ago> RAII is convenient and it allows you to write code that is smaller and more solid than it would otherwise be (with or without a "finally"). You don't know what `unwind-protect` is now do you?
- daemin 15y agoI've looked over what unwind-protect does and to me it doesn't do more than what you can do with a custom RAII like class. The key thing is that it acts like a wrapper around a try/catch/finally-like block (including other forms of flow control), while allowing you to put arbitrary code in the execute and cleanup portions. You would get the same effect with RAII, most of it would be taken care of for you with the right RAII classes, and if you needed custom code then just write a custom RAII like class or be smart about handling it. Although the C++ version wouldn't handle C's longjmp and also goto's. But if you use them you're not exactly coding in C++ then.
- makecheck 15y agoNot just longjmp and goto, but Objective-C's @throw. As much as I'm a fan of RAII in C++, it really is a "pure C++" idiom. If a C++ class is needed in Objective-C code that can @throw an NSException, then the C++ cleanup code really has to be invocable explicitly (because the destructor might not be called). For example: MyCPlusPlusObject object; @try { ... } @finally { object.cleanup(); }