First question I asked myself: What does programming the Smalltalk-style message sending interface look like? What does [dict setObject:x forKey:y]; look like?
It looks like this:
dict:setObject_forKey(x, y);
Well.. okay. I know some people dislike the message sending syntax, but the API is written for that syntax. This is verbose, but readable (if you're familiar with Cocoa):
I know it is a personal thing, but I actually like the Smalltalk-style message system. I don't spend as much time look things up. It is interesting now that iOS gains enough popularity to attract enough people who prefer C/C++ style message syntax. Apple did the property thing to help, but It still feels a little weird.
- If you remove the boilerplate, you can likely get the Objective-C version down to about 40 lines.[1]
- Can Lua/Wax not use IB? The Objective-C version uses IB to lay the views out, while the Lua version seems to lay it out manually? It does for the main UIWindow, at least.
- The Objective-C and Lua code don't behave the same way. This isn't a 1:1 comparison.
1. Less, if you turn your AppDelegate into a UIApplication subclass (so it is a singleton, and you can not worry about dealloc in there because the app will be gone by the time dealloc is reached).
I was going to disagree with you about the boilerplate until I actually looked at the article, and you're right, it's just silly that the the Objective-C version gets about 10 additional methods that serve no real purpose.
The author must not be very experienced with iOS development because you can simply ignore all those extra empty methods if you do not wish to implement them.
It is really not fair to compare a verbose standard project template from Xcode with a a condensed Lua version.
It is only 'not fair' if the number of lines of code is important. Only the most naive programmers think that LOC actually means anything.
If you were really keen, you might consider which of the lines were authored by the programmer, and which were inserted by the tool 'auto-magically'.
In that case, Objective-C may actually come out ahead in this example!
Of course, I don't know how much of the Lua code was boilerplate supplied by the toolchain, all that stuff about twiddling the bounds and the frame might be boilerplate. In _that_ case, the actual amount of code written by both would be almost exactly the same.
And then we get onto secondary claims, e.g. benefits of garbage collection. (See the pretty graph)
Lastly we could compare them on 'prettiness' of code. Objective-C is quite ugly, but 'underscorising' the function names doesn't improve it much if at all.
-----
So overall everything is equal apart from the garbage collection/memory usage thing which tips the scales in Lua's favour.
Now, on iOS the speed can be a big issue, so knowing if there is a performance penalty that comes with that is a big deal, which I don't see covered in the article.
> Only the most naive programmers think that LOC actually means anything.
Call me naive, then. Source code, even automatically generated, will be read, and may be modified. It does count. XCode template (unlike Yacc output) is source code.
> And then we get onto secondary claims, e.g. benefits of garbage collection. (See the pretty graph)
If I got it right, the little graph is about some aspects of runtime performance, which is secondary. But you sound like you don't acknowledge the primary claim of garbage collection: that it simplifies programs.
Except that Obj-C has pretty simple memory management. It's not like comparing with c or c++. More importantly Obj-C's system makes it easy to control when collection happens so you don't get pauses during inportant interactions. Does lua offer that?
I hardly know Objective C, so I'll have to speculate.
If you can control when collection happens and memory management is simple, then it's probably some kind of RAII. That makes sharing (shallow copies) unsafe, and ultimately encourages mutable state, which is bad[1].
If there's some reference counting going on, then GC pauses will occur whenever some giant data structure goes out of scope (and its destructor is called). That's predictable, but not obvious. Plus, a proper GC (generational and incremental) will not pause often nor long, if at all. Even then, many languages give you some control over the GC, giving you most predictability back. I don't know if Lua offers that, but I'd be surprised if it doesn't: it's used for games.
tldr; LUA's GC isn't magic and for games you need to control it carefully. Even then a reference counting system is often better.
Answer excerpted:
As for the garbage collector. Use it as is first. If later you find performance issues use lua_gc to fine tune its behavior.
Some examples:
Disable the garbage collector during those times when the slow down would be a problem.
Leave the garbage collector disabled and only step it when game logic says you've got some head room on your FPS count. You could pre-tune the step size, or discover the optimal step size at runtime.
Disable the collector and perform full collection at stopping points, ie a load screen or cut scene or at turn change in a hot seat game.
You might also consider an alternative scripting language. Squirrel tries very hard to be a second generation Lua. It tries to keep all of Lua's good features, while ditching any of its design mistakes. One of the big differences between the two is squirrel uses reference counting instead of garbage collection. It turns out that reference counting can be a bit slower than garbage collection but it is very deterministic(AKA realtime).
No, it's naive to think that LOC means nothing — it might not be the most important metric for every situation, but given a reasonable definition, it certainly reflects something.
Otherwise, it would sound perfectly reasonable if I were to tell you, "OK, I'm going to give you a 500k LOC program to debug without tool support while I debug a 50 LOC one. First one to finish buys the other a car." You'd be naive to take that bet.
> Only the most naive programmers think that LOC actually means anything.
Sure but the author does actually compare a poorly written Objective-C version to an optimized (and different!) implementation in Lua and then goes on to say, hey look how much more pretty the Lua version is.
If I can accomplish something in 1 line of code that takes me 100 lines of code in another language, that matters. It also probably indicates that the more succinct language has a higher level of abstraction.
"Now, on iOS the speed can be a big issue, so knowing if there is a performance penalty that comes with that is a big deal, which I don't see covered in the article."
I completely agree. Do you have some good suggestions on how to test this?
In that case, it is very weird that one sample (Lua) specifies the bounds of the UIWindow while the other is closer to the default setup and does not specify the bounds (Objective-C).
People often complain about the verbosity of objective-c, but if you have a method that takes several parameters, how is
foo (a, b, c, d) memorable? You have to remember the order of parameters, and the function name rarely makes this obvious, so unless you use this func all the time, you end up reading the docs.
fooWithBarAndBlatAndFazAndFooz(a,b,c,d) makes the parameter ordering obvious, but is to me less readable than:
fooWithbar: a blat: b faz: c fooz: d
Which is just about as concise as you can get. Of course it would be "nice" if objective-c allowed for parameter order to not be meaningful, but that would require dictionaries of parameters, instead of what really happens, translation to a function with a fixed parameter list, which is pretty efficient.
Message passing syntax looking initially complex is a lazy reason to dump an entire system when the alternative has much worse integration and support.
You can't create an "easy to use" function if you name it foo and you name your variables a, b, c and d or blat or faz or whatever.
"Which is just about as concise as you can get. Of course it would be "nice" if objective-c allowed for parameter order to not be meaningful, but that would require dictionaries of parameters, instead of what really happens"
It's pretty easy for the compiler to look at the param name at the call site and compare it to what was declared. No dictionaries needed at run-time.
Looks very nice, and god knows it would be nice to have a next generation replacement for obj-c, but...
1. Obj-c may be verbose but XCode 4 does a lot of the heavy lifting with templates, snippets, and auto-completion, not to mention the continuous feedback on errors. It doesn't feel anywhere near as heavy as it looks. How much of that is available in LUA?
2. What does the picture look like when you want to access C api's and not just send messages? One of the most positive aspects of Obj-C is that you can use C libraries directly without either performance or code overhead - e.g. OpenGL, CoreGraphics, not to mention all manner of OSS C-libraries.
I share your reservations about the loss of XCode functionality. The verbosity of Obj-C and the Cocoa APIs is mitigated to a large degree by code completion and integrated documentation. Losing that, the visual debugger, and, presumably, the tight integration with Instruments would be a big productivity loss.
And another thing - what about debugging. Are we back to just logging?
Personally a slightly simpler syntax for the message sending layer in Objective-C just doesn't seem to give that much leverage. I'd much rather see a functional language properly integrated à la F#.
With the underscores, Wax looks a bit like PyObjC or RubyCocoa. Lua is a fun language, so I will certainly give it a try. I would love to see a Framework in MacRuby, as I think Ruby, as a true Object Oriented language, may be better suited to Cocoa/IOS development. But this is certainly a project to watch.
I must say I didn't like the authors cocksure attitude that "Most of the people dislike the syntax of Obj-C and it does slow down development".
And also, the whole discussion turned into a discussion about exactly how dynamically typed something is, and that feels quite irrelevant to what he tried to show.
Sounds like Cycript (http://cycript.org), but Cycript allows messages to be written in Objective-C syntax rather than underscore-ized, which makes using Cocoa not so painful.
First question I asked myself: What does programming the Smalltalk-style message sending interface look like? What does [dict setObject:x forKey:y]; look like?
It looks like this:
dict:setObject_forKey(x, y);
Well.. okay. I know some people dislike the message sending syntax, but the API is written for that syntax. This is verbose, but readable (if you're familiar with Cocoa):
- (NSIndexPath )tableView:(UITableView )tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath )sourceIndexPath toProposedIndexPath:(NSIndexPath )proposedIndexPath;
This, on other hand...
function tableView_targetIndexPathForMoveFromRowAtIndexPath_toProposedIndexPath(tableView, sourceIndexPath, proposedIndexPath);
...is... not winning the fight, let's say.
Second: what on earth is this:
Is this Android programming now? Do I have to fish my widgets out by hand?Anyway, this still looks pretty cool. Hooking up a garbage collected scripting language on top of Obj-C with minimal memory overhead is awesome.