Raku / old-design-docs

Raku language design documents
https://design.raku.org/
Artistic License 2.0
124 stars 36 forks source link

Shorthand Notation for Private Method Calls #107

Open Idyllei opened 8 years ago

Idyllei commented 8 years ago

On Method Calls, it is noted that dot natation can be used to omit the $ if the object which is being called is already in the $ variable.

my $foo = Foo.new( );
$foo.say; # $foo.say( );
with $foo { .say; }

However, it is illegal to use the private method sigil (!) for short calls:

my $bar = Bar.new( );
$bar!baz; # call private method !baz of $bar
with $bar {
  !baz; # WRONG! !baz == not(baz( ))
}

New Syntax (Addition)

I propose a change to the Perl 6 syntax/grammar which allows a shorthand for the calling of private methods while the object is in $_: .!priv

my $quux = Quux.new( );
$quux!priv;  # $quux!priv( );
with $quux { .!priv; }

Why?

The new syntax (which uses the ! twigil) is an attempt toward unified syntax. The ! twigil is used in classes for private data members and methods:

class Foo {
  has $!priv_member;
  sub !priv_method() {say "In Foo!priv_method()"}
}

with Foo.new( ) { .!priv_method; }  # In Foo!priv_method()

Why disallow the use of the shorthand syntax just because !priv_meth( ) doesn't work as expected? The Perl (6) language is designed to fit the needs of its users. This is a fix to do just that while providing expected functionality and uniformity.

bbkr commented 8 years ago

There are substantial errors in your request.

It is not possible to declare private subroutines, only private methods are allowed:

$ perl6 -e 'class A { sub !foo { } };'
===SORRY!=== Error while compiling -e
Missing block

It is not possible to call private method outside of class the way you wrote it:

$ perl6 -e 'class A { method !foo { } }; my $a = A.new; $a!foo'
===SORRY!=== Error while compiling -e
Private method call to foo must be fully qualified with the package containing the method

Proper way is to use fully qualified package name AND trust policy:

$ perl6 -e 'class A { trusts GLOBAL; method !foo { } }; my $a = A.new; $a!A::foo'

So your shortcut would look like:

with Foo.new( ) { .!Foo::priv_method; }

And that destroys whole "shorthand" concept, because you cannot rely solely on $_ type.