Why RubyMotion Is Better Than Objective-C
joshsymonds.com
joshsymonds.com
"Why do I have to have huge statements like this?
static UIColor firstColor = nil;
static UIColor secondColor = nil;
static UIColor thirdColor = nil;
static UIColor fourthColor = nil;
static UIColor fifthColor = nil;
static UIColor sixthColor = nil; "
Great, so someone who doesn't know how to use arrays is criticizing Objective-C as a language.
To everyone claiming that Objective-C's syntax is unintuitive/unwieldly/etc: remember that familiar != intuitive.
My two darling languages are Python and Haskell and I learned programming in C/assembly, and I find Objective C + Cocoa Touch quite nice, especially since ARC was introduced. Yes, there are things that can be slightly bothering, but once you pass the initial "wow this syntax is weird" hurdle, you're good to go.
It's great to have Ruby as an alternative, but all that Objective-C hating is silly and quite unproductive. Yes, there are limitations in the iOS dev stack (mostly with XCode— but hey, it's not that bad, people have gotten good things done with Eclipse and it doesn't exactly have a perfect track record either). But if the only thing that's getting in your way of developing a great application is the fact that Objective C's syntax makes you uneasy, then you should probably reconsider your abilities as an engineer.
As usual, the ones doing great things done probably won't be the ones tweeting & blogging about how Objective-C is lame and that if only $(arbitrary language) could be used for iPhone dev, then they would change the world.
I think the author has a valid point though, even though that example doesn't illustrate it well. He should have used variable names that didn't immediately cry out for arrayification, but there is a boilerplate problem in Objective C.
The thing is, a lot of the verbosity of Objective C is actually a win. Take the messaging syntax: beautiful and readable. And the lack of first-class syntax for almost anything? Usually pretty nice and elegant. Nothing feels magic.
But you don't get a choice about these ideals. Need optional arguments? Too bad. Use a config dictionary. And there's no literal syntax for dictionaries, so every time somebody calls your method, it's going to be a big pile of boilerplate.
I don't even think Objective-C should compromise on all of these ideals, but it should compromise on some, and I think that kind of basic functionality would have been a better point of focus than foreach loops and dot-notation.
Since they don't, people are tempted to use CPP macros to work around these shortcomings. You may remember CPP macros from every GDB nightmare you've ever had.
It has a much steeper learning curve than Ruby for sure, but once you're proficient it's no harder to use. Indeed there's benefits to both languages.
- Xcode is Unstable
It's gone through periods of instability. But in the current version you may encounter the odd crash (perhaps once a week in full time use for me). Really not an issue given it's a cutting edge tool that's rapidly evolving.
- Xcode Hides Important Information
It has a learning curve. Some things take time to learn but once you do you're more productive.
- Objective-C Is Tedious
Matter of opinion. One person's tedium is another being explicit and reaping the benefits during refactoring, code completion and compilation speed.
- RubyMotion is Easy to Use
For sure easier than Objective-C. But so what? Can it build complex apps more quickly than Objective-C when someone becomes proficient? Probably not.
- RubyMotion is Ruby
That's great. Ruby is a great, easy to use and powerful language. I love Ruby. However given all the other things you sacrifice to get Ruby it's really not worth it.
- RubyMotion Makes Debugging Easy
Really? It sure doesn't look like it does. Xcode and LLVM save me a hell of a lot of time writing my apps because I don't need to actually run them and see the exceptions. And what about the static analyzer?
- RubyMotion Isn’t Perfect
Indeed.
- Better Than Objective-C
For trivial apps yes. For apps you'll be paid to write, in my opinion probably not.
If RubyMotion offered a truly higher level abstraction over Cocoa Touch or offered cross-platform portability I might be interested but an arguably better syntax over the same API just isn't enough of a win.
Now don't get me wrong, I'm normally of the opinion that anything that whiffs of manual memory management is for chumps. But by day I write apps that target workstations that have enough RAM that I can get away with pretending that memory is an unlimited resource.
On a memory-constrained platform like iOS, though, being able to tightly control how much memory you're using becomes much more valuable. If not critical. And the one place where garbage collection simply can't beat manual memory management is total memory consumed. All those dead objects that are waiting around to be scooped up by the collector do take up space. Sometimes a whole lot of it.
- RubyMotion is Ruby
That's great. Ruby is a great, easy to use and powerful language. I love Ruby. However given all the other things you sacrifice to get Ruby it's really not worth it.
What do you sacrifice to get to use Ruby? I've avoided learning to program iOS because I really dislike Obj-C. If Ruby were good enough for 60% of the apps on the App Store I'd join in a heartbeat.- No syntax/error checking as you type
- No static analyzer
- No code completion (perhaps you could find a 3rd party module to do this eventually)
- No refactoring support (very important in larger projects)
- Probably longer compilations (in Xcode/ObjC the compiler will know which files are modified by looking at the included headers and only recompile what is needed, in Ruby I would expect it's gotta do them all but could be wrong).
>> - Objective-C Is Tedious
>
> Matter of opinion. One person's tedium is another being explicit and reaping the
> benefits during refactoring, code completion and compilation speed.
This is not a matter of opinion.Objective-C:
NSDictionary *d = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInteger:1], @"foo", [NSNumber numberWithBool:YES], @"bar", nil];
Ruby:
d = {foo: 1, bar: true}
Objective-C's "explicitness" provides no advantage to the programmer here whatsoever.
I write code all day every day in Objective-C. It is an extremely tedious language that requires large amounts of boilerplate to perform even simple tasks. (Yes, I know about the new literal syntax available in Mountain Lion, but that doesn't change the broader point.)
Your programming language is the most powerful tool in your toolbox. Ruby is clearly more powerful than Objective-C in terms of how much code one has to write to accomplish a given task.
Currently I'm mainting a couple of medium to big obj-c projects and one big ROR custom CMS. My background was mostly in Python. A few years ago this sharade of writing faster obj-c app started. You guys might have heard of Wax (in Lua) which seemed to have a similar concept to RubyMobtion (of course, w/o the shiny presentation style that comes with the ROR community). After rolling my sleeves and digging into Obj-C (and CocoaTouch), all other alternatives look like made for people who are comfy/lazy and stick to writing in high-level scripting languages. If they admit their status, no problem, just that personally I would not bet medium-to-big project on anything else except plain obj-c.
The "RubyMotion Makes Debugging Easy" is the silliest part. Good luck on using GDB/LLDB!
Note: sharade and other casual language was in no intent meant to discredit the hard work put in by the developers of such tools. Full respect for the gents behind RubyMotion. They are building a fair business.
All and all, stop whining and get to know both sides.
A bad workman blames his tools. And, from what I read from the author, that's what he's doing. He doesn't understand trivial software patterns, such as pocketing like types into arrays (I hope everybody who took Programming 1 remembers this), and insists on doing things the Ruby way without a clear understanding of why Obj-C is actually a pretty good tool.
Uh, because you're declaring six static color variables. Also, they could be collapsed into one line.
> Introspection is unavailable at runtime
Not sure what this means. Everything is introspectable in Objective-C. #import <objc/runtime.h>
The cell dequeueing comparison uses a one liner for Ruby and an if statement for Obj-C. That's not a fair comparison. "dequeue ?: allocate" would be fair.
> dequeueReusableCellWithIdentifier, ugh.
What is wrong with this?
• I am dequeueing something from the receiver.
• It is a reusable cell.
• The first (and only) argument is the identifier for the cell.
What would be a better name, without losing the descriptiveness?
> Without tab completion, you do a lot of copying and pasting from the documentation when you find a method name you like, just to ensure you don’t accidentally typo it.
This is a huge problem, not a minor thing! The whole point of those "long" message (not method, btw, but that's minor) names is that you don't have to read documentation. If you want to append a format to a string, but don't know the name, just start typing "stringby" and the names are the documentation.
> dequeueReusableCellWithIdentifier, ugh.
What is wrong with this?
• I am dequeueing something from the receiver.
• It is a reusable cell.
• The first (and only) argument is the identifier for the cell.
What would be a better name, without losing the descriptiveness?
I don't think he's complaining about the name of the method, he's complaining about the fact that he has to type it all out now instead of Xcode completing it for him, which is a gripe against RubyMotion, not Objective-C or the cocoa API.IMHO, the name sucks because it includes information in the name that is also in the signature. At least it would be in languages that support overloading.
I'm very interested to see where this ends up however. I'd love to do iPhone programming (with IB support) in python or ruby. Just not with this tool, just yet.
Get some real iOS development under your belt before you make these broad assumptions.
After using it for almost a year, I find obj-c really nice now. But that was only after I got out of the C/C++ mindset and more into obj-c mindset.
If using Ruby for a developer to produce the same result is more productive, then not using Ruby Motion would be a crime against "true" engineering.
It's true that Xcode is bad, but the solution to that is to use AppCode, not to throw out the language.
I've seen quite a few examples since yesterday where the code given was not fewer in line count or even easier to read (partly subjective), but was simply more approachable and familiar to people who are already set on writing Ruby instead of ObjC.
If you know ruby very well you may get a head start here without having to learn ObjC (yet, i'll be shocked if you dont hit walls with this plan), but the mountain of work for you is learning the frameworks, and learning them without the benefit of 90% of the examples and help available specifically for ObjC.
And what of working with the parts of Apple's platforms that aren't Objective-C in the first place, like all the CoreFoundation stuff which is C. At some point you're going to hit walls that could be easily solved by dashing your code with a few lines of C or dropping in an example you found on stackoverflow, but now you've got to come up with the Ruby equivalent and you're actually juggling a new set of issues whether it seems that way or not. Maybe the time you save writing most of an App in ruby makes up for it, but I'd be surprised if thats the case in practice.
What about MonoTouch? To be honest I think I'd look at that first if I wanted something other than Obj-C. At least I could take my non-UI code and run it on Android.
Not the best researched sentence. Much of this is possible in RubyMotion because of Objective-C's metaprogramming and reflection and other powerful features. This makes me suspect the author's depth of knowledge of Objective-C. That said, he's right that Objective-C has a lot more syntactic noise than more recent languages like Ruby and Python.
I am not sure if the RubyMotion approach is different than Titanium -- does anyone know whether it is faster and why?
- I'm a huge fan of Ruby's || operator, but probably wouldn't use it to dequeue or create a table cell, because the line is way too long. Perhaps this is fixable with a return after the ||
- creating labels programmatically seems like a poor example because I'd do that in my storyboard, and it would take zero lines of code. Or 6 lines of XML for 6 labels, if I'm being pedantic.
#define MSTR(...) [[NSString stringWithFormat:__VA_ARGS__] UTF8String]
@implementation LotsaLabels
- (id)initWithFrame:(CGRect)frame
{
if (self = [super init]) {
CGFloat offset = 0.0;
[@[@"label1", @"label2", @"label3", @"label4"] enumerateObjectUsingBlock:^ (id object, NSInteger idx, BOOL *stop) {
object_setInstanceVariable(self, MSTR(@"%@_text", object), [[UILabel alloc] initWithFrame:CGRectMake(0, 10 + offset, self.frame.size.width, 40)]);
object_setInstanceVariable(self, MSTR(@"%@_label", object), [[UILabel alloc] initWithFrame:CGRectMake(0, 55 + offset, self.frame.size.width, 14)]);
UILabel *text = object_getInstanceVariable(self, MSTR(@"%@_text", object));
UILabel *label = object_getInstanceVariable(self, MSTR(@"%@_label", object));
text.font = [UIFont fontWithName:@"Arial Rounded MT Bold" size:40];
text.textColor = [UIColor redColor];
label.font = [UIFont fontWithName:@"Arial Rounded MT Bold" size:15];
text.textColor = [UIColor grayColor];
text.text = label.text = [object capitalizedString];
text.adjustsFontSizeToFitWidth = label.adjustsFontSizeToFitWidth = YES;
text.backgroundColor = label.backgroundColor = [UIColor clearColor];
text.textAlignment = label.textAlignment = UITextAlignmentCenter;
[self addSubview:text];
[self addSubview:label];
offset += 90.0;
}];
}
return self;
}
@end
The Ruby version is slightly less verbose, I'll give him that, but many of the lines are nearly identical.So if you think that Ruby is providing you with a significant shortcut here you're in for some disappointment.
I worked for a company doing Mac apps in REALbasic for several years, and this was a constant hassle. Additionally, RB chose the wrong backend for their compiler (Carbon instead of Cocoa) and there were multiple years of setbacks due to Apple hemming and hawing about whether they were going to deprecate Carbon altogether and RB porting their entire framework to Cocoa. During that process, everybody who emigrated to Objective-C got their stuff to market sooner, and with access to newer libraries to boot.
The second is the way in which complex applications are built. Some programming languages are known for having many design patterns around them, which often feel artificial. Objective-C and the Cocoa libraries use only a handful of them, but they come very natural.
So I guess what I'm saying is that a lot of people criticizing C++ probably don't have much experience with it, but that's kind of the point.
Also, the Obj-C object system is pretty high level and dynamic (message passing, late binding, dynamic dispatch). This makes it somewhat slower at method calling, but at the same time a lot easier to work with. The downside of being slow is usually mitigated by simply being able to drop back to plain old C if need be.
Of course, C++ can emulate all that, and without performance compromises, but at the expense of readability.
For the longest time, I would hands down prefer Obj-C to C++ just because it was simpler. The more experienced I become with C++, the more I am able to appreciate its power and no-compromise attitude, though.
"I like X. I'm not interested in Y."
and not
"X is better than Y."
That's my point. I think it's a worthwhile distinction for developers.
Also, Obj-C is somewhat more complicated than Ruby, though there is a lot of Ruby if you go looking. Obj-C is also more syntactically noisy than Ruby.
Also, let's not forget 90% of things that make money in the App Store are games. RubyMotion doesn't seem to do much to help you with that.
In other words, for Rubyists, RubyMotion is a thin wrapper around Objective-C classes that feels like home. For everyone else, it's an added layer that provides a thin sugar coating and not much else.
In the same vein that allowing Flash and C# toolkits above Cocoa Touch would slow the adoption new features (http://daringfireball.net/2010/04/why_apple_changed_section_...).
Objective-C better than C++? Wow, has this person ever used Objective-C and C++?
There is a recurring problem in which languages outgrow their original syntax when applied to new programming paradigms.
For example, accessing an array in C uses simple syntax: arr[5] = 10;
But with NSArrays, etc., we have to add lots of explicit method calls with lots of named arguments, destroying the clear and simple syntax meant to express use of an array in C.
The nice thing about C++ is that you can fix that by overloading operators so that a vector can use the same simple syntax most of the time. You can do this for any objects for which it makes sense... And it vastly improves the ease of coding and reading code.
In objective c, you simply can't improve it. Tons of operations with containers and objects are unnecessarily syntactically unwieldy. Higher level languages like Ruby do this as well, but C++ is fast and explicit. If you want to know what the operator is doing, you can step into it. You can read the code...
It's a higher level language, which allows you to get more work done faster. Case closed.