Skip to main content.
Features: Calendar | Interviews | || Login

Interview with Curtis 'Ovid' Poe

The Perl Review: You're the current grants secretary for TPF. What does that mean exactly?

Ovid: Basically, four times a year I pull the grant applications from our queue and I submit them to the grant committee for votes. After the grants are voted on, I let the applicants know the status of vote and if they were denied, I give them a summary as to why they were denied.

I also assign grant managers to grants and find new grant managers. I work with our treasurer, Kurt DeMaagd, to determine the available funds and how to pay out current grants. I have reports which go to the steering committee and I keep the community up to date via the Perl Foundation blog. Also, because of my position, I'm on the TPF Steering Committee and that's even more stuff to take care of.

I've been doing this since September of last year and basically have been trying to do as good a job as Baden Hughes, my predecessor. It turns out to that Baden made it look easier than it is and I've been very grateful for his advice.

TPR: The latest grant was to Nick Clark for improvements to Perl 5. What is the Perl community going to get from that?

Ovid: We've had a few long-standing bugs in Perl which don't affect many, but for those who are bit by them they're pretty frustrating. There are also new things being added. Memory consumption is being reduced, relocatable Perl installations will be possible, he's finishing IPv6 support and many other things. His grant manager, Adrian Howard, has been keeping us informed of his progress and I've been posting the results to the TPF blog. It's wonderful stuff.

TPR: How do you decide how much money to give out?

Ovid: Before we vote, I contact our treasurer, Kurt DeMaagd, and ask how much we can spend. Sometimes we can be flexible, but we're a non-profit and don't have tons of cash to play with.

TPR: How does TPF get the money for grants? Do corporate sponsors have any say in where the money goes?

Ovid: Our website lists our our sponsors. That has a link to a "full" list which is probably incomplete. There are some who have given us cash under the condition that we don't say who they are and we generally respect that (I believe that some of them are not even mentioned on the full sponsors list).

As for how the money gets allocated, corporate sponsors can give us a chunk of cash and say "spend it on this". We might refuse, but I don't know if this has happened because they're happy us decide where to best the donations. One exception has been NLNet. They gave us a huge sum of money specifically for Parrot development. We are very grateful for this as it's allowed Parrot development to continue at a faster pace than it otherwise would have—though I know many will be suprised to hear that.

TPR: Who can apply for a TPF grant? Do you have to be known in the Perl community?

Ovid: Anyone can apply for a grant and they don't have to be known to the Perl community. However, the larger the grant, the more likely it is we will refuse the grant if we have no way of judging the qualifications of the applicant. Nicholas Clark's grant was one of the largest we've awarded and even then, he deserves more. However, if some programmer we had never heard of applied for that grant, we'd be more cautious. This isn't our money, this is the community's money and we have to be responsible stewards of it.

TPR: What makes a good grant application? Are there examples of good ones? Or bad ones?

Ovid: As an example of a good grant application, read Nicholas Clark's latest application.

That's far more in-depth than we see from most applications, but it was for $11,000, so providing a solid application was important. He was very clear about the goals, the benefits, the approach he was going to take, the timeline and the grant amount.

As for a bad example, I have plenty but I don't want to embarrass anyone. However, I can give some "red flags" we watch out for:

TPR: In the past, there wasn't a lot of feedback about grant applications. For instance, applicants didn't get notices that their application was received, or even read. Is that going change? How can applicants see the status of their application?

Ovid: First, for lack of feedback to grant applicants, that's my fault. I had a lot on my plate and only having taken this role in September 2005, I'm still learning to prioritize. I haven't actually had much complaints from folks about lack of feedback (I can only remember two), but I need to be more sensitive to this issue.

On an important related note: one thing that Bill Odom, the TPF President, and Richard Dice, the Steering Committee Chair, have been focusing on heavily is opening up the Perl Foundation. People need to know what we're doing and how we're doing it. Starting the blog was a wonderful first step. Reading on the blog, you can see how Andy "The PR Guy" Lester, and Jim Brandt (conference chair) and others have been updating the blog to let folks know how we're doing.

TPR: Turning the idea of grants around, as TPF thought of offering bounties for certain problems? Have they done that in the past?

Ovid: We've looked into this several times, but there are some issues. The major hurdle seems to be having enough dedicated volunteers to manage the extra effort involved. We're not just cash-strapped, we're body-strapped, too (er, maybe that's not the best wording). Trying to come up with a realistic system of doing this that we can throw both people and money at has eluded us. We haven't given up, though!

TPR: You just released yet another CGI framework, Class::CGI. What's different about your approach to this ancient problem?

Ovid: Ack! It's not a framework. It simply solves a very common issue that folks have while writing Web-based code: taking form data, validating it and returning objects based upon them. I want this line to do all of that at once and there's no reason it can't:

my $customer = $cgi->param('customer');

Instead, programmers get lazy, or programmers are faced with deadlines or worse, newer programmers don't know to how to do this properly. With Class::CGI, your programmers can create "behind the scenes" code which handles this and the junior programmer can just do:

use Class::CGI profiles => '/path/to/profiles';

my $cgi      = Class::CGI->new;
my $customer = $cgi->param('customer'); # untaints and validates!
my $name     = $customer->name;         # look ma, objects!

if ( my %errors = $cgi->errors ) {
  ... something failed to untaint or validate

Side note about frameworks: while some frameworks leave a lot to be desired, that shouldn't lead one to condemn all frameworks. Some programmers work with buggy or confusing frameworks or try to get it to do something it wasn't intended to do and they start to generalize their experiences to all frameworks. This has led to the fad of sneering at the word "framework". This is sad.

TPR: What motivated you to make a shinier wheel?

Ovid: I want my Web code to look very simple and just focus on the business problem it's trying to solve. Class::CGI is basically a mediator pattern which provides a unified interface to the CGI object and whatever objects you need. By having each of your objects specify a Class::CGI handler for them, you have have a centralized spot for handling all of the grunt work of instantiating those objects for your Web code.

As an example, a common problem I see is having separate "select" boxes for day, month, and year. The code fetches those values, validates them and tries to create a date object. The programmer often spends a bunch of time writing or rewriting that code when she really just wants to get to the code which processes the customer's order. One horrible thing I sometimes see is an input box asking for a date with a little note beside it which reads "MM-DD-YYYY". This makes it much easier for your customer to get frustrated typing in bogus information but it makes it much easier for a programmer to do this:

if ( my $date = My::Date->new($cgi->param('date')) ) {
  ... whee!
else {
  ... tell the customer to type it in yet again

That's awful. With Class::CGI, it's trivial to do this:

my $date = $cgi->param('date');

Mind you, there might not even be a "date" param in the form. This could be a composite of your three select boxes, but the programmer is shielded from that and can go back to what they originally intended to do.

While I have docs which show how to do that, I'm soon going to be releasing Class::CGI::DateTime so folks won't even have to write it themselves.

TPR: Is this a new interface to old code, or a completely new way of doing things?

Ovid: Class::CGI is a subclass of CGI::Simple and, as a result, has all of CGI::Simple's behaviors, along with a few new ones. Because CGI::Simple is effectively a drop-in replacement for, Class::CGI gets all of the power of (minus the HTML generating methods), but with faster code and a few extra features.

TPR: Why do some many programming interfaces just suck? Is that the main reason people re-invent things, in your opinion?

Ovid: I think many programmers just write the first interface which comes to mind. As they realize that they can't do "X", they just throw another function or method at it, or add yet another parameter to their god object without thinking about how the thing fits as a whole. I know that I've certainly been guilt of that. While some reinvention is to approach a problem from a new viewpoint, much of it is to get around this issue.

Here's a solution, though: test-driven development. As you get used to tests, you start to learn to write decoupled code because it's easier to test. You write more cohesive functions and methods because they're easier to test. When a proposed change will break a lot of things, you stop to reconsider because it's a pain to go back and change a bunch of tests. All of these things lead to cleaner, stabler code. Learning to write tests is the single best thing which has ever happened to me as a programmer.

Even without test driven development, we can do better. What I like to do is sit down and write and interface that I think would be a joy to use. I don't worry about implementation. Instead, once I have an interface that I think is simple and intuitive, I figure out how to make it work. The result is simple, flexible code.

TPR: Can one interface ever make everyone happy, or do we need a couple different ways to do most things (templating, configuration, et cetera)?

Ovid: I can't think of any interface for anything which I can point to which could make everyone happy. There are simply too many variables out there to create "one size fits all" interfaces. Also, some interfaces make innapropriate assumptions about your code. Maybe they assume you're using Mason when you're using HTML::Template. Maybe they assume you're using hash-based objects when you're not. Those assumptions are frequently reasonable, but certainly not universal.

TPR: How does Class::CGI make this easier?

Ovid: Class::CGI is very, very easy to learn and use. Write a couple of handlers and you're likely to not have to turn to the docs again for a long time. It leverages an existing, well-known interface and still gives the programmer the flexibility to handle weird-edge cases with a minimum of fuss. Further, it's just normal object-oriented code, so there's no requirement to memorize a bunch of arcane stuff to use it.

With Class::CGI, programmers have virtually all of the flexibility they'd need in having objects being created, but I don't have to write code to handle all of the special edge cases that might crop up. Most of the time programmers won't need to worry about the edge cases, but when they do, there's only one method (&args) they need to know which handles this.

The upside of this is that Class::CGI is powerful, lightweight and easier to learn than some alternatives. The downside is that some programmers want software which anticipates more of what they need. There's nothing wrong with that, but it's a style of programming that I've been leaning away from.

TPR: Is this a move towards descriptive programming? Does Class::CGI let us say "Hey, make all that CGI stuff part of my object"?

Ovid: No! It's saying "don't make that CGI stuff part of my object"! CGI should not need to know what your objects are and your objects generally should not know the CGI object. There are exceptions to this rule, but if you want to provide My::Customer->from_cgi($cgi), that's your choice and it's not a general purpose problem that Class::CGI is designed to solve.

Instead, as mentioned previously, Class::CGI is about removing the grunt work from your Web code so you can focus on the real problem you're trying to solve.

TPR: has the problem of a morphing interface and evolving defaults to take care of things such as semicolons instead of ampersands in query strings. Will Class::CGI hide all this so it acts the same, mostly?

Ovid: Since this is a subclass of CGI::Simple, it handles most of this transparently. If CGI::Simple changes (hopefully not) then Class::CGI will change too.

TPR: What are some code smells that would lead me to using Class::CGI?

Ovid: Just to be clear to your readers: a code smell is a sign that something may be wrong with code and further investigation is warranted. It's not a guarantee that something is wrong, though, so programmer judgment is more important than hard and fast rules. So with that cowardly caveat:

If you find your self constantly fetching form data, untainting it, validating it and constructing objects from it, Class::CGI may be a good choice.

If you find that you keep needing to reread the documentation for the modules which solve this problem, then you're spending time reading when you probably want to spend time coding. Class::CGI lets you do that.

If you're perfectly happy with your current method solving this problem, feel free to ignore Class::CGI. My feelings won't be hurt.

TPR: You're a co-author of Perl Hacks, part of the O'Reilly Hacks series. What's that book about?

Ovid: I think of it as the Perl Exotic Dishes Cookbook. Once you get to be really comfortable with Perl, you start to wonder about how to be more productive, how to handle that weird little problem that's been bugging you, or all sorts of odd little things which can almost be thought of as "trivia", but are actually incredibly useful once you need them. Perl Hacks helps to provide many of those answers. Plus, it's lots of fun to just browse through.

TPR: What was your favorite Perl hack in the book? Favorite hack not contributed by you?

Ovid: Oddly enough, it's the very first hack in the very first chapter: "Add CPAN Shortcuts". This hack lists a variety of shortcuts you can add to Firefox to make it quick and easy to search CPAN, AnnoCPAN or anything else you want. I use this hack constantly and it's really boosted my productivity.

TPR: O'Reilly offered Perl Hacks as a Rough Cut, so readers could see a pre-published version of the book. Did that help the writing or editing?

Ovid: Oops. I know that has helped others, but right about the time that this was going on, I became rather distracted by an impending move to the UK and some Perl Foundation work, so I didn't have much time to follow up with that.

TPR: How does Perl Hacks compare to The Perl Cookbook, aside from not being able to break your foot by dropping it?

Ovid: First, it's newer so there are things in there which may belong in the Cookbook, but couldn't go there. However, the Cookbook seems geared towards providing solid recipes for common problems. Perl Hacks offers those, but also offers things like tracing opcodes and using PAR. Also, Perl Hacks many times takes a less formal tone. We have the "CPAN Drinking Game". I don't think the Cookbook is likely to incorporate that.

TPR: How many of Damian's Best Practices do the hacks violate? How many of those are broken on purpose?

Ovid: I certainly can't quantify that, but it's less than you might think. There are some practices such Damian's explanation of using regexes or inside-out objects which folks may not be as familiar with, but we still generally followed good naming practices, used strictures, laid out the code properly and so on. In fact, at one point when I tried to write terser code to more properly focus on the hack, I was chastised for not providing a good example of solid code. The reviewers were right and I changed my code.

It's also worth noting that "hack" shouldn't be taken to mean "bad code". Some hacks are bad, but we mean "hack" in the sense of a clever solution to a problem.

TPR: Damian Conway was a co-author too. Did he follow his own best practices?

Ovid: Er, mostly :)

TPR: You wrote the AI::Prolog module. What is logic programming, and how can you do it in Perl?

Ovid: I'll use the terms "declarative programming" and "logic programming" interchangeably, even though that's not quite accurate.

In programming, we usually direct the computer to perform a series of steps in hopes that it will achieve a desired goal. In logic programming, you describe your goal and let the computer figure out how to get there. This is done by specifying facts and rules and letting the software infer the correct answer.

Regular expressions are a limited form of logic programming. For example:

if ( $var =~ /^a+b*$/ ) { ... }

Here we know that our goal is a string comprised of one or more "a" characters followed by zero or more "b" characters. We've described a pattern for what a goal looks like and let the regular expression engine figure out the best way to match that pattern.

One way of using logic programming in Perl is my AI::Prolog module. That allows you to embed prolog programs in your code and solve simple problems with them. Unfortunately, there are some limitations in how one can pass Perl data to the Prolog program (it would be great to pass SQL result sets) and while AI::Prolog is fun to play with, it's mainly to show folks how logic programming works. I do include a couple of small text adventures, though, just so people can have full logic programs to play with.

If one needs serious logic programming work, I would recommend Language::Prolog::Yaswi as this lets you communicate directly with the free SWI-Prolog compiler.

TPR: What sort of problems are easily solved with this approach?

Ovid: Logic programming is heavily used in liguistic research, expert systems and theorem proving. There's also work with "inductive logic programming" where you don't describe the goal but you instead provide examples of solutions and possibly provide hints on how to build a program which will satify the goal. Credit card companies are using this in fraud detection. They provide the software with your purchase history and with enough information, the software eventually learns to flag unusual purchases.

TPR: Can Perl be as efficient at logic programming as other languages?

Ovid: No. Logic programming, and most forms of AI, are so computationally intensive that a pure Perl approach simply won't scale well for larger programs.

TPR: Why should a programming learn logic programming?

Ovid: Many experienced programmers are already familiar with logic programming even though they don't know it. Both regular expressions and SQL are types of logic programming. However, by learning a "real" logic programming langauge, you can begin to appreciate different approaches to problems. For example, how would you find all combinations of two lists which form a third list? That's an annoying bit of code to write. In Prolog, it's pretty simple:

append([], X, X).
append([W|X],Y,[W|Z]) :- append(X,Y,Z).

If you call that with append(X,Y, [a,b,c]);, you get something like:

''      'a b c'
'a'     'b c'
'a b'   'c'
'a b c' ''

That's not quite what the output looks like, but it's close enough.

In fact, just to show how closely related to logic programming regular expressions are, here's an example of doing this with a regex:

use re 'eval';
my $string = "abc";
my $length = length $string;
my $regex 
	= qr/(\G[$string]{0,$length}(?{print "# [$&][$'][$string]\n"}))/ x 2;
$string =~ $regex;
That prints:

# [abc][][abc]
# [ab][c][abc]
# [a][bc][abc]
# [][abc][abc]
# [abc][][abc]

But it's obviously very clumsy and has a duplicate at the end. :)

I actually had a way of implementing logic programming almost entirely leveraging Perl's regular expression engine. That would have given us plenty of speed, but Perl's regex engine turns out to not be re-entrant and I had to abandon the idea. I explained it on PerlMonks.

If anyone wants to apply for a grant to fix this, I'd certainly be inclined to vote for it (though I can't speak for the rest of the committee).

A review of Perl Hacks appears in the Summer 2006 issue of The Perl Review. Ovid's "Logic Programming in Perl" appeared in the Spring 2006 issue.