with Doug Beaver and Jennifer Buckendorff
(Late 1999)While fortune may come to Damian Conway through his well-crafted guidebook Object Oriented Perl, fame arrived in 1999 via the oddly-named Larry Wall Award for Practical Utility. Having won the year before for two modules – Getopt::Declare (which builds command-line argument parsers from usage descriptions) and Lingua::EN::Inflect (which can automatically inflect singular nouns and verbs into their plural forms) – this year Conway walked away with the honor because of the aptly-titled and very charming Coy.pm. What's apparent in this interview is Conway's respect and enjoyment of the Perl programming language – a playfulness that yielded award-winning results as well as a refreshing take on object-oriented programming. Amazon.com's Doug Beaver and Jennifer Buckendorff chatted with Conway about code and haiku.
Can you tell us a bit about your Coy.pm module, which won the 1999 Larry Wall Award for Practical Utility?
Coy is a little bit of whimsy, built on some fairly solid computer science. Put simply, it replaces any error messages a program generates with an English haiku. For example, if you divide a number by zero in Perl you get this:
Illegal division by zero at demo.pl line 4.That's typical of error messages: curt, uncompromising, and accusatory. It's no wonder programming is stressful. But if you add the Coy module to your program, the same mistake produces this instead:
A songbird above a temple. Con Wei dying beside a river.The Seventh Sage's commentary...
Illegal division by zero ("The Way of demo.pl": line 4)
You still get the same information, but packaged in a much more harmonious and relaxing way! Coy even has subroutines that attempt to relate the subject of the haiku to the error message itself (though the relationship is often very oblique, as in the above example).
Coy generates a new and different haiku every time an error is detected, so the error messages are always fresh, interesting, and unique. And that actually seems to help people pay more attention to them.
How did you hatch the idea?
The idea of using haiku as error messages has been around for some time now. I first came across it in an issue of Salon magazine. Last year they ran a contest to find the best error message haiku. The winners were good, but they weren't really haiku; they were too direct and cynical, and not as evocative as the tradition form – more like senryu, actually.
I had been playing around with computer-generated poetry since my undergrad days and I thought I could do better. So I hooked together a syllable counter, a cross-linked database of Japanese imagery, and some grammatical templates for English.
The generator selects a template and grabs words from the database using the cross-linkages to keep sentences coherent – there's no nonsense like "The bird roars through an arrow" because the database knows that birds only "fly," "nest," "sing," etc. and that those actions occur only in certain contexts: "in the sky," "in a tree," "at dawn," and so forth. Meanwhile, the syllable counter keeps the poem faithful to the 5-7-5 format by backtracking the selections whenever it detects imminent "syllable overflow."
Are there any tricks planned for next year's Open Source/Perl conference?
If you follow the trend [of the last two submissions that won the award], I'm going to need at least four papers in 2000, one of which does something linguistically very magical. I already have something suitable in mind, but I'm not going to telegraph my punches just yet.
Meanwhile, I want to continue to explore how well haiku fit into the Perl world view (and vice versa). To that end, Elaine Ashton, Mark- Jason Dominus, and I will be running a haiku competition leading up to the next Perl Conference. The competition will be known as the "CHI," which is short for
Camelinguistic
Heptadecasyllable
IdeogenyWe ran a similar event ad hoc at this year's Perl conference and had some outstanding entries. My personal favorite was one of the two winners – Kevin Hackman's paean to the ascendancy of Linux over commercial complacency:
fall leaves blanket ground
redmond dreams darkly – beware!
winter brings penguinsWe're expecting even greater flights of poetic fancy next year.
As the author of several different Perl modules related to parsing and text processing, why do you choose to write in only 100 percent Perl, instead of implementing slower parts of the code with C extensions?
It's true that all of my modules are pure Perl. The official line is that I write them that way to maximize portability and to make them as easy to install and use as possible
But the truth is that I write these things in my spare time for my own pleasure, and writing them in Perl is infinitely more pleasurable than slogging my way through the equivalent C code.
It's like the difference between composing a haiku and drafting a legal document: I could write all the "heretofores," "afforementioneds," and "notwithstandings" required in a C program, but why put myself through that misery when I can achieve the same effect in 17 syllables of Perl. And have fun doing it!
Besides, if you find one of my modules too slow, wait a few months. Either CPU speeds will double or I'll have completely rewritten the module. Either way, the performance problem will probably have evaporated.
Before Object Oriented Perl was released, there was no book dedicated to object-oriented programming in Perl. Perl is incredibly flexible when it comes to implementation – some say too flexible – why consider programming in OO Perl?
There are several good reasons to consider object-oriented Perl. For a start, sometimes you really do need the power and flexibility that Perl provides, especially if you're processing text and can take advantage of Perl's regular expressions and formatting capabilities. In such cases, Perl is the natural choice.
But what do you do if the application you're developing is very large? You probably don't want to code it in regular Perl – you may not trust yourself to keep the code readable and maintainable. That's an obvious situation where OO techniques can be used to structure the code better. If it's big and it needs to be written in Perl, OO Perl is a good solution.
Sometimes the motivation is the other way around: maybe you have a programming team with a great deal of OO experience – they're used to thinking in object-oriented ways. That probably means the system you're building has been designed as an OO system. If Perl turns out to be the best language to implement that design (or prototype it), then once again you'll end up writing OO Perl.
However, I also think people have the misconception that OO Perl is somehow more rigorous or nobler or more serious or somehow "higher" than regular Perl, when the truth is that it's just another alternative. When it's the right solution to your particular problem – or the right match for your particular skills – that's when you should consider it.
Personally, I find that working in the OO paradigm usually makes it easier to think about problems and devise solutions for them, so I often end up using Perl's OO features. What I most like about them is that they are so "low-key" that they never get in the way of solving the problem.
Perl lets you manipulate the symbol table and other internal data structures from inside your modules – making it easy to do stupid or bad things, but it also leads to wonderful modules like Class::MethodMaker (which automatically generates constructors, accessors, abstract methods, and other time-consuming bits of code for you). Do you think that people need to approach OO in Perl with a different mindset than they're used to with other languages?
Yes and no. I think one of the outstanding features of OO Perl is that is allows you to approach OO with the same mindset as you're used to in another language.
By that I mean that you can write OO Perl that's similar in structure and operation to a C++ program, or OO Perl that's very like Smalltalk, or OO Perl that mimics Self, or CLOS, or Eiffel. I once even implemented a Perl module that added Python-esque scoping-by- indentation. In other words, whatever brand of OO you're used to using, you can stick with it when you move to Perl.
Eventually you discover that your notions about what OO actually is have been stretched and challenged so often that you've developed an entirely new understanding of what OO truly is – your own OO mindset. But there's another important aspect to all that flexibility. Because it can accommodate such a wide range of approaches, as you become a more accomplished OO programmer Perl also lets you select the most appropriate mindset – or mindsets! – for a particular problem.
If you need OO closures in one application, and interfaces in another, and prototype cloning in a third, you can implement each in Perl. And if you need closures and interfaces and cloning and inheritance polymorphism and objects that can change their class and classes that can modify their inheritance hierarchies, all in the same application, in Perl you can do that too.
So, although you don't need to approach OO Perl with a different mindset, after a while you're almost certain to discover one. I don't know of any other programming language that can give you that.
Are there any modules you'd like to mention that are useful for Perl OO programmers or that allow people to implement their classes in a more traditional fashion?
You already mentioned Class::MethodMaker and its handy method- definition short cuts, and there's also the standard module Class::Struct that does much the same thing. I think those two modules are well worth knowing about. Another indispensable module is Data::Dumper. Not only is it essential when debugging, it also makes a great persistence mechanism, as I talk about in the final chapter of the book.
And I recently found another OO-related use for Data::Dumper: it helped me to solve a major problem with my recursive descent parsing module, Parse::RecDescent. Many people find that module an easy way to build object-oriented input parsing mechanisms, but because it's pure Perl it can be slow to start up. Several users had asked if I could add an option to "precompile" grammars for the parser, so that there was no start-up delay while the module interpreted the grammar and built a suitable parser object.
That seemed like a big task, and one I was not very keen to take on... until I woke up in the middle of the night with a blinding insight. The next morning, I implemented the whole precompiler in five minutes. All I had needed to do was have the precompiler execute the normal (slow) interpret-and-built of a parser object and then use Data::Dumper to dump the entire ready-to-parse object to a file. Then users could just include that file in their programs and it would instantly re-create the complete parser object for them.
Of course, this same optimization could be applied to any statically defined object that's expensive to create. Unfortunately, we were in print by the time I thought of it, so a full explanation will have to wait till the next edition.
Could you tell us about how you wrote Tie::SecureHash and Class::Multimethods?
The Tie::SecureHash module provides secure encapsulation for Perl objects, while Class::Multimethods implements a full breadth-first multiple dispatch mechanism.
The need for a simple tool to enforce encapsulation is fairly self- evident: Perl doesn't hide any of the internal data structures of objects the way most other OO languages do. That can lead to problems in large applications (where OO Perl is most needed).
Because the internals of an object are accessible, programmers will access them, if only to squeeze out a few cycles of better performance. This makes their code reliant on the object's implementation, so when that implementation inevitably evolves, their code breaks.
Tie::SecureHash allows programmers to build objects whose internals are only accessible from within the object's own class (or class hierarchy). Better still, those objects look and act just like regular Perl hashes, so the programmer doesn't have to learn any new syntax to use them.
The fact that it's a very useful module in its own right is almost a side effect: the truth is I needed a "deus ex machina" to finish the chapter! I created the module while I was writing the chapter on encapsulation for Object Oriented Perl. There are two clever techniques to enforce encapsulation in Perl: one uses anonymous subroutines that drag their creation environment around with them (so-called "closures"), and the other uses special mini- objects that rely on the scoping properties of Perl lexical variables. Unfortunately, both techniques are moderately hard to understand, as well as being complex to code. So naturally, almost no one uses them.
I wanted to round out my encapsulation chapter by showing the reader an easier solution, but there just wasn't any. So I had to create one. The fact that it's a very useful module in its own right is almost a side effect: the truth is I needed a "deus ex machina" to finish the chapter!
Class::Multimethods had a very different genesis. There wasn't a huge latent demand for it. I suppose multiple dispatch is considered a little esoteric for most OO applications. That's a pity, because it gives programmers a very powerful tool for specifying polymorphic behavior when two or more classes interact.
With multiple dispatch you can set up a series of subroutines, all with the same name but different parameter types. Such a series is collectively called a multimethod. When you call the multimethod and pass it arguments, the correct subroutine for those arguments is then invoked automatically.
It's very like function overloading in C++, except that the decision as to which version of the overloaded subroutine to call is made at run time (like C++ virtual functions) rather than at compile time.
For example, you could set up a series of event handlers for a GUI system and then generate events of various kinds sent to widgets of various types. The multiple dispatch mechanism would automatically sort out which combination of event and widget had occurred and call the appropriate handler. Better still, if there was no handler specified for the particular combination, the dispatcher would automatically find the handler that was the "nearest compatible match" and call that instead.
I've been interested in multiple dispatch for some time now, ever since one of my postgraduate students wrote his Ph.D. thesis on the difficulties of adding a multiple dispatch mechanism to C++. Although he was eventually successful, it was a long and painful struggle. When I started using object-oriented Perl, I naturally wondered how hard it would be to add a similar mechanism there.
As you might expect, with Perl's full run-time access to a program's symbol table, and ability to intercept subroutine and method calls (via AUTOLOAD), it turned out to be remarkably easy. In fact the core of the new dispatch mechanism is only 200 lines of code.
I didn't have the heart to tell my grad student about that.