http://qs1969.pair.com?node_id=279544

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

There is something I dont understand in the new Exegesis, namely (page 7 bottom):
# Named binding... ($who, $why) := (why => $because, who => "me"); # same as: $who := "me"; $why := $because;
This makes no sence to me. Simply because a pair has the same key value as one of the variables on the left side, it is assigned to that?
So what if I happen to use this snippet in my "legacy" code: ($goats, $sheep) := part Animal::Cat, @animals
Then simply because of my naming of the variables I assign to, I would get the reverse result? (as in, $sheep in this case would contain the same data, as in the case where it was ($sheep, $goats) := ...)
Can anyone explain why this is a good idea?
But then again, if perl6 changes the order of hashkeys as often as perl5, then it would break with every release anyway ;) I do believe he should have used
return $sheep => %herd{$sheep}, $goats => %herd{$goats}; instead of return *%herd;

Secondly:
*%details = (who=>"me", why=>$because); # same as: %details{who} := "me", %details{why} := $because;
makes no sence to me either, unless a colon is missing as in
*%details := (who=>"me", why=>$because);


T I M T O W T D I

Replies are listed 'Best First'.
Re: Exegesis 6 - Named binding
by broquaint (Abbot) on Jul 31, 2003 at 13:10 UTC
    Simply because a pair has the same key value as one of the variables on the left side, it is assigned to that?
    I believe this is so we have behaviour orthogonal to that of named sub/method/etc parameters. As you can pass named parameters into a sub and it will do the right thing e.g
    sub func(Int $this, Str $that) { ... } func(279544, "a string"); ## or with named parameters func(that => 'thing you do', this => 0xdeadbeef);
    So we don't need to maintain order of the arguments we pass in as perl6 will do the right thing and alias the arguments to correct positions in the parameter list. Now when we do named binding it's pretty much the same thing, but without the sub call e.g
    ($this, $that) := ( 279544, 'a string' ); ## or with named parameters ($this, $that) := (that => 'thing you do', this => 0xdeadbeef);
    Also notice that both the parameter list and the named binding alias their arguments as well as putting the arguments in the right place.
    Then simply because of my naming of the variables I assign to, I would get the reverse result?
    If you're performing a simple assign, then yes, the reversing of the variables that are being to assigned to will get the reverse data (same as perl5). But of course if you bind instead and the return is a list of pairs then it should DTRT e.g
    sub &part(Selector $is_sheep, *@data) { ## body here return *%herd; } ($goat, $sheep) = part Animal::Cat, @animals;
    Now regardless of the order of the LHS, the values should be bound correctly as the flattening of %herd produces a list of pairs.
    makes no sence to me either, unless a colon is missing as in
    Indeed, because without the binding colon you don't get the named binding behaviour. I'll speculate that it'll empty out %details and then assign it whatever is on the RHS.
    HTH

    _________
    broquaint

    Disclaimer: IANAP6DG (I Am Not A Perl6 Design Guru ;)

      makes no sence to me either, unless a colon is missing as in
      Indeed, because without the binding colon you don't get the named binding behaviour. I'll speculate that it'll empty out %details and then assign it whatever is on the RHS.
      Well, there are two things it could do. Either it is the same as %details{who} = "me", %details{why} = $because, which would make sence because of the unary * operator or it would be the same as %details = ();%details{who} = "me", %details{why} = $because, but then what usage is the * operator?

      T I M T O W T D I
        Either it is the same as %details{who} = "me", %details{why} = $because, which would make sence because of the unary * operator or it would be the same as %details = ();%details{who} = "me", %details{why} = $because
        The reason I suspect it to be behave like the latter is because the flattening behaviour of the * in this context. If we broke it down it might look something like this
        %data = << why dunno who them where there which this >>; *%data = ( who => 'me', why => 'because' ); ## which if we expand the splat expands to (I think) %data.kv = ( who => 'me', why => 'because' );
        That of course assumes the kv method is lvaluable, but basically it looks like it's assigning all of %data to the RHS. Whereas with named binding it will just be the keys who and why which are bound, otherwise we assume that named binding behaviour is also used in straight assignments, which isn't the case. Again this is all speculation, but I'm hoping it's not too far off, or at least raising some interesting issues. Perhaps in this particular instance the splat is a no-op, or maybe it's a slurp and %data isn't run-over (but that would in turn make the assignment look like a right-to-left pipe ...).
        HTH

        _________
        broquaint

      I asked about this in #perl, and the consesus seems to be that it does not clear %details, because
      sub part (Selector $is_sheep, Str *%labels = (sheep => "sheep", goats => "goats"), *@data ) returns List of Pair { ... }
      would just do the wrong thing if called as part sheep=>"horse", Animal::Horse, @animals

      Update: Just to make it clear, I'm talking assignment here, not binding.



      T I M T O W T D I
Re: Exegesis 6 - Named binding
by Elian (Parson) on Jul 31, 2003 at 14:09 UTC
    There is something I dont understand in the new Exegesis, namely (page 7 bottom):
    # Named binding... ($who, $why) := (why => $because, who => "me"); # same as: $who := "me"; $why := $because;
    This makes no sence to me. Simply because a pair has the same key value as one of the variables on the left side, it is assigned to that?
    Not assigned, bound. Binding in perl 6 does the same thing as the aliasing of foreach's loop variable, only you can do it everywhere. Once you execute this statement, $why and $because are essentially the same variable--they both point to the same underlying structure. $who is bound to the constant "me", which means printing $who prints "me" and trying to assign to it throws an error because you're trying to assign to a constant.

    Perl 6 is making a string distinction between the name of a variable and the structure of the variable. Assignment copies the contents of one structure to another, while binding changes what structure a variable name refers to.

      This actually brings up another question - Will there be an equality operator that distinguishes between value equality and binding equality? For example, I want to know if $who is bound to $because vs. $who being == or eq to $because ...

      ------
      We are the carpenters and bricklayers of the Information Age.

      The idea is a little like C++ templates, except not quite so brain-meltingly complicated. -- TheDamian, Exegesis 6

      Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.

        Last I knew the decision was that testing for identity wasn't going to be common enough to warrant an operator. I think instead there'll be some UNIVERSAL method that returns a unique widget that you can use to test--.is or .ref, or something along those lines.

        In Perl 5 you can already use \$x == \$y to test whether $x and $y are aliases of each other. I would think such would also work in Perl 6 but I don't follow Perl 6 deeply so I could certainly be wrong.

                        - tye
      Ups, wrong choice of words. Offcourse meant to write bound after all I am using the binding operator :=.

      T I M T O W T D I
        Then the answer's yes--because the key has the same name as the variable on the left side of the assignment that key's value is bound to the variable. That's how it's supposed to work, as it means you don't have to rely on hash ordering or manual looping over the RHS. It's essentially named arguments for binding, though I can see cases where it wouldn't necessarily be what you want to do...