My current Perl Ironman Challenge status is: My Ironman Badge

Tuesday, August 11, 2009

Working with Rakudo and Parrot

So after pmichaud had a call for applications for Rakudo, I came to a small epiphany that perhaps I should work on a naive port of POE to Rakudo. So this past weekend came and I started to do a little investigative work on what it would take to do POE on Rakudo. The first step is to get the core loop running. In Perl5 terms this means that select(2) needs to exist. In Perl5 world, select() is for the most part a C equivalent. There is another version of select() but that doesn't concern us.

Anyhow, select() let's us do synchronous multiplexing of IO across multiple filedescriptors. This is how POE does it's magic. As things come back from select() placed into the things-to-watch queue via POE::Kernel->select_read and select_write, those are placed into the Queue and get mingled in with all of the rest of the events that need to be dispatched. This is an obviously very simplified explanation.

So the first thing I did was go into various IRC channels to ask some very pertinent questions such as where is select() implemented? I dug around in the classes defined by Rakudo but could not find a definition of select. But someone pointed me in a couple of different directions and referred me to a couple of different people that were interested in the same topic.

Ultimately, it came down to this. I took a look-see into the Parrot source and found that, no, select was not implemented as a generic plain-old C-like call you could make. Instead, each of the Parrot socket objects have a method, poll, that will return to do it's status, if any. Internally, it uses select(2) to do this for the unixy source file anyhow.

Unfortunately, Rakudo has no parallel in the IO classes because it was decided to /remove/ select(2) (including the other version) from the spec. Apparently, people wanted to roll that up into the concurrency layer that doesn't really exist yet, because it is pretty instrumental in event loops. In the mean time, I'm for the most part stuck. Sure I could do a IO::Select port to Rakudo (and had planned to do just that), but I would have to implement it using the non-portable Q:PIR construct and call down to the Parrot sockets methods. I'd have to learn PIR, ontop of any augmentation to Perl6 that I barely know. Plus, it would only work on the Rakudo implementation due to the use of inline PIR.

With that said, I decided to stop looking at doing a naive port until the IO layer is fleshed out a bit more and I have safer abstractions from which I can do simple things like use a select-like idiom that is extremely common for writing socket based network servers. The Parrot and the Rakudo projects have come a very long way in their years of development, but I just don't have the time to be writing core infrastructure pieces and also maintain and further develop my other modules. I really understand the catch-22 that Rakudo and Perl6 in general have when it comes to specs vs implementations, but I can't really do much to fix it without investing a lot of time and effort coming up to speed on the thoughts behind a lot of the decisions (such as removing select()).

I tried to approach this project from the perspective of bringing current Perl5 tools forward to the Perl6 world. That means attempting a naive, get it running, port that doesn't bother with any of the new fancy idioms. At most, I wanted to adjust the sigils, and do some light source filtering by hand to cover the large breakages. Document what I found for other projects looking to do the same. And go from there. I couldn't really get to square one because of the specification vs. implementation situation.

So while I certainly sympathize with these projects, I just don't feel they are ready yet for the casual developer (eg. me) to even take the first steps. I would like to at least revisit the issue for the Rakudo Star release, however, given more of the IO layer has been implemented and I can do what I want without resorting to platform specific inline assembly.

Let the flames begin :-/

1 comment:

  1. I was recently (last week) discussing exactly this topic with uri. You're right - it's a touchy subject.

    IO is critical to the usability of *any* programming language. It's also something that, more or less, has long-standing, well-vetted and well-understood semantics and conventions.

    If Rakudo or even Parrot will change those conventions, it could be a fatal mistake.

    However, it seems that a lot of us believe that there must be a better way - a simpler set of rules that could provide scalability and simplicity... I'm not smart enough to figure that out, but it's nice to dream, right?

    Well, it's nice to dream, but in the meantime there's work to be done - and without stable support for asynchronous IO, I'll just have to wait.

    That said, I have enough confidence in the authors of both Parrot and Rakudo that they will deliver something interesting and good - eventually.