Other Lua/Objective-C bridges Compared

LuaCocoa is not the first Lua/Objective-C bridge to hit the scene. In fact there have been many others through the years. Here is short history of them and how they compare/contrast to LuaCocoa.

LuaObjective-C (Steve Dekorte)

This might be the world's first Lua/Objective-C bridge implementation. (Though maybe Richard Kiss's bridge precedes it as I am unsure of exact chronology.) It was open souce (BSD) and written by Steve Dekorte. It was written against Lua 3.1 and OpenStep 4.2 and later ported to Mac OS X circa 2001.

It covered the basic ability to call Obj-C from Lua as you would find in all subsequent bridges. From Objective-C, it introduced a way to call Lua using a NSProxy subclass called LuaProxy.

Steve Dekorte is also the author of the IO Language. As an interesting piece of trivia, Steve Dekorte gave the very first presentation at the very first Lua Workshop in 2005 hosted at Adobe. Steve's presentation was about the IO Language which might offer some interesting symbolism, insights, or irony about the Lua community.

LuaBridge (Richard Kiss)

Richard Kiss wrote a white paper and implementation which was presented at Machack 2001. The paper was titled, "Cocoa from a Scripting Language or Lua-se the Compile". The implementation was implemented against Lua 4.0 and Mac OS X. It was released under the BSD license. 

The paper and implementation covered a lot of ground, even covering subclassing Objective-C objects in Lua.

I do not know if this implementation ever saw industry use. The Google search engine has not been kind to this work as Google no longer turns up hits for the paper or project.

LuaObjCBridge (Tom McClean)

This open source (MIT) bridge has been probably the most known about and used bridge due to its use of "modern" Lua 5 and being MIT licensed. It's implementation was also quite small. It was 2 files (.h and .m) and around 2500 lines of code at its height. The bridge actually had two implementations that could be switched with a #define. The main implementation was built around the Objective-C 1.0 runtime. The other was built around NSFoundation classes. Unfortunately, I never got the Foundation side to work quite right so when Objective-C 2.0 came around and Obj-C 1.0 was deprecated, the code base could not be used on 64-bit Mac or iOS.

The LuaObjCBridge provided both a Lua side API and a Obj-C/C side API. The LuaObjCBridge itself handled most of the basic Obj-C cases, but the interface might be considered primitive. For example, to retrieve a class in Lua, you had to use a bridge function to request a class by a string name. Also, (originally) you were required to call retain/release/autorelease on the Lua side of the code because the bridge did not automatically apply Lua memory management for you. (This is a fix/redesign I later implemented in public fork which also became a proving ground for LuaCocoa.)

The LuaObjCBridge did not handle subclassing of Objective-C objects. The LuaObjCBridge also did not handle anything outside of Obj-C such as structs and functions. Hand written bindings needed to be written yourself. Gus Mueller contributed a bunch of manual bindings in a public fork he called LuaCore. I extended LuaCore in another fork with even more stuff and experimented with fancy metatables for struct access which also became another proving ground feature for LuaCocoa.

I personally consider LuaCocoa to be a spiritual successor to the LuaObjCBridge because so many ideas and lessons were drawn from it, despite the fact that there is no attempt to keep API parity and pretty much no code reuse.

Adobe Lightroom (Mark Hamburg and his team)

Lightroom is a closed source commercial product which incorporates its own Lua/Objective-C bridge. Adobe hosted the very first Lua Workshop in 2005 and Mark Hamburg gave a nice talk about how they used Lua in Lightroom in a presentation entitled "It's All Glue". 

One area that the presentation gave some focus to which is not present in any other known Lua/Objective-C bridges is issues dealing with getting performance with concurrency. Lightroom also has a cool in-app debugger. In summary, it seems to be a very cool implementation, but unfortunately it is closed source so none of us can touch it.

iPhone Wax (Corey Johnson)

Wax is a relative newcomer to the scene. It has made a splash by being an iPhone centric Lua/Objective-C bridge.

But unlike the other bridges listed here, even though Wax did a first public release earlier than LuaCocoa, the ideas behind LuaCocoa had already been pretty much designed and established by the time Wax hit the scene so it didn't really have any influence in LuaCocoa's design.

Since Wax is also a Lua 5/Obj-C 2 based implementation, I often get asked about the differences between Wax and LuaCocoa. There are many.

The most significant difference between LuaCocoa and Wax is that Wax is iOS specific and does bindings similar to other Lua/Obj-C bridges. This means manual handwritten bindings are required for any areas that don't have Obj-C introspection. In contrast, LuaCocoa uses BridgeSupport and libffi to provide full automatic bridging to the ugly areas of Cocoa like structs, C functions, booleans, constants, enums, etc.

As a consequence, LuaCocoa for now is Mac centric instead of iOS centric. This can be addressed as JSCocoa has already solved the problem (but LuaCocoa needs some porting to replace NSXMLDocument which is not currently available on iOS.). LuaCocoa has paid a great deal of attention to details like big-endian/little-endian, 32-bit/64-bit, and Obj-C garbage-collection/non-garbage collection which are Mac things but potentially could work on iOS. Wax on the other hand would have to have to think about these things if they wanted to do a first class port to Mac.

I think there are also philosophical differences. I think Wax likes to auto-convert tables and NSArrays/NSDictionaries. LuaCocoa tries to avoid conversion when possible and instead provide special metatables for NSArrays/NSDictionaries so you can use them like Lua tables.

Wax also doesn't seem to give much attention to the idea of writing stuff in Obj-C. There is no C/Obj-C API that I've seen in Wax so the impression I have is you write your Wax apps in 100% Lua. LuaCocoa can do 100% Lua, but it is also designed with the hybrid Obj-C/Lua integration paradigm in mind and includes a formal Obj-C/C API.

I also think Wax currently has a few technical limitations. For example, I believe Wax will break if you subclass and override a method in Lua and then subclass it and override the method again. This comment is not intended to disparage Wax because this is actually a tough problem to solve in Objective-C. Since LuaCocoa also incorporates libffi into its implementation, LuaCocoa has additional avenues to solve the problem.

But for what Wax currently lacks in general scalable solutions to bridging, it has advantages in simplicity and performance. In the near term, Wax will probably continue to be the choice for bridging Cocoa on iOS. LuaCocoa will conversely be focused on bringing complete/full bridging solutions which will make it more suitable for Mac. In the long term, Wax seems interested in utilizing BridgeSupport, and LuaCocoa is interested in supporting iOS, so who knows what will happen.

Additional Acknowledgements:

As you can see, LuaCocoa was not written in a void. It has been a very long road and I wish to give my thanks to the many people I've encountered on the way who helped provide insights on how to build this thing.

- Tom McClean for LuaObjCBridge, much of which was the starting point for LuaCocoa

- Laurent Sansonetti for sitting down with me one WWDC afternoon and walking me through how RubyCocoa and MacRuby use BridgeSupport and how I should approach the problem

- Bill Bumgarner for his talks on PyObjC and BridgeSupport over the years

Greg Parker for his help at WWDC and the Obj-C mailing list

- Steve Dekorte for his Lua/Objective-C bridge and sharing what he could find and remember with me

- Richard Kiss for his white paper on his Lua/Objective-C bridge and also digging up what he could find for me

- Dan Treiman for letting me bounce ideas off him about retain/release/garbage collection

- Gus Mueller for his patches to LuaObjCBridge which are ideas I incorporated into my own patches of LuaObjCBridge and are undoubtedly seeds of ideas in LuaCocoa

- Patrick Geiller for writing JSCocoa and being the first to write something using BridgeSupport that somebody like me could kind of decipher

And everybody else I may have missed, thank you!

Copyright © PlayControl Software, LLC