Loving 5.14

Just a quick update to let people know that I am not, in fact, dead.

I really appreciate so many features in modern Perl.

use v5.14;
use Modern::Perl;

my @list = qw( 1 3 4 87 5 3 3 65 1 3 );
my %indices_for;

while ( my ( $i, $value ) = each @list ) {
    push $indices_for{$value} //= [] => $i;
}

What's better is that I appreciate what Jesse Vincent is trying to do with 5.16 (trim the core so that all non-essential stuff is a module). With that, we'll get .Net, the JVM and many other goodies we've wanted. Perl is slowly, slowly crawling into the modern era.

11 Comments

You haven’t forgotten about autovivification, right? :-)

Oh gosh, because you are using the new push SCALAR syntax, I see.

Ugh.

I’ll have to bring that up on p5p.

Quite likely I've missed the point but why is the code fragment shown superior to, say:

my %list = qw( 1 3 4 87 5 3 3 65 1 3 );
my %indices_for;

while ( my ( $i, $value ) = each %list ) {
    push @{$indices_for{$value}} , $i;
}

?

Just curious really.

It's simple, really - Ovid's example is taking explicit advantage of several new features in perl itself. These are activated by the use v5.14; at the top. The use Modern::Perl; line you can ignore - it's not a no-op but changes nothing for the purpose of the example.

The three cool features I see are:

  1. each can be called on an array, and in list context, returns the index of the current iteration along with the value at that index in the array.

  2. The defined-or-assignment operator: //= (which is based on the defined-or operator //) assigns the value on the right-hand-side to the variable on the left-hand-side only if the the value on the left-hand-side is undef.

  3. Auto-dereferencing array and hash functions. In perl 5.14 and up, you can now call 'push' and 'shift' et al. on a scalar that references an array... the same has been done for the functions to operate on hashes!

So, let's poke at the lines showing off #2 and #3, since those are the most fun and #1 seems pretty obvious to me...

Features #2 and #3 are demonstrated by the line,

push $indices_for{$value} //= [] => $i;

Prior to perl 5.10, you would probably have to write that like this:

my $indices = defined $indices_for{$value} ? $indices_for{$value} : [];
push @{$indices}, $i;

But let's add some modern Perl features...

With auto-deref you can do this:

my $indices = defined $indices_for{$value} ? $indices_for{$value} : [];
push $indices, $i;

Add defined-or and you can have this:

$indices_for{$value} //= [];      
push $indices_for{$value}, $i;

Take into account that like ||, // is a very high precedence operator, and that => (equivalent to ,) is pretty much the lowest-precedence operator, and that assignment is in the middle, and that an assignment expression returns the value being assigned, and I'm not sure what push's precedence is but it appears to be lower than = you get...

push $indices_for{$value} //= [] => $i;

\o/

Ah. I didn’t see it. Looks like I had more luck, but same thing.

Hercynium: Ahh. Thanks - didn't realise 5.14 each can return index in list context. Don't have 5.14 to hand at the moment.

The other bits I did know about. I love defined-or!

I suppose in "retro-perl" you could achieve the same thing with:

( defined $list[$_] && (push @{$indices_for{$list[$_]}} , $_) )
    foreach (0 .. @list);

More-or-less identical character-count - is this better, or worse? I guess I'm intrigued by why certain syntactic forms are considered superior to others.

I always thought what was preventing Perl on the jvm was the whole "only Perl can parse Perl" thing. How does trimming out modules solve that?

Thanks Ovid. That is very exciting to look forward to. Also, this presentation by Jesse at OSCON gives a good overview of this subject. He describes strategies for making Perl smaller, as you stated. He even makes a nod to the "only perl can parse perl issue".

http://www.slideshare.net/obrajesse/oscon-2011-perl-516-and-beyond

Leave a comment

About Ovid

user-pic Have Perl; Will Travel. Freelance Perl/Testing/Agile consultant. Photo by http://www.circle23.com/. Warning: that site is not safe for work. The photographer is a good friend of mine, though, and it's appropriate to credit his work.