[Perl5-syntax] Adding Moose type checking to Method::Signatures

Michael G Schwern schwern at pobox.com
Sat Feb 26 08:17:30 GMT 2011


On 2011.2.26 1:52 PM, Buddy Burden wrote:
>> Object methods being called as class methods: agreed, bad.
>>
>> But I don't have a beef with class methods being called as object methods.
>> Class->class_method and $obj->class_method are functionally equivalent.  I
>> don't think denying that will catch real bugs compared to the effort.
> 
> Well, a couple of things about that:
> 
> *) From a strictly philosophical standpoint, I think that $obj->foo()
> and Thing->foo() are saying different things.  Even if $obj->foo()
> works, functionally, I don't actually want my coders saying
> $obj->foo() if they really meant Thing->foo().  It makes their code
> harder to maintain, IMHO, because it implies something's going on
> that's different from actually _is_ going on.

I don't disagree on the principle, just the magnitude of the problem.  I don't
think it's even worth:

    my $class = ref $obj;
    $class->method();


> *) From a practical standpoint, it _could_ produce a bug, unless the
> class methods are carefully written.  For instance, this:
> 
>     method foo ($class: Int $arg)
>     {
>         no strict 'refs';
>         my $func = "${class}::bar";
>         return $func->($arg);
>     }
> 
> wouldn't work if called as $obj->foo().  How likely that is in
> practice, I'm not sure; I've written something similar before, but
> admittedly it was more tricky than typical.

Again, no disagreement on the principle.  I don't think it's worth the runtime
overhead.


>> IMO the type of the invocant would always be inferred.  You should not be
>> allowed to explicitly set the type.
> 
> Well, if we're trying to roughly mimic P6 syntax, setting the type of
> the invocant is definitely allowed.  See Synopsis 12
> (http://perlcabal.org/syn/S12.html#Methods).

Even they say "you could declare a more restrictive type, but that would
probably be a bad thing for proper polymorphism" and I'm with them on that one.


> But I don't really have a horse in this race.  If we decide that
> typing on the invocant is allowed, I'll use it (for class methods
> only).  If we decide it's not, I won't miss it. :)

I guess it's one of those features that would be there if you really want to
do that... but I'm not going to be the one to implement it.


>> What's missing is the ability to differentiate between class and object methods.
> 
> Sure, if you think there's a better way, I'm certainly open to it.

Perl 6 has the "method ^foo" syntax.
http://perlcabal.org/syn/S12.html#Class_methods

But note that even Perl 6 doesn't restrict $obj.class_method.

Anyhow, there are bigger fish to fry.


>> I think what I'd like instead of parse_extra (same issues as inject_extra) is
>> this...
>>
>> I agree with most of the MXMS syntax, just not with the implementation.  And
>> I'd like to bring the syntax of the various signature modules together.  So if
>> you want does and coercions and all that, patch them into MS.  I would
>> particularly like constraints (ie. "where").  This would improve MS for
>> everybody and MS doesn't have to worry about supporting 3rd party parser hacks.
> 
> Hmmm.  My hesitation there is a few things:
> 
> *) It means that we're declaring that this module is providing the One
> True Way for parsing signatures. You don't like the code we generate?
> That's okay, you can provide your own.  You don't like the syntax we
> parse?  Tough cookies buster!  I mean, obviously people can write
> their own module.  It just seems weird to provide extensibility in one
> area but not the other.

Not providing the One True Way for parsing, MXMS has its own parser for
example, but converging on the One True Syntax.

One of my goals is to converge the various signature modules into an agreed
upon syntax and behavior for Perl 5 signatures which can ultimately be
implemented in Perl 5 itself.  We are, essentially, acting as a prototype for
future versions of Perl 5.

Anyhow, I don't so much mind the idea of an extensible parser as the
implementation of parse_extra().  Just handing out the prototype and saying
"go at it!" doesn't seem maintainable.


> *) If there's any extra overhead in parsing all the extra stuff,
> people pay that whether they use it or not.  That's probably
> insignificant, though.

Yeah, not my concern either.


> *) It seems weird to me to accept syntax that you don't do anything with.  So
> 
>     method foo ($debbie does Dallas)
> 
> doesn't generate a syntax error, but doesn't actually do what you
> thought it did.  Sort of a silent failure.

Oh, I guess I didn't make that clear.  We'd implement "does" (it's just a
synonym for "is", right?) and where and the rest.  Even types can be
implemented with isa() and stealing from
Moose::Util::TypeConstraints::OptimizedConstraints.

You're right that if MS doesn't implement syntax, it should die or warn rather
than silently ignore it.


>> I was considering also making MS more configurable about its features.  For
>> example, a lot of people don't like that it declares the methods at compile
>> time like a normal sub.  That could be turned off by passing a flag to
>> import() which would pass that along to the object.  I was thinking about
>> using it also for syntax... but I don't think I want to get into optional
>> syntax, just optional behaviors.
> 
> The only things like that I was thinking was that it might be nice to
> be able to change "method", "func" and/or "self" (similar to how
> Method::Signatures::Simple does it).  Which would be fairly trivial to
> implement.  Again, _I_ wouldn't use it, but it seems like others
> might.

Sure.  I wouldn't use it either, but I can see it being useful.


>> Another example is a flag to control how types are checked.  For example, MS
>> could ship with a purely class based type check on by default (fast and no
>> dependencies) with the option to turn on a Mouse/Moose based one.
> 
> Sure, that would save the need for the vast majority of people to
> subclass.  Depends on how much you want to build into MS directly, or
> if you want to build in some sort of plugin structure, which might be
> more work than you really want to get into.

Hmm.  Instead of having to override inject_for_type() which involves more work
than one needs to do, maybe the ability to just pass in a type_check routine.


>> If you tell me your Github ID I can add you as a collaborator.
> 
> I'm barefootcoder (most everywhere).  I'm still a total git newb tho;
> just giving you fair warning. :)  I just managed to get the $work
> folks converted over to svn a couple of years ago. ;->  But I did get
> my github login a while back, so I'm good to go there.

Ok then, you're all set.  We've talked about a bunch of stuff here.  Implement
away!  Be bold, I can always roll your changes back.  Just don't force a push
and you'll be fine.

My only request is you post an issue before you add a feature or make a major
change.  You don't have to wait for a reply, it just gives everyone an idea
what's going on.


-- 
But there's no sense crying over every mistake.
You just keep on trying till you run out of cake.
    -- Jonathan Coulton, "Still Alive"



More information about the Perl5-syntax mailing list