http://www.perlmonks.org?node_id=435074


in reply to Perl6 dot syntax (for methods?)

All of this is laid out here, and this particular item is in the invocant parameter section. But let me see if I can explain it for you.

Invocant parameters allow you to associate an argument* (usually the first one) with a subroutine. In a very round about way, you could view this as dynamically adding a method to the class of the invocant, however that is not really what is happening (although it is kind of what it looks like).

The synopsis describes the invocant parameter syntax as having a colon after the invocant parameter. However, the colon is apparently implied with all subs. So this code:

sub foo ($x) { say($x) }
is actually equivalent to this code:
sub foo ($x:) { say($x) }
Which will allow it to be called "hello world".foo. Still another way to view this would be that it's Reverse Polish Notation perl ;)

To be honest, I am not sure I like this feature 100% myself. It does give things a weird look, and you are correct in that it seems to be OO, when its not OO. However, it is worth keeping in mind that AFAIK, all types in perl 6 will be objects, and that the runtime will perform all the neccessary autoboxing DWIMery. So even if you are not doing OO, you are using OO.

Now as for the *$x, *@xs code, I can answer that pretty easily. When you apply a * to a parameter, it becomes slurrpy. Since perl 6 has named parameters, argument lists don't flatten as they do in perl 5. So in order to do the common perl trick of slurping all the args into an array or hash, they introduced this syntax. This is discussed in the "Flattening argument lists" section of Synopsis 06. In that section they show how you can force a list to be flattened when you pass it into a subroutine.

sub foo($x, $y, $z) {...} # expects three scalars @onetothree = 1..3; # array stores three scalars foo(1,2,3); # okay: three args found foo(@onetothree); # error: only one arg foo(*@onetothree); # okay: @onetothree flattened to thr +ee args
In the quicksort code, it is doing the reverse, and saying that it should slurp up anything that is passed into it. First the *$x slurps up a scalar (which is just one element). This is not unlike just saying $x although they are not interchangable (don't as my why, I am still trying to grok details like this myself). The second parameter *@xs then slurps up a array, which in effect slurps up the rest of the arguments. Again, remember that perl 6 has formal parameters, and that
sub perl6foo ($bar, $baz) { }
is very different from
sub perl5foo { my ($bar, $baz) = @_; }
So it is best not to view them as even remotely equivalent.

I hope this helps (and not hurts) as I am still trying to digest much of this stuff myself.

* Actually the argument's type since you cannot and would not want to bind to a specific literal argument itself
-stvn

Replies are listed 'Best First'.
Re^2: Perl6 dot syntax (for methods?)
by Ven'Tatsu (Deacon) on Feb 28, 2005 at 16:26 UTC
    This is not unlike just saying $x although they are not interchangable (don't as my why, I am still trying to grok details like this myself).

    There are two differences that I can see between *$x and $x. The first is parameter checking:

    sub fooprintf (*$fmt, *@args) { ... } sub barprintf ($fmt, *@args) { ... } $foramt = '%5d %10s'; @data = (16, "baz"); @both = ('%5d %10s', 16, "baz"); fooprintf($format, @data); #this works fooprintf(@both); #so will this barprintf($format, @data); #this works barprintf(@both); #this won't work barprintf(*@both); #but this will

    fooprintf will take any LIST of arguments and will just trust you the the first item in the (flatened) list is a scalar, while barprintf will force you to give it a scalar as it's first argument, or force you to flaten any arguments you pass it your self. In some cases this could catch at compile time errors that Perl5 would not have caught until runtime. (can you see the uncaught error in printf $format @data or the reverse printf $filehandle, @both?)

    The other issue is context, ponder these:

    fooprintf(localtime); #localtime is called in array context barprintf(localtime); #localtime is called in scalar context

    If your intent was to print out the current seconds then the fooprintf will work, if however you were looking for the strigified representation of the current time barprintf is will likely be closer to what you expected.

      In Perl5, the contexts are called scalar and list, despite the fact that wantarray is misnamed. Is this going to change in Perl6? Will there be an array and a list context that are separate and distinct? Or was "array context" simply a slip-up?