Pages

Monday, September 20, 2010

I received two quick comments to my blog post from yesterday. One of which was from Parrot developer chromatic, who always makes good points and always deserves a thoughtful reply. We did have a quick back-and-forth in the comments of that post, and he wrote a blog post of his own on the topic. Given all that, I wanted to write a follow up and try to be a little bit more clear about things. First, here's a part of my original post that drew his ire in particular:

Name me one other mature, production-quality application VM or language interpreter which does not support threading. This isn't an empty set, but it's not a particularly large list either. Name me one other application VM that does not currently sport an aggressive, modern JIT.

His first comment reply, in full, is:

I can name lots of VMs which fit your "Woe is Parrot!" criteria (Python, Perl 5, Ruby, PHP). Consider also the first few years of the JVM.

These are great examples and are extremely true, in no small part because I was not nearly specific enough in the point I was trying to make. Mea Culpa.

Before going any further, I want to clearly state my thesis with this series of posts and comments. It consists of three parts:

One, Parrot isn't nearly as competitive now in the dynamic language runtime realm as it could (and maybe should) be. Two, we can increase our rate of improvement with focused objectives and more developer motivation. Three, if we do that I project Parrot to be among the top-tier of dynamic language runtime environments within the next 1-5 years.

If you don't agree with that, stop reading. Everything that I say after this point is in direct support of that statement. Where it might appear that something I say contradicts that, I've probably mistyped something.

If we look at the case of multithreading, three of the examples that chromatic listed above do have some support. Python, Perl5, and Ruby all do support some variety of threading, of some usability level. PHP is the odd man out in this regard, though the argument could easily be made that the webserver niche where PHP primarily lives really doesn't need and doesn't want threading. I won't expand on that topic here, but I will say this: PHP does not support threading, and is definitely a production-quality language interpreter in use by many companies. Point made.

In terms of JIT, I was drawing an unnecessary and mostly fictitious line between programs which have far more similarities than differences, and I did little to clarify what I meant. So, I'll throw away that entire question.

The second part of chromatic's statement is a little bit easier to respond to. The first Java Virtual Machine was released in 1995. That's 15 years ago, and even though that initial release did not stand the test of time it was temporarily considered to be the state of the art. No, Java 1.0 did not support threading as we would expect it now. But then again, in 1995 it would have been much harder to find a multicore processor capable of exploiting the scalability of threaded application. In a single-processor environment, cheap green threads were definitely a competitive and acceptable alternative to true native threading. 15 years later, multicore processors are the norm, and a threading strategy based completely on green threads is hardly acceptable by itself. This is all not to mention a dozen other subsystems in the original JVM that were immature then and would be absolutely laughable now.

Trying to compare Parrot in 2010 to Java in 1995 is both telling and depressing. Sure, it's a victory for Parrot, but not one that we should ever mention again. I'm bigger and stronger than my 9 month old son. That doesn't mean I want to get into a fist fight with him (even though I would totally win).

Let me pose a question though that should provoke a little bit of thought (and, I'm sure, more anger): Consider a world that had no Perl language. Larry Wall got busy and worked on other projects for 25 years, and never released Perl to the world. Then, in a flash of light and unicorns in 2010 he releases, from nowhere, a fully-formed Perl 5.12 interpreter as we know it today. Like Athena springing fully-formed from the head of Zeus. Would you use that Perl today?

Would you use a language like Perl 5.12 if you hadn't already been using it, if your job wasn't using because it had been using it for years, if neither you nor anybody in your company had prior expertise in it and were not demonstrably able to work miracles with it? Would you use Perl 5.12 today if there wasn't a huge preexisting community and if there wasn't the miracle of CPAN? Would you use Perl 5.12 knowing about some of it's idiosyncrasies, the weaknesses of it's default exceptions system, the uninspiring nothingness of it's default object metamodel, or the sheer fact that in 2010 you still can't define function parameters with a meaningful function signature? Is that an investment of time, energy, and maybe money that you would make considering some of the other options available today?

Now, I'm not ragging on Perl. I want to state that very clearly before chromatic buys a plane ticket, travels to Pennsylvania, and punches me in the back of the head. Perl 5 is a fine language and obviously doesn't exist in the kind of vacuum that I contemplate above. There is a huge community of Perl programmers. There are vast amounts of institutional knowledge. There is the entirety of the CPAN. There are modules like Try::Tiny, and Moose, and Method::Signatures which can be used to build some pretty impressive modern (and even "post-modern") things on top of Perl 5's default tabula rasa. On top of all that, Perl is demonstrably stable. Robust. Flexible. Usable. Coders in other languages invent terms like "Rapid Application Development" and "Rapid Prototyping" to describe what the Perl people call "a slow day at the office". People everywhere may debate the aesthetics of sigils and the multitude of operators, but nobody questions the fitness of Perl for use as a programming tool. It's competency and utility are unassailable.

Here's my point: Take a look at the Perl 5 base technology. Take a serious, hard look at it. At the very most, the stand-alone Perl 5 interpreter is flexible, but technologically unimpressive. Nothing that the base Perl interpreter provides is the jaw-dropping, nerd-orgasming state-of-the-art. I could point to a dozen performance benchmarks that pit modern Perl 5 against modern Python, Ruby, Java, and whatever else, and Perl 5 almost always comes in dead last (notice that we're not benchmarking the time it takes to write the code). That's fine. It is in the context of history, community and ecosystem that Perl 5 becomes a strong competitive force in the world of computer programming. We know that a great Perl coder can write more functionality in one line of apparent gibberish than a Java coder can write in a whole page of code. We know that the same great Perl coder can write his solution faster. It is because people have written the tools and modules, that people have identified best practices, that people can do so much in so little time, and because people have taken the time to distill down to the elegant essence of Modern Perl, that we love and use Perl.

The problem I identify in Parrot is a bootstrapping problem. Perl 5 has plenty of reasons to use it besides just performance and a technical feature set. Parrot does not. Parrot needs to provide a massive, overwhelming technological impetus for new developers to use it and to get involved with. Attracting those new developers further accelerates the pace of development, both of the core VM and the ecosystem. All these improved components, in turn, attract more people. It's a bootstrapping problem, and Parrot needs something compelling to get the cycle started.

Make a great product. Attract more minds. Develop a bigger ecosystem. Build a better product. Repeat.

In his blog post, chromatic takes exception to the word "mature" I used in the previous post. I won't use that word any more. In his comments, he also expressed a dislike of the word "enterprise". I won't use that word either. They were probably bad choices.

In his blog post, chromatic says :

His argument is that a focus on threading and a focus on JIT is necessary for enterprises or language communities to consider Parrot a useful platform.
I can see his point, and yet (as usual) I challenge the terms of the debate itself.

Do challenge it. That's not really what I said. I mentioned the two particular cases of threading and JIT as things that I think Parrot is going to need to be competitive in the world of 2010. Perl 5, and Python, and Ruby, and all sorts of other things that chromatic mentions don't have both these things, so the counter-argument appears that none of these are suitable, competitive platforms either. That's not what I said either. Keeping up with the comparison I've been trying to make between Perl 5 and Parrot, here is a summary view of what both bring to the table:

Perl 5: Reasonable, but not blockbuster performance. Huge ecosystem of modules, add-ins, tools, and applications written in Perl. Huge preexisting developer base with large amounts of institutional knowledge. Long and storied history of robustness, stability and fitness. Institutional inertia (people using Perl next year, at least partially because they have been using it this year).

Parrot: Reasonable, but not blockbuster performance. Extremely small (but growing) ecosystem of dependent projects. Extremely small (but growing) preexisting developer base. Very little history of Parrot being stable and robust, considering the huge changes that the project has to make on a regular basis to improve itself.

So if you're a developer, or a manager, a graduate student, or a hobbyist, or anybody else who has a great idea and is looking for a platform on which to implement it, which of these two would you choose? I'll give you a hint: If you reach into your pocket for a coin to flip, or reach to the shelf for a magic 8-ball to help answer the question, you probably need to re-read the choices more carefully.

JIT is a feature that Parrot can use to set itself apart from the pack, not something that's a necessary requirement to join in. JIT is a leg up that Parrot can use to gain some traction against another runtime environmnt like Perl 5, Python 3, Ruby, or PHP 5 which have so many compelling stand-apart features of their own. Stable and scalable threading is another one. And Parrot needs to be fast. When groups like Facebook are talking about compiling PHP code down to C, you know that performance is an issue in the world of dynamic languages. It is foolhardy to think Parrot can succeed (for any definition thereof) without dramatically improved performance over what it offers now.

In the end, this is really a fallacious argument anyway. I'm sure chromatic has pointed that out by now. Parrot isn't a language like Perl 5 is a language, so the two aren't really comparable in a direct way. Parrot doesn't target the same kind of audience that Perl 5 targets. Parrot targets people like the ones who make Perl 5.

The idea of porting Perl 5 to run on top of Parrot was once kicked around in a semi-serious kind of way. I don't remember what number it was exactly, I think it was something like the 5.14 release was supposed to be running happily on top of Parrot. Let's revive that discussion a little bit. What kind of feature set would Parrot need to have to make a compelling argument for the Perl 5 development team to focus their energy whole-hog on porting to Parrot instead of improving Perl 5 in place? What kinds of tools would Parrot need to provide to smooth the way? If I want to see Perl 5.98 be released on Parrot, what do we need to do to make that happen? In answering this, I'm more interested in hearing about the shortcomings of Parrot (which I can work to fix) than the shortcomings of Perl (which I will not).

Rumors have been floating around for over a year now about a complete rewrite of PHP called PHP 6. They want unicode support built-in. We have unicode support built-in. What do we need to do to make a compelling argument in favor of building a new PHP 6 language on top of Parrot? What do the PHP designers and developers need to see to be convinced that Parrot is the way to go, instead of pulling out the old C compiler and starting from scratch?

In 5 years when maybe Python and Ruby people are looking to rewrite their languages, what do we need to have on the table to convince them to use Parrot as a starting point.

These are the important questions. Nothing else really matters. If language designers and compiler developers don't use Parrot and don't want to use Parrot, we've lost.

Parrot needs honest, constructive criticism. It is neither offensive nor overly aggressive to provide it. We need to set aggressive, but realistic goals as a team. There are several planned parts of Parrot that need to be implemented, and several existing parts that need to be re-implemented. Good goals will help to inform those designs and tune those implementations. Eventually, our wildest dreams can become reality.

7 comments:

With that said, Perl 5 or Python or PHP or Ruby don't have to have Parrot ports for Parrot to meet its goals. If Parrot provides enabling technology for the next great language (and I have high expectations for Perl 6, but it could be Arc or what could have been ECMAScript 4.0), it can still succeed as a platform.

To me, a sane subset of Perl 5.12 running on Parrot would be an amazing technology, especially considering that it could take advantage of language interoperability, multiple dispatch, a better built-in object system, a decent FFI, and bytecode generation.

You're definitely right (as usual). Porting an existing language to Parrot is probably not nearly so attractive as using Parrot to create a new language. It's too bad we missed the boat on Python 3 by a few years, that would have been killer. I mention the idea of PHP 6, but who knows if that language will ever become more than good intentions and vaporware.

Every argument I've ever heard about not running a 5.xx series Perl on top of Parrot has centered around the complexity of Perl, not on the inadequacy of Parrot. If we ask ourselves "what do we need to do to make this happen?" and we act on it, we'll be much better off, even if the Perl people never attempt to make a port to Parrot.

All those features that you mention, and several others that you don't mention are all great reasons why Parrot should be thoroughly considered to be the cornerstone of any new dynamic language compiler.

i'm right in the middle of implementing something (better left unsaid) in c++. why would i ever want to do that? because the pdl version didn't run fast enough on our target hardware.

so from this user's perspective, jit is not candy. in my mind it goes like this:

1) parrot gets jit2) perl 6 or something gets good cross-platform support3) i don't have to write things in c++ any more. i can do in two weeks what has now taken me over three months (and i'm still not done).

JRuby (Ruby on the JVM) is an excellent Ruby implementation, so Ruby definitely has excellent thread and JIT support. Jython (Python on the JVM) and Groovy are nice dynamic languages on the JVM. Groovy in particular feels a lot like Perl 6.

Current builds of OpenJDK support dynamic languages with a new opcode: invokedynamic. When Java 7 is released mid-2011, a VM with good dynamic language support, excellent JIT, excellent GC, and good threading will be widely deployed. JRuby, Jython and Groovy developers are all targeting this VM.

The niche that Parrot was aimed at no longer exists. It took 15 years to be filled, but Parrot didn't get there in time to be the universal dynamic VM.

That's not a reason to abandon Parrot of course, but it's definitely important to understand why other projects might not switch to Parrot. And why developers might be more interested in hacking on OpenJDK.

My vote is that feature completeness for the language implementation (of course in the case of Parrot, that's Perl6) trumps speed.

Until Perl6 is nearly fully implemented, some potential users will be scared off by the fear that features their apps require are not implemented. Once Perl6 support is almost complete - admittedly no easy task - then emphasis could switch to speed.

Speed is crucial to the long term wide use of Parrot, but for the immediate future consider that the JVM, Ruby, PHP, Python, and Perl all made huge gains in the market when their performance was dramatically worse than it is today. They grew because they were substantially more productive than the tools they replaced. (Well, in the case of Java it was perceived as more productive, if not actually more productive.)

Oh, and as someone who uses Java professionally and has totally lost faith in it, I agree with your statement that a good Perl developer can accomplish more in an hour with one line of good code than Java developers can do with a day.

Lots of people (including me) are concerned about Oracle. The Sun deal definitely disrupted OpenJDK development, the community process and non-Java language support. Hopefully Sun opened the JDK early enough that it will survive whatever Oracle does. The Dalvik suit is a poor start.

Oracle's the main reason I'd like Parrot to flourish.

I don't understand why invokedynamic is a good reason to avoid OpenJDK. The documentation and example code isn't great, but it does allow user code to take control over method dispatch. It's just a user defined megamorphic inline cache.

Anyways, I responded to Andrew's idea of being a top-tier dynamic language VM and what the competition looks like. If the JVM were good enough that you'd consider it, that would be a sad day for Parrot indeed.