So the post is about how he had to learn Objective-C quickly because they fired their iPhone developer. If you look under Services on their web page they have this...
"Our mobile development team is highly specialized in creating applications for many popular mobile platforms including the iPhone..."
Does "highly specialized" mean learned it last night...
Hah, oops. I think Sean meant at a previous employer. All of our mobile devs are seriously skilled (f.e., Brendan Lim delivers talks all over the place about mobile dev) and check out our work (Mashable, Oil Reporter, etc.). Er, point is: our mobile devs rock. :)
I just edited the blog post for clarity: Sean was working for another company when he first learned Obj-C. I don't think he specified that in his post initially, because it probably seemed so obvious (to him) that something like that would never happen at Intridea. :)
I'd actually go a step further and argue Objective-C is actually closer to Ruby than to C. So close, in fact, that MacRuby implements Ruby's object system using Objective-C's runtime.
Syntax and naming conventions are another matter...
This makes me feel old -- when I was learning programming/CS, memory management and storage classes were part of basic training. Now we've got a generation of programmers who've never had to worry about these things.
Just because it's good to be aware of how memory management works doesn't mean you should be dragged through tedious manual tasks every time you code.
Assembler was probably part of many peoples basic training as well. Do you want to spend your days juggling everything in 4 general purpose registers because it makes you feel like a better programmer? Is that the best use of your time?
I don't understood why people think automatic deallocation = garbage collection = slow language. You can have reference counting without garbage collection. It's pretty obvious to a compiler when a variable has gone out of scope and can be dereferenced (and deallocated immediately at 0).
Using a language like obj-c where you have to do memory management manually just seems so archaic after using modern languages. Plus there is strange property duplication syntax, split header/code files, a GUI editor that doesn't easily wire events to code, named parameters, c/smalltalk calls mixed together, etc.. it's just a mess.
In my brief stint using it the whole time I kept thinking this would be so much simpler if I could do it the XYZ language way. Obj-C is a language that you have to try really hard to like. If you have to convince yourself then maybe it's not that good.
First, even the "manual" version of garbage collection (the retain/release) pattern is pretty trivial with Objective-C (more so with the new property syntax). Once you know the rules it was pretty automatic and really didn't cause that many problems. It was more a problem with the "checklist" language comparisons.
The "property duplication syntax" (I assume you mean the declare versus synthesis) is there for flexibility and so you can do some pretty good customization to make your classes work better.
For OS X, Objective-C now has garbage collection that works pretty well.
>Using a language like obj-c where you have to do memory management manually just seems so archaic after using modern languages.
That's not an Objective C thing, the language has garbage collection, just it isn't enabled for the mobile platform, for the reason it eats power and memory.
My point was that it is possible to have deterministic deallocation without garbage collection. This can be done at compile time. So I don't buy the "eats power" excuse for needing manual memory management.
I don't understood why people think automatic deallocation = garbage collection = slow language. You can have reference counting without garbage collection. It's pretty obvious to a compiler when a variable has gone out of scope and can be dereferenced (and deallocated immediately at 0).
`[object performSelector:sel];` // where `sel` may be - retain
How should the compiler optimize that?
Plus there is strange property duplication syntax
You don't have to bother with that anymore. The only reason you ever did with iPhone dev is because the iPhone Simulator didn't support the modern runtime. If you only tested on the device, you never had to bother with it.
Objective-C doesn't have named parameters. It intertwines the method names with the arguments that it takes.
Instead of `void doStuff(foo, bar, baz);`, its `- (void) doStuffFoo:(id) foo bar:(id) bar baz:(id) baz;` (which can also be written (and compiled) as: `- (void) :foo:bar:baz;` if you wanted).
Intended audience of article is Rubyists and other users of dynamic languages who are unfamiliar with having to code in a C style. Probably small subset of HN readers.
I would recommend use of Objective-C without Apple frameworks to anyone who must build robust modular systems while retaining C compatibility or performance characteristics. I use it myself in a game engine.
He is at the first stage of Cocoa development. Learning a new language is fun, and you can create some really cool stuff with the Cocoa frameworks. But once that wears off you are left with Objective-C, a vestigial language that isn't suited for a majority of application development.
Here are some reasons I think Objective-C needs to be retired:
- Header Files: These are archaic and require you to repeat code unnecessarily. Compiler's shouldn't require humans to do something that computers are better at.
- No Automatic Garbage Collection: In ObjC 2.0 we have this, but not on the iPhone. Unless you are making a high performance game, there is no reason the phone can't handle Automatic GC.
- No NSDictionary/NSArray literals: [[NSDictionary alloc] initWithObjectsAndKeys:@"value", @"key", @"value2", @"key2", nil]; // Enough said
- No regex: You kind of get regex's in 3.2+, but they are very limited and require around 3-4 lines of setup to get anything done.
- Xcode: You are pretty much required to use Xcode and I don't like Xcode. Even if you use the "xcodebuild" CLI, you still have to create the project through Xcode.
- Closures: I guess we will be able to use these soon, but it is going to take awhile for all the API's to get updated to accommodate them.
- No dynamic variables: It's handy to be able to shove data into objects sometimes. It's a hack, but as long as you treat it as such you can save a lot of needless code. (You can do this via the ObjC runtime, but it's messy)
- Unit Testing: It barely exists and is difficult to use.
- No namespacing: ObjC handles namespaces by prefixing class names. Blah, that is so 1978.
Compared to other C-supersets, it's not the worst thing ever, but yeah I totally agree with you that Obj-C is painful compared to many newer languages. So glad that MacRuby is pretty much usable now.
I just wish I could use it for iPhone development. :)
Am I the only person in the world who happened to like header files? It's a nice tool (for me) to separate interface declaration from modules/classes, so it's much easier to navigate massive codebases without the help from IDE.
Seriously, how would you get a list of all functions in a module without an IDE? Besides, I put all my documentation into h-files as well, so other devs can pretty much see what I am doing without ever glancing at c-files.
With Ruby or Java you need some advanced folding support in your editor or a full-fledged IDE.
> a vestigial language that isn't suited for a majority of application development.
But good enough to write major parts of an operating system in by a company full of people easily smarter than you? Say what?
> Header Files
It's C for chrissakes.
> No GC on the iPhone
Because it's a performance penalty. Clock cycles on a phone are vastly more important than on a desktop/laptop. I can guarantee you this will change in a few years.
> No NSDictionary/NSArray literals
It's not a scripting language. Show me array literals in C or C++ that map to an underlying collection class that gives you fast enumeration and then we talk.
> Xcode
Personal preference.
> Closures
They're called Blocks.
> No dymanic variables
It's called 'id'.
id whatever = [[YourObject alloc] init];
But even better:
id whatever = [[NSClassFromString(@"YourClass") alloc] init];
Or how about setting properties on objects dynamically?
You bitch about all the typing, but you want to type out namespaces instead of using a prefix on your classnames. Ok ...
Your confusing ObjC with Ruby, Python, et al. But it is not any of those. Like I mentioned elsewhere, it's a high level layer on a low level language. Adjust your expectations accordingly.
I'd say he more aiming to comfort than impress. The good part is that because of the homogenous paradigm there are three rules to learn about when to retain/release. You find them, read them, think about it for 10 minutes, and then get on with programming.
You could contrast it with malloc/free in the unix/C ecosystem. Get a pointer back from function X in library Y. What do you do when you are done? free? call X_Z? constraints on the order of freeing dependent objects? That is a trip to the man pages every time.
Didn't see a single explanation of why the language deserves my love. Let's see.
* The language is verbose.
* Practically speaking, it's only used to developer for two platforms (OSX and iOS).
* The frameworks for those platforms are MEGA verbose.
* The memory management model for the iOS platform is not GC, and it's not manual management. Frankly I found manual management of memory simpler than retain/release. And the autorelease pool? That's just wrong.
* Typically speaking back to two files per class.
* Doesn't have any functional elements to it whatsoever. Any manipulation of collections = instant development velocity kill.
* Typically have to deal with two different kind of strings (NS versus C).
The memory management model for the iOS platform is not GC, and it's not manual management. Frankly I found manual management of memory simpler than retain/release. And the autorelease pool? That's just wrong.
retain/release + autorelease pools solve the ownership problem inherent in manual memory management system. You can return a heap allocated object from your function/method and neither you nor the caller have to be concerned about how it will be cleaned up.
Not sure what's wrong with that solution -- I've even implemented/used an equivalent implementation for pure C code.
"Doesn't have any functional elements to it whatsoever."
There are methods like makeObjectsPerformSelector: and now methods for taking blocks.
Sending a selector is not functional, true, because it is an OO language, not a functional one. So the idea is "send this message to all these objects" instead of "call this function on all these objects."
Unfortunately, I don't see anyway to create a new collection from an existing one by sending each object a message (the equivalent of map). Furthermore, some methods actually do take C functions, and others take an NSPredicate. It would be more consistent if they had found a way to do all these things by sending selectors and a varargs list.
(It seems like blocks is the new, improved way to do all these things, and rather functional, but all the older ways still exist, so a developer must understand all of them.)
Are blocks available in the iOS version of Objective-C? (Not trying to refute your point, just curious, since that would be exciting news for me if I do another iPhone app...
As someone who has been, on and off, writing Objective-C for the past decade, I will unequivocally state that as application programming languages go, it's a terrible 1980s jalopy of bad language decisions cobbled on top of more bad language design under which Smalltalk-descendent ideas peek through now and then.
Language research has progressed. Microsoft has invested heavily in C# and related technologies. Even Smalltalk research moved on -- strongtalk, newspeak. We have alternative, real-world usable languages running on the JVM, from Scala to Clojure.
Yet Objective-C moves forward one slow, stuttering step at a time. There are no namespaces. There are no self types (your init methods all have to return id so that they don't conflict with other init methods that have the same name). There are no private methods. Writing an initializer takes 3 lines of boilerplate, every time, plus the header declaration:
The language is obtuse, ridiculously verbose, frustrating to use, and downright paleolithic compared to modern deployed languages. It's a joke compared to everyone else's modern language research. I suffer through it full time because that's what the platform demands, but I would shoot it in the head in a second if I could.
Nuke it from orbit. It's the only way to be sure.
Anyone who thinks ObjC is a good language either hasn't actually spent significant time outside of C/C++/ObjC, or is still new to the wide, wonderful world of Mac/iPhone development.
I pretty much totally agree. I released two apps in the app store (one was a rather elaborate game). I feel I experienced enough to get a feel for what the language is like, and I came away unimpressed. At the most basic level, how verbose the language is is what bugged me the most. You gotta type like crazy to get anything done in Obj-C.
As someone who does a ton of Objective-C, I challenge the notion that namespaces are even remotely necessary. I've also done development in nearly everything under the sun, in nearly every "popular" language under the sun, which challenges your other assumption that anyone who thinks Objective-C is good hasn't spent time outside of C/C++/Objective-C.
I'm guessing you've never written a Windows app with C++ and MFC. Or have done any hardcore UI development in C# or Java - both languages that are easily way more verbose - and require way more boilerplate - than Obj-C.
My assumption is that you simply don't grok it, that you haven't learned how to utilize dynamic dispatch, KVO, etc. to greatly simplify and streamline your application designs. Or you are one of those script kids that takes all the low level shit for granted. This isn't python. This isn't ruby. This isn't even smalltalk. It's a high level layer on top of a low level language. You don't get that kind of performance without some sacrifice, but rest assured that sacrifice is significantly less than C/C++ while maintaining similar or the same performance.
Obj-C does not have a similar performance profile to C/C++. Method dispatch is far slower than vtables. I've personally witnessed a huge Obj-C dev project fall apart when the team couldn't get performance up to snuff, even with dedicated help from Apple's UI team. The rewrite in C++ is progressing nicely.
And as someone who is currently writing high-performance ObjC code, and who has written internet-scale packets-per-second-metered code in C and C++, I call bullshit on this.
I have no doubt that method dispatch is significantly slower than vtables, but you're ignoring the fact that for performant code, plenty of C++ devs believe that vtables are far too slow as well. Large high-performance C-style projects are always struggling with the tension between the indirection that architects want to keep the system clean and the hardwired directness that the profiler says the system needs to be fast. ObjC didn't introduce this dilemma; function pointers did. It's so well known in C++ code that the MIT Click Modular Router even got distributed with a tool that automated de-virtualizing method calls.
In both C++ and ObjC, when dispatch gets scary, you write C code. The difference is that C++ pummels you about the head and shoulders for even considering writing straight C with naked pointers, while ObjC could care less.
I would rather avoid ObjC. I would rather build a large system out of any high-level language, from Scala to Ruby to Python to Lisp, and use an FFI to drop into C code. But I'd spend the rest of my career in ObjC without so much as a Bourne shell script to fall back on than I would willingly start another project in C++.
So on 64-bit architectures Obj-C messages are eight times slower than a vtable lookup. There's no way that could make or break an apps performance, right?
No, there isn't. Because in any application where that code path was at the top of your profile, you'd code around it with direct function invocation, just like people do in C++ with expensive chains of vtable calls (which you end up with in GoF-style code).
In many real world apps there just isn't a single chokepoint but overhead distributed over your entire object model. C++ gives you 8x the breathing room that Obj-C does before you have to start tearing your abstractions apart and coding direct. For a codebase of any real size that can easily be a dealbreaker.
This is why it's easy enough for advocates of python/php/ruby to say "just code the slow parts in c" but often far harder to actually do this without losing any advantage the higher level language bought you in the first place.
Comparing the amount of time it takes to refactor an expensive (inner-loop) series of message invocations into a direct function call to the amount of time it takes to recode Ruby in C and bridge it with an FFI is specious.
There's a huge difference between the overhead of a dynamic function call and a vtable lookup. No doubt there are some cases where even a vtable lookup is too expensive but there are millions upon millions of lines of production C++ in high-performance apps that use C++'s vtable dispatch.
What language would you choose to write something like Protools, Photoshop, Maya, Visual Studio etc in? Definitely not C and definitely not Obj-C.
There's millions upon millions of lines of production code, some of it (for instance, at the financial exchanges) millisecond-optimized, running in Java. What's your point?
Again, I simply call bullshit on the idea that you couldn't write ProTools or Photoshop in ObjC. The portions of those systems where you care deeply about performance can be written most effectively in bare-metal C anyways; it's a delusion of C++ programmers that all the shellac and geritol that C++ offers is giving them a major performance benefit. It's C++ that forces you to make a lifestyle decision by pretending that pointers are anything other than register-sized integers. ObjC is just enough object goop layered over straight C to make large programs maintainable.
I hate C++ as much as the next guy but the idea that the people behind essentially all the performance-critical desktop apps on the planet are just too dumb to move on is quite strange.
Again, I've seen first hand a big, native UI project crash and burn on Obj-C dispatch overhead that is now trucking happily along in C++. Have you?
I have never seen an ObjC program crash and burn under the weight of ObjC. I have seen two major C++ projects get rewritten, once to straight C and once to new flavor-of-the-month C++ (from ACE-style objecty GoF-y C++ to Alexandrescu-y template-y C++).
You talk like adoption of C++ is a testimonial to C++'s power. The fact is, the market picked C++. Your realistic choices for bare metal app dev are straight C, which you can use anywhere, or C++, which you can use anywhere. If you want native objects, you're going to use C++.
There are two places where ObjC is even an option:
* On Apple stacks.
* In SaaS/ASP/service backend code.
In both of those places, ObjC is better than C++. If you care about portability, write in C or JVM+C.
I don't understand the comparison you're drawing. On most platforms, they don't have the option of using Objective-C (support outside the Apple ecosystem could charitably be called "anemic"), and on Apple platforms, most native development is done using Objective-C.
As someone who does a ton of Objective-C, I challenge the notion that namespaces are even remotely necessary ...
Apple is now suggesting that you use three-character class name prefixes, since they claim all the two character ones. I had my two character prefix claimed by a new private framework Apple added to iOS, and now one of my class names conflict with one of theirs. Kaboom.
If you go the no-prefix route, your code isn't library-reusable since other people will do the same thing, and you will still get screwed -- Apple regularly claims non-prefixed classes in their code, too.
My assumption is that you simply don't grok it, that you haven't learned how to utilize dynamic dispatch, KVO, etc. to greatly simplify and streamline your application designs. Or you are one of those script kids that takes all the low level shit for granted. This isn't python. This isn't ruby. This isn't even smalltalk.
Seeing as you're writing ObjC using a compiler I've worked on, I think that probably understand the "low level shit" better than you do.
Just because I have the perspective to understand what's wrong with a language doesn't mean I can't or won't use it when it is the correct solution in a specific problem domain.
If Apple developed a first-class alternative to ObjC I would switch in a heartbeat. In the meantime -- to write Mac/iPhone apps -- I will continue to use it.
The best way to hate a language is to implement it. It forces you to learn all the ins and outs of the language, every nook and obscure corner that something, somewhere, depends on.
Apple is now suggesting that you use three-character class name prefixes, since they claim all the two character ones.
So you saw that talk at WWDC as well? Every engineer from Apple that I've spoken to and asked about this has gone "What?! Did he really say that? Ignore it. We don't recommend that. Not at all."
Seeing as you're writing ObjC using a compiler I've worked on, I think that probably understand the "low level shit" better than you do.
You work on LLVM? Props to you, if so. Thats an awesome project. However, if you work on gcc, I haven't used that in over a year :-)
(I kid. Props to you, either way. I can't do what I do without what you do.)
So you saw that talk at WWDC as well? Every engineer from Apple that I've spoken to and asked about this has gone "What?! Did he really say that? Ignore it. We don't recommend that. Not at all."
Regardless of what they say, Apple is still claiming new two-character prefixes, including the one I've been using for years.
You work on LLVM? Props to you, if so. Thats an awesome project. However, if you work on gcc, I haven't used that in over a year :-)
I'm a big fan of LLVM, but no, I've done nothing with it. That said, if you're using clang for your production builds, you're a much braver soul than me.
There are still plenty of codegen issues, especially in the new iPhone/ARM support. There's a reason Apple is still using GCC.
That said, if you're using clang for your production builds, you're a much braver soul than me.
Hardly brave; I only use it personal projects (which target 10.6/64-bit Mac) and debug builds. Release/Ad Hoc/Distribution builds for what I work on uses llvm-gcc. But, I'm not responsible for those builds.
When was the last time you've used C#? The fact you are lumping it in with Java already suggests your C# skills are very out of date. C# is by far the fastest growing mainstream language. C# 3 and now C# 4 require very little boilerplate code. I'm often amazed at how clean and succinct my C# code can become nowadays.
As for UI programming in C#, give WPF and/or Silverlight a try. They both have their downsides, but in the end they offer a far more pleasant experience than Cocoa Touch. I haven't written an MFC app in about 1.5 decades or so.
You just wrote exactly the same thing I did, but in a style that triggers GCC warnings regarding using assignment as a truth value.
Huge advantage of this is that you can implement object pools, singletons, etc. transparently.
You might consider looking into Newspeak constructors to see how it can be (much) better done, with much less code.
In short, treat constructors as class methods, allow them to be used interchangeably, support self-types so that you can't get selector conflicts, enforce calling of the constructor so you don't have to rely on documenting the designated initializer.
I'm otherwise mainly a Rubyist, but I have to say that on the whole I really like the verbosity of Cocoa, because I find it's generally the right sort of verbosity: it's there to clearly and unambiguously describe what's going on. The stringByReplacingOccurencesOfString:withString: method, as mentioned in the article, is a great example of that: three cheers for it!
The worst part is Apple forces you to use Objective-C on the iPhone even if better options exist. I created a Lua/Cocoa bridge http://probablyinteractive.com/2009/10/18/Setting-up-iPhone-... that works wonderfully. It considerably cuts down the amount of code I need to write, but Apple forbids me from using it on the iPhone.
The discussion for another article on the front page discusses why, even today, many developers prefer C-family languages over Java for developing user interfaces, because of unpredictable delays in responsiveness with garbage controlled languages.
In that context, Objective C is the closest you will find to a best of both worlds language for responsive user interfaces. Being a strict superset of C, you can control the performance characteristics of your application to your hearts content. With SmallTalk style message passing, you can implement highly dynamic object oriented designs.
The warts that come along with this are the places where C still pokes through when you just want to work in a high level object oriented context and things like header files and static variables rear their ugly heads.
You can easily get unpredictable delays in responsiveness with reference counting too. How can you be sure releasing that reference isn't going to unleash the teardown of some huge data structure?
If you choose to attack someone's intelligence instead of presenting a factual counterargument then it behooves you to get your spelling right.
So again, how can you be sure that the reference you just released isn't the last live pointer to some huge datastructure that now has to be torn down reference-by-reference?
Like I said, if that happens you are doing something incredibly wrong. It is your error. It's not the language, it's bad programming, bad architecture, bad whatever.
If you release an object and it gets torn down, it means you didn't increment the ref in the right place. And I don't get how release/retain is such a difficult concept to grasp. If you don't think you can deal with it, should this be your profession?
Brushing aside the unnecessary and uncalled for rudeness...
If you release the last pointer to a complex datastructure that has no other references, you certainly should hope it gets "torn down" = deallocated. If that object happened to contain a lot of other objects they will each in turn have to be released. Obviously your main code execution path is going to halt while this graph is walked and released.
Maybe Jimbokun is right that you can control this better in a ref counting scheme than in a typical GC but you're hardly immune from the problem.
I think the idea is that, if you're careful, you can avoid situations like this with a reference counting scheme.
With a garbage collector, there are more things that are out of the developer's control, like when exactly the garbage collector will run and for how long.
C languages don't magically always perform better than other languages, but they do give you a greater level of control over what happens when. Whether that's a good or a bad thing is up to you.
That's not unpredictable. You might not happen to foresee it, but it's pretty obvious when the teardown of a huge data structure might occur when you're the one releasing it.
90 comments
[ 43.4 ms ] story [ 2807 ms ] thread"Our mobile development team is highly specialized in creating applications for many popular mobile platforms including the iPhone..."
Does "highly specialized" mean learned it last night...
Syntax and naming conventions are another matter...
However, I fail to see why I should have to worry about it and do it manually.
Assembler was probably part of many peoples basic training as well. Do you want to spend your days juggling everything in 4 general purpose registers because it makes you feel like a better programmer? Is that the best use of your time?
GET OFF MY LAWN YOU DAMN KIDS WITH YOUR FANCY PYTHON.
Using a language like obj-c where you have to do memory management manually just seems so archaic after using modern languages. Plus there is strange property duplication syntax, split header/code files, a GUI editor that doesn't easily wire events to code, named parameters, c/smalltalk calls mixed together, etc.. it's just a mess.
In my brief stint using it the whole time I kept thinking this would be so much simpler if I could do it the XYZ language way. Obj-C is a language that you have to try really hard to like. If you have to convince yourself then maybe it's not that good.
The "property duplication syntax" (I assume you mean the declare versus synthesis) is there for flexibility and so you can do some pretty good customization to make your classes work better.
For OS X, Objective-C now has garbage collection that works pretty well.
That's not an Objective C thing, the language has garbage collection, just it isn't enabled for the mobile platform, for the reason it eats power and memory.
Plus there is strange property duplication syntax
You don't have to bother with that anymore. The only reason you ever did with iPhone dev is because the iPhone Simulator didn't support the modern runtime. If you only tested on the device, you never had to bother with it.
As of LLVM 1.5 (in Xcode 3.2.3) or 2.0 (in 4.0) on 10.6, the compiler can fake enough for runtime support (and only requires @property declarations - no more ivar or @synthesizers): http://www.mcubedsw.com/blog/index.php/site/comments/new_obj...
named parameters
Objective-C doesn't have named parameters. It intertwines the method names with the arguments that it takes.
Instead of `void doStuff(foo, bar, baz);`, its `- (void) doStuffFoo:(id) foo bar:(id) bar baz:(id) baz;` (which can also be written (and compiled) as: `- (void) :foo:bar:baz;` if you wanted).
I would recommend use of Objective-C without Apple frameworks to anyone who must build robust modular systems while retaining C compatibility or performance characteristics. I use it myself in a game engine.
Here are some reasons I think Objective-C needs to be retired:
- Header Files: These are archaic and require you to repeat code unnecessarily. Compiler's shouldn't require humans to do something that computers are better at.
- No Automatic Garbage Collection: In ObjC 2.0 we have this, but not on the iPhone. Unless you are making a high performance game, there is no reason the phone can't handle Automatic GC.
- No NSDictionary/NSArray literals: [[NSDictionary alloc] initWithObjectsAndKeys:@"value", @"key", @"value2", @"key2", nil]; // Enough said
- No regex: You kind of get regex's in 3.2+, but they are very limited and require around 3-4 lines of setup to get anything done.
- Xcode: You are pretty much required to use Xcode and I don't like Xcode. Even if you use the "xcodebuild" CLI, you still have to create the project through Xcode.
- Closures: I guess we will be able to use these soon, but it is going to take awhile for all the API's to get updated to accommodate them.
- No dynamic variables: It's handy to be able to shove data into objects sometimes. It's a hack, but as long as you treat it as such you can save a lot of needless code. (You can do this via the ObjC runtime, but it's messy)
- Unit Testing: It barely exists and is difficult to use.
- No namespacing: ObjC handles namespaces by prefixing class names. Blah, that is so 1978.
I just wish I could use it for iPhone development. :)
Seriously, how would you get a list of all functions in a module without an IDE? Besides, I put all my documentation into h-files as well, so other devs can pretty much see what I am doing without ever glancing at c-files.
With Ruby or Java you need some advanced folding support in your editor or a full-fledged IDE.
These "people" don't also seem to get when you distribute a lib, you need to distribute headers with them.
But good enough to write major parts of an operating system in by a company full of people easily smarter than you? Say what?
> Header Files
It's C for chrissakes.
> No GC on the iPhone
Because it's a performance penalty. Clock cycles on a phone are vastly more important than on a desktop/laptop. I can guarantee you this will change in a few years.
> No NSDictionary/NSArray literals
It's not a scripting language. Show me array literals in C or C++ that map to an underlying collection class that gives you fast enumeration and then we talk.
> Xcode
Personal preference.
> Closures
They're called Blocks.
> No dymanic variables
It's called 'id'.
But even better: Or how about setting properties on objects dynamically? Or dynamically dispatching methods?Ever messed with vtables in C++?
> Unit Testing
Agree, but that's changing.
> No namespacing
You bitch about all the typing, but you want to type out namespaces instead of using a prefix on your classnames. Ok ...
Your confusing ObjC with Ruby, Python, et al. But it is not any of those. Like I mentioned elsewhere, it's a high level layer on a low level language. Adjust your expectations accordingly.
It really is sad that so little of the state of the art in GC is available in mainstream languages.
You could contrast it with malloc/free in the unix/C ecosystem. Get a pointer back from function X in library Y. What do you do when you are done? free? call X_Z? constraints on the order of freeing dependent objects? That is a trip to the man pages every time.
Erm, not true. For example, NSString's
* The language is verbose.
* Practically speaking, it's only used to developer for two platforms (OSX and iOS).
* The frameworks for those platforms are MEGA verbose.
* The memory management model for the iOS platform is not GC, and it's not manual management. Frankly I found manual management of memory simpler than retain/release. And the autorelease pool? That's just wrong.
* Typically speaking back to two files per class.
* Doesn't have any functional elements to it whatsoever. Any manipulation of collections = instant development velocity kill.
* Typically have to deal with two different kind of strings (NS versus C).
So for now, yep, I still hate ObjectiveC.
The memory management model for the iOS platform is not GC, and it's not manual management. Frankly I found manual management of memory simpler than retain/release. And the autorelease pool? That's just wrong.
retain/release + autorelease pools solve the ownership problem inherent in manual memory management system. You can return a heap allocated object from your function/method and neither you nor the caller have to be concerned about how it will be cleaned up.
Not sure what's wrong with that solution -- I've even implemented/used an equivalent implementation for pure C code.
NSString has plenty of methods to deal with this, and you get boxing for free between CFString and NSString.
> The frameworks for those platforms are MEGA verbose.
Which some view as self documenting.
And that pesky char * that you get from C.
There are methods like makeObjectsPerformSelector: and now methods for taking blocks.
Sending a selector is not functional, true, because it is an OO language, not a functional one. So the idea is "send this message to all these objects" instead of "call this function on all these objects."
Unfortunately, I don't see anyway to create a new collection from an existing one by sending each object a message (the equivalent of map). Furthermore, some methods actually do take C functions, and others take an NSPredicate. It would be more consistent if they had found a way to do all these things by sending selectors and a varargs list.
(It seems like blocks is the new, improved way to do all these things, and rather functional, but all the older ways still exist, so a developer must understand all of them.)
Language research has progressed. Microsoft has invested heavily in C# and related technologies. Even Smalltalk research moved on -- strongtalk, newspeak. We have alternative, real-world usable languages running on the JVM, from Scala to Clojure.
Yet Objective-C moves forward one slow, stuttering step at a time. There are no namespaces. There are no self types (your init methods all have to return id so that they don't conflict with other init methods that have the same name). There are no private methods. Writing an initializer takes 3 lines of boilerplate, every time, plus the header declaration:
The language is obtuse, ridiculously verbose, frustrating to use, and downright paleolithic compared to modern deployed languages. It's a joke compared to everyone else's modern language research. I suffer through it full time because that's what the platform demands, but I would shoot it in the head in a second if I could.Nuke it from orbit. It's the only way to be sure.
Anyone who thinks ObjC is a good language either hasn't actually spent significant time outside of C/C++/ObjC, or is still new to the wide, wonderful world of Mac/iPhone development.
I'm guessing you've never written a Windows app with C++ and MFC. Or have done any hardcore UI development in C# or Java - both languages that are easily way more verbose - and require way more boilerplate - than Obj-C.
My assumption is that you simply don't grok it, that you haven't learned how to utilize dynamic dispatch, KVO, etc. to greatly simplify and streamline your application designs. Or you are one of those script kids that takes all the low level shit for granted. This isn't python. This isn't ruby. This isn't even smalltalk. It's a high level layer on top of a low level language. You don't get that kind of performance without some sacrifice, but rest assured that sacrifice is significantly less than C/C++ while maintaining similar or the same performance.
I have no doubt that method dispatch is significantly slower than vtables, but you're ignoring the fact that for performant code, plenty of C++ devs believe that vtables are far too slow as well. Large high-performance C-style projects are always struggling with the tension between the indirection that architects want to keep the system clean and the hardwired directness that the profiler says the system needs to be fast. ObjC didn't introduce this dilemma; function pointers did. It's so well known in C++ code that the MIT Click Modular Router even got distributed with a tool that automated de-virtualizing method calls.
In both C++ and ObjC, when dispatch gets scary, you write C code. The difference is that C++ pummels you about the head and shoulders for even considering writing straight C with naked pointers, while ObjC could care less.
I would rather avoid ObjC. I would rather build a large system out of any high-level language, from Scala to Ruby to Python to Lisp, and use an FFI to drop into C code. But I'd spend the rest of my career in ObjC without so much as a Bourne shell script to fall back on than I would willingly start another project in C++.
http://www.mikeash.com/pyblog/performance-comparisons-of-com...
Nice try, though.
This is why it's easy enough for advocates of python/php/ruby to say "just code the slow parts in c" but often far harder to actually do this without losing any advantage the higher level language bought you in the first place.
What language would you choose to write something like Protools, Photoshop, Maya, Visual Studio etc in? Definitely not C and definitely not Obj-C.
Again, I simply call bullshit on the idea that you couldn't write ProTools or Photoshop in ObjC. The portions of those systems where you care deeply about performance can be written most effectively in bare-metal C anyways; it's a delusion of C++ programmers that all the shellac and geritol that C++ offers is giving them a major performance benefit. It's C++ that forces you to make a lifestyle decision by pretending that pointers are anything other than register-sized integers. ObjC is just enough object goop layered over straight C to make large programs maintainable.
Again, I've seen first hand a big, native UI project crash and burn on Obj-C dispatch overhead that is now trucking happily along in C++. Have you?
You talk like adoption of C++ is a testimonial to C++'s power. The fact is, the market picked C++. Your realistic choices for bare metal app dev are straight C, which you can use anywhere, or C++, which you can use anywhere. If you want native objects, you're going to use C++.
There are two places where ObjC is even an option:
* On Apple stacks.
* In SaaS/ASP/service backend code.
In both of those places, ObjC is better than C++. If you care about portability, write in C or JVM+C.
Apple is now suggesting that you use three-character class name prefixes, since they claim all the two character ones. I had my two character prefix claimed by a new private framework Apple added to iOS, and now one of my class names conflict with one of theirs. Kaboom.
If you go the no-prefix route, your code isn't library-reusable since other people will do the same thing, and you will still get screwed -- Apple regularly claims non-prefixed classes in their code, too.
My assumption is that you simply don't grok it, that you haven't learned how to utilize dynamic dispatch, KVO, etc. to greatly simplify and streamline your application designs. Or you are one of those script kids that takes all the low level shit for granted. This isn't python. This isn't ruby. This isn't even smalltalk.
Seeing as you're writing ObjC using a compiler I've worked on, I think that probably understand the "low level shit" better than you do.
What?
If Apple developed a first-class alternative to ObjC I would switch in a heartbeat. In the meantime -- to write Mac/iPhone apps -- I will continue to use it.
So you saw that talk at WWDC as well? Every engineer from Apple that I've spoken to and asked about this has gone "What?! Did he really say that? Ignore it. We don't recommend that. Not at all."
Seeing as you're writing ObjC using a compiler I've worked on, I think that probably understand the "low level shit" better than you do.
You work on LLVM? Props to you, if so. Thats an awesome project. However, if you work on gcc, I haven't used that in over a year :-)
(I kid. Props to you, either way. I can't do what I do without what you do.)
Regardless of what they say, Apple is still claiming new two-character prefixes, including the one I've been using for years.
You work on LLVM? Props to you, if so. Thats an awesome project. However, if you work on gcc, I haven't used that in over a year :-)
I'm a big fan of LLVM, but no, I've done nothing with it. That said, if you're using clang for your production builds, you're a much braver soul than me.
There are still plenty of codegen issues, especially in the new iPhone/ARM support. There's a reason Apple is still using GCC.
Hardly brave; I only use it personal projects (which target 10.6/64-bit Mac) and debug builds. Release/Ad Hoc/Distribution builds for what I work on uses llvm-gcc. But, I'm not responsible for those builds.
As for UI programming in C#, give WPF and/or Silverlight a try. They both have their downsides, but in the end they offer a far more pleasant experience than Cocoa Touch. I haven't written an MFC app in about 1.5 decades or so.
You just wrote exactly the same thing I did, but in a style that triggers GCC warnings regarding using assignment as a truth value.
Huge advantage of this is that you can implement object pools, singletons, etc. transparently.
You might consider looking into Newspeak constructors to see how it can be (much) better done, with much less code.
In short, treat constructors as class methods, allow them to be used interchangeably, support self-types so that you can't get selector conflicts, enforce calling of the constructor so you don't have to rely on documenting the designated initializer.
The long method names don't bother me.
Ruby --> Obj-C or PHP --> Obj-C
Just for references sake. Or some "gotchas".
NSObject Class Reference
– performSelector:
– performSelector:withObject:
– performSelector:withObject:withObject:
why stop there, lets tack on more withObject arguments
In that context, Objective C is the closest you will find to a best of both worlds language for responsive user interfaces. Being a strict superset of C, you can control the performance characteristics of your application to your hearts content. With SmallTalk style message passing, you can implement highly dynamic object oriented designs.
The warts that come along with this are the places where C still pokes through when you just want to work in a high level object oriented context and things like header files and static variables rear their ugly heads.
I'm really starting to doubt the intelligence of HN.
So again, how can you be sure that the reference you just released isn't the last live pointer to some huge datastructure that now has to be torn down reference-by-reference?
If you release an object and it gets torn down, it means you didn't increment the ref in the right place. And I don't get how release/retain is such a difficult concept to grasp. If you don't think you can deal with it, should this be your profession?
If you release the last pointer to a complex datastructure that has no other references, you certainly should hope it gets "torn down" = deallocated. If that object happened to contain a lot of other objects they will each in turn have to be released. Obviously your main code execution path is going to halt while this graph is walked and released.
Maybe Jimbokun is right that you can control this better in a ref counting scheme than in a typical GC but you're hardly immune from the problem.
With a garbage collector, there are more things that are out of the developer's control, like when exactly the garbage collector will run and for how long.
C languages don't magically always perform better than other languages, but they do give you a greater level of control over what happens when. Whether that's a good or a bad thing is up to you.