Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight

Perl6 dot syntax (for methods?)

by Thilosophy (Curate)
on Feb 28, 2005 at 05:33 UTC ( #434972=perlquestion: print w/replies, xml ) Need Help??

Thilosophy has asked for the wisdom of the Perl Monks concerning the following question:

Fellow monks,

now that Perl6 is suddenly all around us, can someone explain to me the new . syntax for subroutine calls? I was under the impression that this is the replacement for Perl5's ->, making it more compatible with conventions in many other languages (such as Java), and being somewhat reserved for use in object-oriented programming.

But looking at the Perl6/Pugs quicksort example it seems to be okay to use it for normal function calls as well (as opposed to the current -> whose usage outside of OO is frowned upon).

use v6; multi sub quicksort ( ) { () } multi sub quicksort ( *$x, *@xs ) { my @pre = @xs.grep:{ $_ < $x }; my @post = @xs.grep:{ $_ >= $x }; (@pre.quicksort, $x, @post.quicksort); } (1, 5, 2, 4, 3).quicksort.say;
Is there a reason why that last line is not written
say quicksort (1, 5, 2, 4, 3);
Please enlighten your brother in his confusion (and I have not even started to ponder about the many new ways to specify argument *$x, $@xs).

PS: Multi subs are cool.

Replies are listed 'Best First'.
Re: Perl6 dot syntax (for methods?)
by PodMaster (Abbot) on Feb 28, 2005 at 06:29 UTC
      Basically @array is an object (everything is an object).

      Oh my, now I am getting even more confused...

      (1, 5, 2, 4, 3).quicksort.say;

      So, quicksort and say are methods of the array class? Or of the base object class? Because if they are not, I think the normal functional syntax is more appropriate. Especially if everything is (or can be treated as) an object, should we not be extra careful about what really is a method and what is not?

        They are methods of the list class, at least here, at least as far as I understand it.

        My understanding is also that the operator forms multi-dispatch to the appropriate methods according to their arguments.

        FWIW, you can do this sort of thing in Perl5 as well; see autobox.
        So, quicksort and say are methods of the array class? Or of the base object class?

        I think both of them are methods of the array abstract base class. I mean, similar semantics and syntax is pretty common, and very familiar in other scripting languages. At least, Python does this:

        >>> q=[2,3] >>> p=[1,q,3] >>> p[1].append('xtra') >>> p [1, [2, 3, 'xtra'], 3]


Re: Perl6 dot syntax (for methods?)
by stvn (Monsignor) on Feb 28, 2005 at 14:57 UTC

    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
      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?

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://434972]
Approved by kvale
Front-paged by grinder
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (5)
As of 2020-09-28 09:39 GMT
Find Nodes?
    Voting Booth?
    If at first I donít succeed, I Ö

    Results (143 votes). Check out past polls.