Thursday, July 26, 2007

First cut at the JVM dynamic languages metaobject protocol

You might remember I was musing about coming up with a framework library for extensible metaobject protocol to be used for dynamic language runtimes on JVM a while ago. The main thing it would give all those language runtimes is interoperability: you could write your program in mixture of JavaScript, Ruby, Python, etc. - using the best language for a particular subtask (or better yet, cherry-picking existing components regardless of their language), and still pass objects created from code in one language to code in another language, and have them all see those objects as being no different than their native objects.

Well, since talk is cheap compared to working code (and also because if I can express a concept as clearly as to have a computer execute it then I can probably make people understand it better too), I have a first version of the implementation, not yet fully complete, and first and foremost for the purposes of soliciting feedback from the community, available now.

(For the record, I blew several days of my vacation in Palma de Mallorca on getting this code into publishable state and suffered numerous scorns from my wife so far for doing so. Goes with the territory, both ways... ;-) )

The initial announcement was made on the JVM Languages group, go read the details (including where to find the code and documentation) there if you're interested.

2 comments:

Justin said...

I read your post because I just finished "the art of the metaobject protocol" (which is available online through Google Books if you don't have library access). From your announcement, looks like a decent approach to the problem. It also looks like it may be very slow. If you haven't read that book, I highly recommend it.

Attila Szegedi said...

Thanks for the recommendation -- I haven't read the book proper, but I did briefly review the spec itself that's found at http://www.lisp.org/mop/contents.html. I wasn't aware that the book is available online; thanks for the heads up - it was going to go in my next batch of orders from Amazon (and it still will), but it's nice to be able to peruse the content until it arrives (especially given that it's two more weeks until I return to my home address).

Anyway, as for being slow: I'm aware that chaining many mops together in linear fashion could degrade performance, if that's what you meant. I have an optimization for this already. (I didn't want to burden the very initial implementation with optimizations for better understandability). Namely, I think I'll allow MOPs to declare whether they claim authority over an object solely based on its class. I expect many will do -- they'll only claim authority over their native objects. Then, subchains that contain only class-based MOPs can be replaced by a different composite MOP that dispatches based by object's class to its contained MOPs.

There are other possible optimizations as well, i.e. if the language runtime can prove that certain invariants hold at a certain call site, it could ask the MOP for a reusable invocation object that can be used to perform the call without repeatedly performing much of the dynamic lookups. However, this is all subject to discussion, to see whether (a) people need this sort of additional smartness at all, and (b) they have even better ideas.