Method::Signatures 0.05: speedy \@foo, closures work

schwern on 2008-09-21T22:24:29

Using Matthijs van Duin's amazing Data::Alias module, the \@foo prototype now runs without a performance hit and @foo is a true lexical so closures work!

Method::Signatures 0.05 just released.


Sweet! But are attributes possible?

rhesa on 2008-09-21T22:41:17

I really like this. I was already tinkering with my extract_method script to make use of this gem of yours, and references were one of my unsolved issues. Thanks for fixing that so quickly :)

Is there any chance code attributes will be supported? I'd like to use this with CGI::Application, and I bet it'd be cool for Catalyst too.

Re:Sweet! But are attributes possible?

Aristotle on 2008-09-22T01:36:59

Catalyst has plans to obsolete the attribute syntax in favour of something very much like Method::Signatures, where you write something very roughly like

action foo (/bar/baz) { ... }

rather than

sub foo : Chained('/bar/baz') { ... }

… at least that was the idea when I last heard of it.

Re:Sweet! But are attributes possible?

Ovid on 2008-09-22T05:21:15

I'm already having issues with how "magical" bits of Catalyst are. Using hooks into the op-tree to stack the magic stuff on doesn't really reassure me. Does it seem warranted?

Re:Sweet! But are attributes possible?

tsee on 2008-09-22T07:16:15

Assuming that these bits of Catalyst would also be done with Devel::Declare, and guessing that it's still mostly mst hacking on Devel::Declare, it all depends on whether he's hit by a bus, doesn't it?

Personally, I'd rather worry about whether, by getting too cosy with the internals, Catalyst may eventually get similar breakage as Rails did between Ruby releases.

Re:Sweet! But are attributes possible?

Alias on 2008-09-22T08:18:30

Indeed.

Data::Alias has already horribly died once, plus it doesn't work anywhere that forbids the hack it uses to reference unexported symbols.

Re:Sweet! But are attributes possible?

Aristotle on 2008-09-22T15:05:01

There was discussion on p5p a while back to pull modules like PadWalker and Data::Alias into the core on the basis that they are highly dependent on the internals, and need to be maintained in synch, but that never happened. I still think it’s a good idea; Data::Alias and PadWalker allow things that are indispensable in some situations, and leaving them fend for themselves seems like a choice that diminishes the value of the entire Perl ecosystem to an extent.

Re:Sweet! But are attributes possible?

schwern on 2008-09-22T16:49:32

Is there any chance code attributes will be supported?

I hadn't even thought about them. It could, I think it just involves more Devel::Declare black magic from mst to make it aware of attributes.

Launch from Moonbase Alpha

jplindstrom on 2008-09-22T00:20:36

Very. Very. Cool.

So it's alpha, with large blinking warning signs to stay away, etc. Is the alpha flag a matter of concept (unsound/fragile) or a matter of effort (just not done yet)?

What's needed (if possible) to get it to a state so that people can use it?

Re:Launch from Moonbase Alpha

schwern on 2008-09-22T16:35:07

Is the alpha flag a matter of concept (unsound/fragile) or a matter of effort (just not done yet)?

It might be fragile. So far it's holding up well, but I haven't done anything major with it and I'm wary of building this on top of so much scary tech. Devel::Declare has a few bugs (it causes the debugger to spin like a top) that I hope mst will clear up shortly.

Second is the prototyping syntax and behaviors. Since I'm creating, essentially, a new language feature here I'd like it to get knocked around some before locking it in place. I'm pretty happy with how it's come out, and if I stabilized with just the list of features in 0.10 I'd be very happy.

There's a list of bugs and caveats as well as the open issues from the named parameters proposal which Method::Signatures is an implementation.

What's needed (if possible) to get it to a state so that people can use it?

More testing to ferret out bugs. More commentary on how the prototypes behave (good or bad). More fuel for mst's brain.

Also making sure I'm not boxing the prototype syntax into a corner. That I'm not preventing us from adding something important on later.

Re:Launch from Moonbase Alpha

jplindstrom on 2008-09-22T22:31:31

On the matter of syntax, do you have any ideas on named arguments (i.e. hash/hash ref automatically unpacked into the variables)?

It seems doable to me. If the signature is misc vars, but you pass in a single hash ref, then... *magic*

Re:Launch from Moonbase Alpha

schwern on 2008-09-23T09:42:45

While they are definitely a possibility, and you're not the first
person to ask for them, I'm wary of trying to mirror Perl 6's named parameters right now for a number of reasons. First, they're not
necessary just now. Method::Signatures has a nice bag of problems to
deal with already and the signature syntax is extensible. And I
haven't given them a lot of thought.

Second, Perl 6 has all sorts of magic at the caller's end to force
named vs positional parameters. We have none of that. All we can do
is, as you suggest, treat a hash ref as positional. But that leaves
some ambiguity...

method foo( $things ) {
    ...
}
 
Class->foo({ things => 42 });

What's in $things? Currently it's { things => 42 }. Under named
parameters it might be just 42. Or maybe not. It's ambiguous.

Because named parameters are implied in every method, it means every method has to have a little extra code to check if the first argument is a hash ref. This adds a performance hit of about 10-15% to an empty method call whether or not you use it.

#!/usr/bin/perl -lw
 
use Benchmark qw(cmpthese);
 
{
    package Methods;
    use Method::Signatures;
 
    method echo(\@args) {
        return @args;
    }
}
 
{
    package Subs;
 
    sub echo {
        my $self = shift;
        my $args = $_[0];
        return @$args;
    }
}
 
{
    package Subs::With;
 
    sub echo {
        my $self = shift;
        my $args = (ref $_[0] eq 'HASH') ? $_[0]->{args} : $_[0];
 
        return @$args;
    }
}
 
cmpthese( shift || -3, {
    'M::S'              => sub { Methods->echo([1,2,3,4]) },
    'sub'               => sub { Subs->echo([1,2,3,4]) },
    'with positional'   => sub { Subs::With->echo([1,2,3,4]) },
    'as positional'     => sub { Subs::With->echo({ args => [1,2,3,4] }) },
});
__END__
                    Rate as positional with positional         M::S          sub
as positional   272775/s            --            -39%         -45%         -47%
with positional 448256/s           64%              --         -10%         -13%
M::S            496243/s           82%             11%           --          -3%
sub             512481/s           88%             14%           3%           --

It needs more thought. Maybe you can think of some trick to eliminate that drag. Or maybe a method would have to declare its use of named parameters.