C: Portable Macro Assembler

This post’ll be all over the map — there has been a lot of traffic on this subject. This stuff is particularly interesting to me. I have been banging out object oriented code for more than 20 years in a variety of languages — Obj-C since 1989. Thinking about this stuff is my day job, too. That rocks. Makes me really happy.

Daniel Jalkut recently wrote a post entitled “C is the New Assembly“. I’m not entirely sure what rock Daniel has been under for the last 20 years, but I’m pretty sure that C has always been considered to be little more than a portable macro assembly language by many folk for a long long time. I certainly remember such analogies being made when I first learned C.

Well, when I first learned C in a non-perverse environment. I learned C writing hypercard plug-ins. Yes, I learned C writing plug-ins for an application that only offered a Pascal API in an environment where pointers were often really pointers to pointers (handles) where the pointer would occasionally move out from under you. Fortunately, I was too ignorant to know that I was learning C the hard way.

But I digress. C has always been in the role of the “fallback for performance reasons” solution as soon as developers started writing significant bodies of code in other languages. Perl based CGI always had random modules written in C. Java has always had a painful native interface. C++ developers have long written chunks of code in C (though that has grown less common over time). Even the scripting languages all have supported dynamic loading from the beginning that has always been used for both accessing native functionality and for implementing “performance critical” stuff in native C.

Update: Daniel commented on this post:

I compare C to assembly completely apart from its rather coincidental technical approximations to assembly. I meant it on a much higher level. On a level where I hope in 10 years to be saying “Ruby Is The New Assembly.” It’s a coincidence that C is a relatively good alternative to assembler for producing highly optimized code. It’s still the case that C programmers “drop into assembler” when necessary to squeeze extra performance out of a particular platform.

Python is “close enough to C” that I suspect somebody in 5 or 10 years could say “Python Is The New C” and have a bunch of critics chime in “it’s been the new C for 15 years!” Well, not in my universe it hasn’t.

Actually, I think C developers dropped into assembly to squeeze out extra performance (or do stuff that wasn’t possible in C) more often in the past than they do now. The reasons are two fold:

First, fewer developers can effectively develop in assembly anymore. Not because programmers are dumber these days, but because writing assembly on modern CPUs is One Hell Of A Lot Harder than it was back in the 6502 or 68000 days. As well, modern codebases tend to be more portable even when only targeted to one manufaturer’s CPU — programming for a G3 vs. a G4 vs. a G5 could require very different low level code, if you were trying to eek out every last bit of performance.

Secondly, optimizing compilers have improved by leaps and bounds over the years. In particular, the optimizing part of the compilers are truly amazing chunks of linear algebra that do all kinds of subexpression optimization, execution reordering, and all kinds of relatively non-obvious tricks to make the code go really fast on modern processors.

Rare is the programmer that can effectively write assembly code on a modern CPU. Rarer still is the programmer that can write assembly code that performs better than that generated by a good compiler.

I agree with Daniel. I sincerely hope that we get to the point where “drop into primitive python” is an answer to various problems we are having in our highly abstracted programming environments of the future.

To get there, I think we will first have to get past treating software development like a specialized word processing exercise.

Daniel pointed to a post by Jesper called Take it to the Bridge that discusses a podcast with Gruber where he discusses the bridging technologies in Leopard.

Daniel said (which I ran into before I saw Jesper’s post, so I’ll respond to it here prior to Jesper’s post because, well, that was how my brain wen down this particular path):

He suggests that a typical developer will write everything in Ruby or Python, and then do performance testing. Anything that needs a speed-up can be redone in Objective-C. You know, that “slow” dynamic variant of C :)

This analysis is foreboding, because it’s exactly what programmers have always done when they switched to a higher level language.

Yup. It is exactly what programmers have always done. Lots of Objective-C programs have C or C++ engines under the hood for the “performance sensitive” parts. I put that in quotes because, more often than not, the optimization wasn’t necessary — it just added complexity for little or no actual performance benefit. Not always the case, but more common than anyone would care to admit.

And it is no different with Python or Ruby based GUI apps. Native code is commonly used for the performance sensitive parts. Of course, with PyObjC or RubyCocoa, much of the optimization-in-native-language has already been done because, after all, the python and ruby in said programs are typically just gluing together already existing native language frameworks.

If you think about it, a Cocoa app that is using — say — Core Data and Quartz Composer is consuming very little CPU in actual developer authored code. Most of the CPU time is spent in QC or CD either pushing data around or rendering graphics in 3D; 100s of thousands of lines of code being driven by relatively few lines of custom code found in the project.

Jesper says:

So at the end of the day, writing Ruby Cocoa apps is going to be a whole lot better and easier than writing Java Cocoa apps

Actually, that is the case now that RubyCocoa has evolved significantly in the last year and has been the case with Python via PyObjC for many years.

The problem with the Java Bridge is that it tries to make the Cocoa API look like a Java API. The end result is an API that doesn’t look like Cocoa and doesn’t feel natural to a Java programmer.

The RubyCocoa and PyObjC bridges don’t try to “mogrify” Cocoa into Ruby-esque or Pythonic APIs beyond a slightly syntactic adjustment to take the Objective-C interleaved method name and arguments style dispatch and turn it into the much more common call-it-like-a-function style dispatch. (No, for the last time, Objective-C does not have “named parameters”. Never did.)

As a result, you pretty much always know when you are message across the bridge except for really simple things where it generally doesn’t matter that much.

Jesper goes on to conclude:

Writing Java-Cocoa with some Objective-C is like trying to write some parts of your book in BritishInternational English and some parts in US English. Same everything, you just wrote ‘old chap’ in one chapter and ‘homeboy’ in the next. Writing Ruby-Cocoa with some Objective-C is like writing half your book in Swedish and half your book in English. The two are noticeably different, and Swedish kicks English’s ass in a variety of places, so you can actually play on their respective strengths.

This isn’t true. Or, at least, it is backwards.

Objective-C, Python and Ruby all use very similar class models. And all of them are quite a bit different than Java. Whereas Java is naturally statically typed and bound, the other three languages are naturally dynamic. Java’s introspection and dynamic dispatch is a complete pain in the ass. Introspection and dynamic dispatch come very naturally to the other three languages and are quite often leveraged across large bodies of code (Cocoa, Twisted, and Ruby on Rails all come immediately to mind).

As for bridging, connecting Python and Ruby to Objective-C is a much more natural fit than Java. Python and Ruby both allow for easy on the fly class definitions and, though the API is a bit primitive, so does Objective-C.

Because of the way Java works, you can’t really dynamically create class definitions on the fly without either generating byte code on the fly or calling out to the Java compiler. Even once you do, the impedance mismatch between the Java class library(ies) and Objective-C are downright painful. Hell, String is declared final — cannot be subclassed — and, as a result, bridging from NSString to java.lang.String pretty much requires making copies across the bridge. Even if copies weren’t really expensive, you then have to keep track of the various instances on either said for purposes of preserving identity. I could go on. And on. To summarize: Ouch.

From the comments on one of the posts, Mark Grimes says:

The script bridges also aren’t uniform. E.g. RubyCocoa and RubyObjC have different performance metrics when crossing the bridge. The former requires implementation constraints that dictate not crossing the bridge too often. But alas, I agree with Scott, the popularity of these languages along with the abandonment of the Java bridge will get people new to OSX on-board until they discover how much more versatile ObjC is.

Then what? You package the app and the interpreter as a part of an application bundle? Ewww.

First, RubyCocoa has been fixed. It is much more efficient now, using libffi like PyObjC to achieve pretty damned good performance across the bridge.

Objective-C more versatile? I’m not really sure that is a fair assessment. Each language has strengths and weaknesses. More importantly, each has access to sets of technologies that are way beyond anything available in other languages.

For example, whenever I write a Cocoa application that has to do heavy network communications, I immediately turn to Python via PyObjC for the bulk of the implementation. Why? Because I can use Twisted, which is — hands down — the best damned network programming toolkit around (steep learning curve, amazing framework — think of it as the AppKit for Networking). Nothing available in Objective-C can touch it (without writing a ton of code anyway).

Finally, packaging the interpreter and your custom modules into the app wrapper really isn’t that big of deal. At least, it hasn’t been a problem for the handful of commercial applications shipping today that are implemented using Python, Cocoa, and PyObjC. As a matter of fact, you would never know that they were written in Python unless you went poking about the app wrapper. Even the launch times aren’t noticeably slower, if various optimizations are employed (especially with modern machines). Size really isn’t an issue given that most polished commercial apps will include megabyte upon megabyte of artwork, image laden documentation, sample material, and other multimedia capabilities.

Something to keep in mind: Bridging to Cocoa from scripting languages is nothing new. This is a very mature field of technology. PyObjC has been around since 1994, being used scientific, financial and commercial applications throughout its 13 year history. There were scripting bridges before PyObjC (I wrote a fairly full featured Tcl bridge at one point, for example) and, obviously, several others that were created after.

And it hasn’t just been for casual hacking. There are people who rely upon said bridging technologies every day. If the bridges don’t work or can’t be relied upon in the customer’s hands, it would be a major and often costly problem!

Jens Alfke commented:

I haven’t tried to develop a GUI app in a scripting language (Ruby or Python) yet, though I’ve used both for web apps, and have done tons of GUI development in Obj-C, Java and C++.

One problem I suspect will bite people using scripting-language bridges is the lack of type checking. Yes, I’ve read all the propaganda about “duck typing” and how the lack of type checking makes you more Agile. For small quickie bits of code, I tend to agree. However, in a full app, type errors will bite you in the ass. A lot.

In practice, type errors don’t really cause any more problems with GUI apps written in scripting languages than they do with carefully compile-time type checked Objective-C Cocoa apps. Unless, of course, you try to treat the untyped language like a strongly typed language or vice-versa. It is really a question of architecture — don’t try to write Python code that tries to manage types like a C++ program!

There will still be type errors, but they are mostly caused by various dynamic behaviors such as incorrectly ripping apart an NSNotification’s userInfo or improperly traversing the DOM tree of some XML gunk or the like.

I have worked on and have worked with developers working on some pretty good sized Cocoa apps that have significant chunks implemented in Python via PyObjC. Type errors really weren’t any more or less of a problem than with compiled Objective-C.

And, yes, I completely agree that automated testing of GUI apps is nearly impossible. Scripted based GUI development does offer one significant advantage. In particular, Python and Ruby make it quite natural to “dynamically load” additional functionality, both have easy to use unit testing facilities, and both languages make it easy to inject functionality into existing code.

As a result, you can do some fun in-context unit testing in conjunction with the user based testing. Or you can set up testing such that the user can play around with the app and then hit a button to have a bit of testing code injected that can verify the internal state of the app.

All stuff that can be done in non-scripted GUI apps. No question about it. It just somehow seems easier and more natural in Python and Ruby. Maybe it is just me.

Bret says something really funny:

Uncompiled languages will never take off for commercial app development. Here’s why: you are shipping your source code. OSS, server stuff, yeah – but not desktop apps the way they are defined now.

The folks at Goombah, Checkout, and Talking Panda have already proven you wrong. All three are shipping commercial applications implemented using PyObjC.

Pixar, Sandia Labs, several trading houses, and a number of other software development shops are all using PyObjC or RubyCocoa every day to help build their products, some of which include shipping said scripting bridges as a part of their product suite.

Jim says:

You youngsters will eventually “discover” Common Lisp.

Ya know… there is a Lisp to Objective-C bridge….



24 Responses to “C: Portable Macro Assembler”

  1. Daniel Jalkut says:

    This a great summary of the conversation thus far, and with some interesting, intelligent commentary adding to the dscussion on our various blogs. I was wondering why nobody had yet taken to task the notion that interpreted languages couldn’t compete performance-wise with compiled code. Obviously, everything is relative when it comes to performance.

    Forgive me for focusing in on … umm… the part of your post that paints me as some kind of technological neanderthal. For some reason my (sensational, I admit) use of the phrase “C Is The New Assembly” seems to have gotten everybody excited about pointing out how close C is to assembly, and how “so 5 minutes ago” this analysis is. Maybe it is? But most people I know still program in C and consider assembler for optimization. The fact that this scenario exists means that C and assembler have *not been considered interchangeable* by most programmers over the past several years.

    I tried to clarify my position in my own blog’s comments, but I’ll roughly reiterate it here: I compare C to assembly completely apart from its rather coincidental technical approximations to assembly. I meant it on a much higher level. On a level where I hope in 10 years to be saying “Ruby Is The New Assembly.” It’s a coincidence that C is a relatively good alternative to assembler for producing highly optimized code. It’s still the case that C programmers “drop into assembler” when necessary to squeeze extra performance out of a particular platform.

    Python is “close enough to C” that I suspect somebody in 5 or 10 years could say “Python Is The New C” and have a bunch of critics chime in “it’s been the new C for 15 years!” Well, not in my universe it hasn’t.

  2. Jesper says:

    Yes, Ruby and Objective-C have similar class models; what I’d use Ruby for instead of Objective-C doesn’t have anything to do with class models as such. Or should I say, similar class models is what allows great bridging, but there are obviously great differences between Ruby and Objective-C that makes bridging worthwhile.

    I stand behind what I said about ‘old chap’ (Java) and ‘homeboy’ (Objective-C). Java is Objective-C’s less dynamic brethren, so it’s a terrible language to bridge to for that reason. I’ve specified what I mean a little more in The Planks in the Bridge: nothing new for folks like bbum, but I think it’s a good assessment that a) the new bridges is not your father’s Java bridge and that b) holy shit, Apple is not only improving but integrating these by inventing some common ground. I’m betting that the ground work Apple does is going to make this a rising-tide situation where other bridges will prosper as they adapt to the new de-facto bridge template.

  3. Daniel Jalkut says:

    Thanks for updating the post with your responses to my comment. I think I may have slightly overreacted based on a sensitivity I have to the way people have been zeroing in on the “C as intrinsically portable assembler” factor.

    Anyway your original point is probably true, that when it comes to the notion of programming an app (or anything, relally) in a scripting language, have been living under a rock for … well, my whole career.

    So the point I meant to make on my blog was really aimed at people stuck in my mode of thinking. if you thought life essentially consists of programming in a C-ish language and optimizing when necessary with assembler, then it’s time to update that thinking.

    And you may well be right that fine-tuning in assembly is outdated. I know people who claim to do it, but for all I know they’re faking it :) I haven’t hand-optimized anything in assembler for many years.

  4. David Herren says:

    I certainly am in no position to argue with you on any of this, but I do have to say the only app I am aware of that was written in Python using a bridge is the worst piece of shit and most unstable app I’ve ever installed: BitTorrent. THing crashed constantly, would fail to connect, generated error messages every few minutes, etc. From a layman’s perspective, if that’s what we have to look forward to in app-land, it’s not a very pretty picture…

  5. bbum says:

    The BitTorrent client is, by no means, a commercial app nor of commercial quality. The apps I’m talking about — see the links in the post — are definitely of commercial quality.

  6. Mark Grimes says:

    I agree with you about twisted, as a user looking from the outside-in, I adore hellanzb. :) While I’ve not developed in Python beyond using nodebox for implementing a call graph visualization of a language lex to see which orphan nodes represented areas I can prune out of a project that I was handed with no unit tests in place… I’m pretty sold on specific examples of using Python as the tool, even if the language confounds me (compared to Ruby).

    Erroring on the side of caution, I do wonder how Apple will deal with interpreter backwards compatibility, which at least as far as I’ve read and experienced in run time in a few places, has been a problem in the past with Python alone across dot revs. This doesn’t mean I’m not willing to experiment and gladly be proved wrong.

    I’m relieved RubyCocoa has been fixed — it will be a nice prototyping solution, maybe even production in some areas where I can’t find an easy way get what I want out of Foundation. When I refer to ObjC versatility however, I am refering largely to it being a superset of C which if you look in xml space e.g. NSXML supports but a fraction of what libxml2 offers, but you could use either without crazy bridge talk… maybe Python XML support is that good and my statement is misfounded. Sometimes it’s worth playing devil’s advocate to all this *Cocoa bridge talk like it’s the second coming — far from being dismissive though, that just ensures you have no room to complain :)

  7. Koen Bok says:

    Hi, I am the one of the developers of Checkout.

    For us one of the great things of developing in PyObjC has been that you can mostly choose multiple libraries to solve your problems. Most of the time we investigate both options (CoreData/SQLAlchemy, NSURLStuff/URLLib, NSArchive/cPickle) and in a lot of cases the python options have more capabilities, are more mature, have a bigger user base and sometimes are even faster too if there is a c implementation. Also, from what I hear unit testing in python is way easier then in objc. For a financial application as we make that is crucial.

    Plus, sometimes we do find bugs/oddities in Cocoa (cough – NSNumberFormatter with behaviour 10_4 – cough) and by using replacing small parts in those classes with their python counteparts we save ourselves lots of work. (Although it still took me 3 weeks ;-))

    We are also waiting for someone to fix psyco for the intel mac. That should also get us a significant speed boost, although checkout is already pretty snappy, we think. Now we don’t have a very CPU intensive application, but the parts where it is needed we do use c/objc either through python extensions or by importing objc frameworks.

    Shipping an application in python can indeed be somewhat tricky because it’s not that hard to reveal parts of the source, but we did not yet found that to be a problem. Our app is protected by copyright law, and as long as we can take legal action we think we are ok.

  8. Andrew Shebanow says:

    Great post, and great comments as well. I’m really enjoying this whole conversation thread. I’ve posted my own thoughts on these issues and how they interact with the trend towards multicore and general purpose GPUs on my blog, and I’d love to hear what people think.

  9. Drew McCormack says:

    Just out of interest, is that Tcl bridge available anywhere? I’m a python programmer, but we have a bit of Tcl at work, so it could come in handy.
    If not, have you heard any plans to use the Leo stuff to make a Tcl bridge?

    Drew

  10. bbum says:

    Nope — the Tcl bridge isn’t available. It was written against Object (not NSObject) and was a prime example of massive over engineering. I ended up writing my own language for describing how to bridge certain kinds of methods. And, instead of using a parser-in-a-box like YACC or bison, I wrote my own recursive descent parser with the added twist that it could bifurcate the parse at any level so I could save a few characters in the data file by allowing any given keyword to actually be multiple keywords while still allowing per-keyword configuration.

    Yeah. It was stupid. Classic situation of an engineer solving a problem that no one had simply because the actual problem at hand was just too damned boring and straightforward.

  11. michael-mccracken.net » “New Assembly?” - native apps in Python and Ruby? says:

    [...] A couple days ago, Daniel Jalkut wrote a quick note wondering if the future is writing native desktop apps in languages like Python or Ruby, dropping down into C/Obj-C only for performance reasons. It’s been an interesting thread since then, in comments and other posts. Notably, today Bill Bumgarner responded with a long and informative ramble about how the dynamic language future is already here. [...]

  12. Scott Stevenson says:

    In terms of typelessness, I don’t think the point is runtime safety — at least not for me. Having type information right there inline is useful to the reader. Unit tests can’t help you read code. No one really seems to measure code legibility, but it’s a huge factor in productivity.

    You could easily write Objective-C apps without very little type information. Just make everything an id, and it doesn’t matter much at runtime anyway. But no one does that because type information is useful. It’s like a comment that the compiler understands.

    The fact that I don’t have that readily available to me in scripting languagues is a huge drawback. I really like Ruby — it’s a very cool language — but neither it nor python are just higher-level versions of Objective-C in the way C is (more or less) to assembly. They’re different.

  13. Travis Cripps says:

    Bill,

    Thanks for the insights you shared in your article. I thoroughly enjoyed it.

  14. Tim says:

    … and OCAML is the new C!
    http://www.ocaml-tutorial.org

  15. Stephane says:

    I’m not sure Bret’s comment was funny because of shipping app really shipping with source code. It’s funny because you can reverse engineer Obj-C app pretty easily. And with new things such as bindings, it’s even worse.

  16. bbum says:

    Worse? Define “worse”.

    I have yet to find an app with a user interface where being able to open the NIBs or reverse engineer the bindings reveals anything that could be considered Super Top Secret Intellectual Property By Which Your Competitors Could Eat Your Lunch.

    Having the source code for some subset of the app, or even the whole app, really isn’t that much different beyond giving pirates the ability to kill off your licensing code (which could be left in compiled code and be as secure as it is today).

    Sure, someone could reskin your business logic and try to sell your work, but I’d be surprised if they weren’t busted in seconds in this modern Internet police state.

  17. Ken Anderson says:

    > C++ developers have long written chunks of code in C

    Do you really think so? I’m wondering why anyone would do that. Theoretically, C++ should always be faster than C. Bjarne Stroustrup originally said that he wrote “C with classes” to eek more performance out of a C compiler by using inline functions and effectively making it easier (and faster) to write more efficient code.

    Ken

  18. bbum says:

    The C++ runtime is fast, yes. But there is a certain amount of memory overhead implied, be it just due to architecture (all that generalization), the various additional libraries that are dragged in, or memory management fun stuff.

    For really small, tight, fast code written against what is typically a C layer on the system, C is still the tool of choice.

    But, yes, certainly, C++ can be very very fast, too. Much faster than Objective-C, certainly, but at a significant potential cost simply from the sheer volume of code that might have to be written to get the same thing done, depending on architecture.

  19. Kevin Walzer says:

    Too bad the Tcl bridge isn’t available anymore. I’m a Tcl programmer who spends massive amounts of time tweaking my Tk GUI’s to look native under Aqua. I’ve tried very hard to get my head around Python via its Tkinter bindings, in hopes of leveraging that into PyObjC, but I always wind up going back to Tcl because it does what I need to. My problem is that I’m not a C programmer (in any real sense), so hacking Tcl at its C API level to bridge to Cocoa is beyond my skills.

  20. Stephan Cleaves says:

    So if someone with Objective-C, Cocoa, and Java experience wanted to delve into either Python or Ruby which is the best to pursue? Python seems to have more history and therefore I am guessing is more mature and has better resources for the learner. Does Ruby challenge Python in some way that would make it a more appealing choice for someone just starting out? I’m not really interested to try to learn both, I find I have trouble keeping languages known if I’m not using them regularly.

  21. bbum (waiting for panic'd machine to reboot) says:

    Ruby and Python are fairly equivalent in terms of features and approach to development. While fans of either language will quibble with this statement, it is true “in the large” — in comparison to the laundry list of languages out there. Both languages have their strengths and weaknesses.

    So, it is matter of personal choice. Personally, I would recommend Python for a number of reasons. Keeping in mind that I have actively written Python code since at least 1993 or so, this list is not entirely without bias. However, I have learned Ruby and do occasionally write Ruby code. So far, I haven’t found anything about Ruby that is compelling enough for me to choose Ruby over Python when given a choice. Without history, it really would be a toss up for all but a handful of reasons.

    - Python is easier to learn. The whole point of the language was simplistic readability. Python is often used as a teaching language for non comp-sci folks because of this. And there are some awesome tutorials out there — http://diveintopython.org/. On the flip side, Ruby often makes comp-sci types jiggle with glee. Blocks! Whee! (Seriously — Ruby seems to be a more “serious” language… and, yes, I’m mocking it for being more “serious” because, frankly, I find all the damned punctuation and side effects to be just plain bloody annoying).

    - Python has Twisted. If you are ever going to do network app development or do any kind of network communications stuff, nothing beats Twisted. A bit of an iniital learning curve, but just flat out amazing after that.

    - While RubyCocoa has evolved significantly in the last year, PyObjC is more mature and provides better support for distributing production applications at this time. RubyCocoa is making great strides in this area and I suspect it will catch up sometime in the near future. Mostly. Ruby 1.x has an unfortunate threading model that causes hell, but it isn’t a total showstopper and it will be fixed in 2.0.

    - if you want to write a web app, Ruby On Rails is the crack of web programming. Very very easy to get a site up and running and you can do some impressive stuff with it. But RoR isn’t really designed to produce large scale modular or maintainable sites.

  22. Alan Little says:

    Mark Grimes:

    > maybe Python XML support is that good …

    actually, yes it is. ElementTree is a very nice simple, “pythonic” xml library for most of what normal folks need to do on an everyday basis. In its cElementTree version it’s well fast, and it’s part of the standard libraries from python 2.5 onwards. If you need to get more down’n'dirty there are perfectly decent libxml2 bindings available.

    I know you were really making up a hypothetical example and random, and whether python actually happens to be good at that particular thing wasn’t the point you were making – but python does in fact happen to be good at that particular thing

  23. Johann Visagie says:

    Which Lisp/Objective-C bridge are you referring to? The one that ships with OpenMCL?

  24. Jordan Hubbard says:

    Regarding the requests to bridge Tcl in the same way that Python and Ruby are being done in 10.5… It’s obviously a little late to consider this for Leopard, but if there’s sufficient interest, I think it’s something we could look into for the future (perhaps even doing it “outside the firewall”, as the RubyCocoa work is being done, so that people don’t have to wait until 10.6 to see it). I’d be interested in hearing how desirable this is since, perhaps erroneously, Tcl is often seen as a dead language and doesn’t get the same amount of respect that the newer scripting languages do. I’m a big fan of Tcl myself since it’s saved my butt more than a few times (it’s very easy to embed and doesn’t have a syntax that makes me Lua all over my keyboard) so I’d perhaps even be willing to take a run at doing this myself…

Leave a Reply

Line and paragraph breaks automatic.
XHTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>