Perl Subroutine Signatures Opinion Blog

This site is an opinion blog about Perl Subroutine Signatures. Subroutine Signatures is plan to added to Perl in the near future. I have a very strong concern in the future of Perl, so I created an independent site about sub signatures. My name is Yuki Kimoto. I'm Perl Light User. I have no media power, community power, political power, and big company power. I just feel and talk about the heart of a weak perl user without a voice.
2019/12/25

Larry said "No one sews a patch of unshrunk cloth on an old garment"

When he aproved Raku naming change, Larry said .

"No one sews a patch of unshrunk cloth on an old garment, for the patch will pull away from the garment, making the tear worse. Neither do people pour new wine into old wineskins. If they do, the skins will burst; the wine will run out and the wineskins will be ruined. No, they pour new wine into new wineskins, and both are preserved."

This is a Bible quotation, but needs some explanation.

New wine means Raku features. New skins means Raku name

New wine means Raku features. New skins means Raku.

old wine means Perl features. new skins means Perl name

Old wine means Perl features. Old skins means Perl name.

New Raku features don't fit old Perl name

New Raku features don't fit old Perl name.

What did Larry want to say?

If we try to add Raku's new features to Perl name, it will break Perl.

New Raku features must be put into Raku.

Both Perl and Raku have grown up. Both is over 18 years old.

Subroutine signatures are a new feature in Perl, On the other hand, if we were to get much from Raku, it would break Perl.

Why not start again from who the Perl user is?

2019/12/24

Default value expression

In first proposal of subroutine signatures, default value is the following.

sub func($foo //= 0, $bar ||= 0) {
  
}

I think this can use only "=" as same as many ohter languages. and "||" is in body if needed.

sub func($foo = 0, $bar) {
  $bar ||= 0;
}

This expression is general in other languages.

PHP

function makecoffee($type = "cappuccino")
{
    return "Making a cup of $type.\n";
}

Python

def func_default(arg1, arg2='default_x', arg3='default_y'):
    print(arg1)
    print(arg2)
    print(arg3)

Ruby

def printHello(msg="No msg", name="No name")
  print(msg + "," + name + "¥n")
end
2019/12/23

Type Constraints using Type::Tiny and attribute handler

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) {
  
}

What is attribute handler?

The attribute handler is a function that can handle the attribute setting of subroutines and variables from Perl 5.6.

#!perl -w
use strict;

sub MODIFY_CODE_ATTRIBUTES{
  my($class, $code_ref, $attr_name) = @_;
  Dump($code_ref);
}

# Subroutine attribute
sub foo : MyAttr {

}

Perl already has a syntax called attributes.

sub foo : attribute

Attribute for arguments of subroutine signatures

We are fortunate.

Aattributes of subroutine argument are not yet implemented.

We can implement the use of subroutine attributes without worrying about the past.

It would be nice to be able to check arguments by combining a subroutine argument attribute handler with Type::Tiny.

use Type::Tiny::Signatures;

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

Perl core is all dynamic, and you can add listrictions by module

We have known for 30 years that all Perl core is dynamic.

Perl has no restrictions by default.

On the other hand, you can incorporate constraints by using modules.

For example,

fields modules for field listrictions.

Hash::Util::lock_keys for hash key listrictions.

Sure, Type::Tiny for type constraints.

This is 30 years of Perl convention.

If signatures is dynamic and, add listrictions by module and attribute handler,

We are likely to be able to work with the old and the new and solve the Perl community's dissatisfaction.

I hope that older users who have enjoyed the dynamic types of Perl can collaborate with the Perl community who wanted to do type checking.

I suggest an implementation where Type::Tiny works correctly with subroutine signatures.

Toby proposal

I discussion about Type::Tiny with Toby Inkster in blogs.perl.org.

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

2019/12/20

The way that CPAN authors use subroutine signatures in natural

Perl users contains CPAN authors, not only application users who use the new version of Perl.

Generally, CPAN authors use Perl old grammar to support older versions of Perl.

Most CPAN modules support Perl 5.8+, and Some modules support Perl 5.10+ and 5.12+.

CPAN authors also want to use subroutine signatures

Perl's new feature is for the new Perl, but when it comes to subroutine signatures, CPAN Author also maybe wants to use it.

If CPAN authors can use subroutine signatures, both application code and CPAN module code can be written in one source.

I think new features should work with the new Perl, but I'm happy that only the subroutine signature feature can be backported.

Wouldn't it be nice if you could use subroutine signatures with tens of thousands of CPAN modules?

But is there such a way?

Use signatures.pm if the perl version is lower than subroutine signatures

Use signatures.pm if the perl version is lower than Perl which support subroutine signatures.

I write the code. CPAN author can use signatures.pm instead of core subroutine signatures.

This code use SigImport. SigImport export signatures.pm features to Foo.

package Foo;

use strict;
use warnings;
use utf8;
use FindBin;

use lib "$FindBin::Bin";

use SigImport;

# Subroutine signatures imported from signatures.pm
sub func($foo) {
  return $foo;
}

package main;

print Foo::func(1, 2);

SigImport. This contains some signatures.pm fix.

package SigImport;

BEGIN {
  require signatures;
}

BEGIN {
  no warnings 'redefine';
  sub signatures::import {
    my ($class, $caller) = @_;
    $caller ||= caller();
    $pkgs{$caller} = $class->setup_for($caller);
    return;
  }
}

sub import {
  my $caller = caller;
  
   
  #if ($] >= 5.034001) {
  #  feature->import('signatures');
  #}
  #else {
    signatures->import($caller);
  #}
}

1;

This code work well. Swich signatures features by Perl version.

In this way, a more several things is needed.

the number of arguments in the subroutine signature is not checked by default

the number of arguments in the subroutine signature is not checked by default.

See also the following entry.

Risk increased by checking the number of subroutine arguments

signatures.pm is bandled to Perl core

If signatures.pm is bandled to Perl core, we can write the following in Makefile.PL

    PREREQ_PM => {
      'signatures.pm' => 0.15,
    },

CPAN authores can switch signature.pm to core subroutine signatures.

Wouldn't it be nice if you could fix the past in a subroutine signature?

2019/12/18

Is the new grammar easy to google search?

Is the new grammar of subroutine signatures easy to google search?

One of the criticisms of Perl is that "it cannot search google because it has many symbols".

Increasing the number of difficult-to-search symbols also increases the blame for Perl.

New symbol in subroutine signature

In general, unlike function names, symbols are difficult to search for google.

List new symbols in the proposal of subroutine signature.

  • @
  • %
  • !$foo
  • :$foo
  • ?$foo
  • ??$foo
  • is
  • isa
  • where
  • Is it easy to understand when a beginner reads the code?

    Can one million Perl light users easily search for google?

    Put your hand on your chest and think sincerely and honestly.

    If you think Perl is part of the Perl community, it will take mistake.

    Perl is also connected to business users and light users outside of Perl community.

    What is a good balance?

    2019/12/17

    Are array and hash representations really needed?

    Are array and hash representations really needed?

    Currently, "@foo" is proposed as the array representation. "%foo" is proposed as the representation of the hash.

    # Array representation
    sub (@foo) {
      
    }
    sub ($var, @foo) {
      
    }
    
    # Hash representation
    sub (%foo) {
      
    }
    
    sub ($var, %foo) {
      
    }
    

    Are these always necessary?

    Alternative representation using only scalar variables

    You can rewrite the above array and hash representation using only scalar variables if you need copy.

    # Array representation
    sub ($foo) {
      my @foo = @$foo;
      
    }
    sub ($var, $foo) {
      my @foo = @$foo;
    }
    
    # Hash representation
    sub ($foo) {
      my %foo = %$foo;
    }
    sub ($var, $foo) {
      my %foo = %$foo;
    }
    

    In many languages, array and hash passed as a reference

    In many languages, array and hash passed as a reference.

    JavaScript Function Definition

    At first, see JavaScript code. foo function definition.

    function foo (nums, opt) {
      
    }
    

    Ruby Function Definition

    Next, see Ruby code of foo function definition.

    def foo (nums, opt)
      
    end
    

    Python Function Definition

    Next, see Python code of foo function definition.

    def foo (nums, opt)
      
    

    PHP Function Definition

    Next, see PHP code of foo function definition.

    function foo ($nums, $opt) {
    
    }
    

    Perl

    Subroutine signature of Perl is special.

    sub ($var, @foo) {
      
    }
    
    sub ($var, %foo) {
      
    }
    

    In fact, current Perl already have reference different from past Perl.

    If it is limited to only scalar variables as arguments of subroutine signatures, alternative expressions are possible.

    What is benefit of limited only scalar variables?

    What is benefit of limited only scalar variables?

    The biggest benefit is that the subroutine signature is very simple.

    Perl is already big and complex.

    External people feel that Perl is already difficult to read and complex.

    Therefore, the subroutine signature specification, which is easy to understand, gives good evaluation when viewed from outside.

    The Perl internal community may be frustrated.

    What is good balance?

    2019/12/16

    Risk increased by checking the number of subroutine arguments

    The current subroutine signature specification checks the number of subroutine arguments.

    Many people think that this reduces the mistake of checking for incorrect argument count.

    sub foo ($args1, $args2) {
      
    }
    
    # Exception occur for argument count is difference
    foo(1, 2, 3);
    

    On the other hand, there is actually risks of increasing by checking the argument count.

    Unexpected exception due to later increase of subroutine arguments

    I yet see the discussion that unexpected exception due to later increase of subroutine arguments.

    I will explain this with a sample.

    First, a subroutine is defined with one argument.

    sub foo ($num) {
      
    }
    

    User use this subroutine in many place.

    foo(1);
    
    foo(2);
    
    foo(3);
    

    After a while, you want to pass options to this function and change the code to:

    sub foo ($num, $opt) {
      $opt //= {};
    }
    

    The user believes it is the same as the following change:

    # Before
    sub foo {
      my ($num) = @_;
    }
    
    # After
    sub foo {
      my ($num, $opt) = @_;
    }
    

    Long-time Perl users know that this change doesn't break the source code and this is how it works.

    This change is a long practice for Perl users and has been going on for a long time.

    On the other hand, checking the number of arguments in a subroutine signature yields different results.

    # Unexpected exception
    foo(1);
    
    # Unexpected exception
    foo(2);
    
    # Unexpected exception
    foo(3);
    

    "The program is broken. An exception is thrown in an unexpected place!"

    There is a risk of adding unexpected bugs by checking the number of subroutine arguments.

    Should I use the default value?

    Such an answer seems to be returned to the above problem.

    "Should I use the default value?"

    sub foo ($num, $opt = {}) {
    
    }
    

    This is work well in fact.

    What is the problem I feel about this?

    This is unintended behavior for users who have been using Perl for a long time.

    Perl users generally do not expect Perl to be constrained.

    Perl users expect that there are no constraints by default.

    The presence of constraints by calling the module is the user's choice, but the subroutine signature is a core feature.

    If Perl user write the following for long-standing habits, code is broken.

    sub foo ($num, $opt) {
      $opt //= {};
    }
    

    "Oh, in production code, an unexpected exception has occurred! Subroutine signature increases unexpected risk!"

    Are we just thinking that adding constraints reduces the risk of mistakes?

    Want to add to the discussion that an unexpected exception can break your production code?

    Do Perl subroutine signatures require a constraints of number of arguments?

    Isn't it essential?

    Is checking the number of subroutines compatible with Perl's dynamic mechanism?