Type Constraints using Type::Tiny and attribute handler of subroutine signatures

If you can perform type checking with an attribute handler and Type::Tiny, Perl will be more attractive.

For example.

use Type::Tiny::Signatures;

sub foo ($str : Str, $num : Int) {

Type Constraints using Type::Tiny and attribute handler - Perl Subroutine Signatures Opinion Blog


I'm usually not an early adopter of new Perl features in publicly released code because I like to offer support for older versions of Perl. (Type::Tiny still supports Perl 5.6.1.) Once it's been stable for a few years, I imagine I'll start using it.

My main concerns with Dave's original proposals for type constraints and coercions are that:

  • There's way more extra syntax than necessary which will overcomplicate the language.

  • Certain features (coercion, aliasing, read-only variables) overlap with each other and will interact in confusing ways. (Like if a parameter is coerced from Num to Int, and it's an alias, then is the caller able to see the changed variable? Does this become an error if the parameter passed was a constant?)

  • The proposed mechanism for extension is lacking; if A.pm defines a "NonEmpty" type constraint for non-empty strings, this prevents B.pm from defining a "NonEmpty" type constraint for non-empty arrayrefs. There's basically a single, shared flat namespace for types.

That's why my proposal is to scrap Dave's entire proposal apart from one bit of syntax:

$var is $type

... which is just a shorthand for writing...

$type->check($var) or Carp::croak($type->get_message($var));

(Plus my proposal also includes an opt-in mechanism for the check to be optimized, avoiding the method call.)

Would also be kind of cool to allow $var is $type outside of signatures. For example, this would throw an error during the loop if it found a non-number in the array...

my $sum;
for my $n (@numbers) {
  $n is Num;
  $sum += $n;

If parameter attributes do get introduced, and if Perl sub type constraints end up being a mess (which the current proposal is, in my opinion), I'll probably try to add support for type constraints via attributes in Type::Tiny.

That works, though my original proposal was to always do

$type->check($var) or croak($type->get_message($var))

regardless of whether $type is a blessed object. check and get_message methods would be added to UNIVERSAL so that if $type was a class name, everything would just work.

I can imagine there being some resistance to adding these methods to UNIVERSAL though.

Yes, feel free to mention it on your blog.

I don't know what you mean. In that example, "Object" is a sub which returns a blessed object which has "check" and "get_message" methods, so it can be used like:

Object->check($var) or croak(Object->get_message($var))

The "compile" thing is for combining a bunch of type checks into a single coderef so a whole array (@_) can be checked in one sub call.

I used the names `check` and `get_message` because MooseX::Types, MouseX::Types, Type::Tiny, and Specio already all provide methods of those names. The idea still works with other method names, but would require updates to type frameworks to add support.

Leave a comment

About Yuki Kimoto

user-pic I'm Perl Programmer. I LOVE Perl. I want to contribute Perl community and Perl users.