Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

Aristotle (5147)

Aristotle
  pagaltzis@gmx.de
http://plasmasturm.org/

Blah blah blah blah blah [technorati.com]

Journal of Aristotle (5147)

Wednesday January 14, 2009
12:36 AM

I’ve heard something like this somewhere before…

Reginald Braithwaite :

Also, I reject the argument that responds_to? checking is buggy because some people write method_missing magic that breaks it. I reject the argument because I reject as buggy any code such that object o responds to method m but o.responds_to?(:m) => false. If you implement your own method_missing for a class, you should almost always implement your own responds_to? as well.

Tuesday December 23, 2008
01:10 PM

Sound familiar?

Paul Haahr :

Exceptions are also used to implement the break and return control flow constructs

Saturday December 20, 2008
01:12 AM

Perl Buzz mentions xkcd again

Wildly hit-or-miss weblog Perl Buzz has had to mention xkcd again. Why can’t you people leave the guy alone?

(SCNR.)

Saturday November 08, 2008
11:49 AM

A simple `unfold` in Perl

For many years, a very simple issue about writing an unfold in Perl 5 has stymied me.

(An unfold is the opposite of fold, of course. The latter is better known to Perl programmers as reduce from List::Util, which is a function that takes a block and a list and returns a single value by repeatedly applying the block to successive values. An unfold does the opposite: it takes a block and a single value and then repeatedly applies the block to the value, accumulating the return values to eventually return them as a list.)

A good unfold as I want it will allow the same thing as map does: for any iteration to return any number of elements, including zero. Also, the elements returned from an iteration must be passed out of the block as its return value for that iteration – otherwise you might as well write a conventional loop instead.

But then you have a problem: how do you know when the block is finished generating output? There is no possible return value you could use for this. The Python implementations of this function that I’ve seen invariably expect an exception to be thrown to signal the end of the iteration, which struck me as profoundly un-Perlish. But how else do you signal the termination condition out of band?

I could think of no sensible solution given the combination of constraints that I adopted. Until an hour ago, that is, when a flash of inspiration struck me.

I’ll let the code speak for itself.

sub induce (&$) {
    my ( $c, $v ) = @_;
    my @r;
    for ( $v ) { push @r, $c->() while defined }
    @r;
}

In this version, the initial scalar value is made available to the block in $_ (somewhat cleverly done via for, which is necessary because local $_ has lots of subtle pitfals), and the block is called repeatedly as long as $_ is defined. The block therefore signals the detection of its exit condition by undefining $_.

It’s that simple. It’s so simple I cannot believe it took me so many years to think of it, but there it is.

Here is a silly example:

my @reversed = induce { @$_ ? pop @$_ : undef $_ } [ 1 .. 10 ];

Of course, the eagle-eyed will immediately notice a problem: this produces 11 return values, the last one being the undef that got returned from undef $_. The fact that induce will collect the value of the final iteration rather than throw it away was a conscious design decision: there are two cases for the return value of the final iteration, either it is useful or not. What happens if it it’s not useful, but would be collected? Then you have to suppress it, which is easy. What happens if it’s useful, but would be thrown away? Then you have to arrange for the block to remember state so it can return the useful value first and then signal the termination condition on its next invocation. Since it is so much easier to suppress useless values that would be kept than to retain useful values that would be dropped, I chose to have induce keep the final iteration’s value.

There are various ways to arrange the suppression in the above example. One of them is to check more eagerly for whether another iteration will be necessary:

my @reversed = induce { my @l = @$_ ? pop @$_ : (); @$_ or undef $_; @l } [ 1 .. 10 ];

That is clearly extremely awkward. A simpler (and insignificantly less efficient) approach is to suppress the value returned by the undef function:

my @reversed = induce { @$_ ? pop @$_ : ( undef $_, return ) } [ 1 .. 10 ];

That’s much better, but still not pretty. In particular, that return can be awkward to place due to precedence rules. In the above example it requires those annoying parens. (Try it: the code compiles but breaks without them.) Instead, we’ll take a page from Javascript and write another function:

sub void {}

No, seriously. The point of this function is, well, to take any arguments you pass it, throw them away, do nothing, and return nothing – most importantly, to return an empty list in list context.

I admit that writing this, err, function greatly amused me. But the end result is quite satisfying:

my @reversed = induce { @$_ ? pop @$_ : void undef $_ } [ 1 .. 10 ];

So these two functions, induce (named like this instead of unfold, of course, to contrast with List::Util’s reduce) and void, will probably start appearing in my small scripts from now on.

Tuesday October 28, 2008
07:25 PM

Identifier clash

Pip pip, ol’ bean!

05:09 AM

Installing a perl with a minimal, collapsed directory layout

I just started getting onto the one-perl-per-app train. By default, Configure wants to set up an installation with a deeply nested directory layout so as much as possible can be shared across installs. I don’t care about that – having completely separate installs is quite affordable these days. So all that hierarchy is merely annoying and serves no useful purpose, and I would prefer to simply have all modules in ./lib and all XS components in ./archlib below the root directory of the installation, without any further nesting for different Perl versions, system architectures and packaging authorities.

But figuring out exactly how to get Perl’s Configure to give me I want took almost two hours of fiddling and research (and the final hint came from a rather tangential archived mailing list post).

So I thought I would jot the recipe down here:

PREFIX=$HOME/perl/5.10.0  # pick any root directory you like
sh Configure -des \
    -Dprefix=$PREFIX \
    -Dinc_version_list=none \
    -Dprivlib=$PREFIX/lib \
    -Darchlib=$PREFIX/archlib \
    -Dsitearch=$PREFIX/archlib \
    -Dsitelib=$PREFIX/lib

The maddening part was to figure out that inc_version_list must be none, otherwise the sitearch and sitelib settings will be ignored and Configure will generate the default deeply nested layout for them.

I have to say that Perl requires rather a lot of work to beat it into submission to my preferences…

Sunday October 26, 2008
02:35 PM

Alternate realities

Lukas Smith :

As such we have decided to go with “\” as the new namespace separator [in PHP] instead of the current “::

I’m sure that makes a lot of sense when the other options you seriously considered include “:)” and “:>”.

[Update: I wrote this before seeing Ovid’s posting about the same matter.]

Monday October 06, 2008
02:35 PM

Deposition

Elyse M. Grasso :

We are re-architecting [our commercial application]. This would be a good time for us to transition to perl6.

As far as I can tell from the various faqs and wikis, the existing functionality in rakudo should support most of our needs for the initial release. […] Is it practical now to deploy a Perl6/Parrot runtime with a (possibly precompiled) version of our product?

Seeing this mail made my day.

Wednesday September 24, 2008
07:02 AM

The Little Prince and the Programmer

[By Olivier Danvy, via Dave Long]

On the next planet, in a building, there was a computer room.

The little prince: “Good evening.”

The programmer, glued to his computer terminal: “Sh! I’m programming!”

The little prince: “What is programming?”

The programmer, his eyes still on the screen: “Mmmmh… you’re interrupting me! What are you doing here?”

The little prince: “What is programming?”

The programmer, blinking and turning his head towards the little prince: “It is to make a machine do something. You write a program specifying what to do and the machine runs it.”

The little prince: “So what do you want the machine to do?”

The programmer: “To run my program. I am making a program to run my program, meta-circularly.”

And the programmer returned to his meta-circular program.

The little prince pondered.

The little prince: “Why do you want a program to run itself since the machine already runs it?”

The programmer, looking at him again and frowning: “Ah. You’re still there. It is because I am building a tower of computation.”

The little prince: “How tall will your tower be?”

The programmer: “Infinite.”

The little prince looked up.

The programmer: “But in practice one only needs three levels.”

The little prince looked down again.

The programmer, resuming his task with a concentrated appearance: “And I am working on it.”

“What a strange person. Every time I ask him what he wants, he tells me what he is doing,” the little prince said to himself.

“So he must always be doing what he wants,” he thought continuing his journey: “a programmer must be very happy.”

Monday September 15, 2008
02:46 PM

Breaking Out of the Perl Echo Chamber: A Call to Action

I just picked up yet another useless distraction, and I am going to ask you to do the same. Bear with me here:

StackOverflow just opened for business. It’s essentially an advanced form of Perl Monks’ Q&A section, except open to questions for any language – in fact, any programming and programmer topic at all. (Joel Spolksy explains the concept; take a look at that post if this is the first time you are hearing about StackOverflow.)

The site does not have a concept of forums; questions can simply be tagged, and you can filter by tag.

Each tag also has a feed.

You can see where I am going with this.

Here’s the thing: the site has pretty solid traffic already. If it really takes off, a large community of programmers from all walks of coding will wind up there. The Perl community core can either be present there, representing Perl as the excellent language we know it to be, or we can leave Perl’s image to the typical mix of novices, too-clever-by-half coders and CPAN non-users – likely also managing to let Perl look moribund in the same stroke, thus single-handedly reinforcing every common preconception about the language.

This would be an effort along the same lines as PerlBuzz, the claim-your-journal-on-Technorati meme, doing something about the low usefulness of Google searches for [perl blogs] and so on: letting our enthusiasm ring outside the echo chamber.

So let’s do it. Please subscribe to the questions tagged “perl” at StackOverflow and take a peek whenever the fancy strikes you and you have a few minutes to spare. Thank you to everyone who responds.