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

Okay, rather than being patient enough to wait for all N Apocalypses, Exegesises (Exegei?), and/or Camel 4, I'm trying to understand them as they come out.

And I totally don't get the binary := operator.

Apocalypse 3 says of the binary := operator "it treats the left side as a set of formal arguments exactly as if they were in the declaration of a function, and binds a set of arguments on the right hand side as though they were being passed to a function."

Which I have to admit I just don't understand. Later it's treated as an alias. Exegesis 3 affirms this understanding: "Perl 6 provides a more direct mechanism for aliasing one variable to another in this way: the :="

Great. But aside from being able to shorten names I'm typing out (which I can do with references, and will be able to do more easily in Perl6 with auto-dereferencing), what benefit do I get? Sadly, the examples cited are either from languages I don't use, or refer to swapping arrays. (which I'm not sure I get: Can't I do (@a , @b) = (@b, @a) now that lists either are or are not flattened?)

What is the scope of an alias? How does (@a, @b) := (@b, @a) differ from (@a, @b) = (@a, @b)?

Am I not understanding what an alias is? How is $bound := %data{$key} different than $bound = \%data{$key}

Are the parameters to an alias (Or "bound variable" which I guess is more appropriate) evaluated at evaluation time? Would $bound := %data{$key} give me a different $bound as $key changed?

I'm sure this is a very powerful construct, but I really feel I'm missing something.

Replies are listed 'Best First'.
Re: Comprehending Binary :=
by demerphq (Chancellor) on Oct 06, 2001 at 16:38 UTC
    Hi swifttone,

    (which I'm not sure I get: Can't I do (@a , @b) = (@b, @a) now that lists either are or are not flattened?)

    Nope. Not according to Exegesis and comments made in the thread Apocalypse 3. According to those comments the slurp behaviour of = hasn't changed.

    What is the scope of an alias?

    Good question. I'd like to know that too.

    Am I not understanding what an alias is? How is $bound := %data{$key} different than $bound = \%data{$key}

    Well, lets say %data{$key}="Foo", then in the first case $bound would also equal "Foo", but in the second case $bound would be refrence to the string "Foo" and thus to get at the string would be $$bound="Foo". There were more intuitive examples in Exegesis, like @bound := %data{$key} which would make @bound be an aliase for the array that %data{$key} refrences.

    Would $bound := %data{$key} give me a different $bound as $key changed?

    Judging by the fact that TheDamian mentioned using aliases as a form of the Pascal/Basic with sturcture, (Yahh!) I would assume so. Which I guess basically answers the earlier question regarding scoping issues, ie that an alias would have to be a scoped entity, but frankly if it is scoped then there are going to be some weird side effects. Like what happens if you declare a variable then alias that varible to something else inside a scope, after the scope does the variable go back to the original value? So that means it could be used to in effect localize a lexical variable, which could get _real_ confusing. :-)

    Great questions, I hope TheDamian steps in to clear these points up.

    Yves
    --
    You are not ready to use symrefs unless you already know why they are bad. -- tadmc (CLPM)

      What is the scope of an alias?

      The aliasing persists until the lvalue of the binding ceases to exist. Typically, I think, people will prefer to bind lexicals, so typically the scope will be till the end of their lexical block.

      Would $bound := %data{$key} give me a different $bound as $key changed?

      No. The binding is static and early. That is, the rvalue is evaluated, a reference is taken to the result, and that reference is installed in the lvalues symbol table entry.

      Damian

Re: Comprehending Binary :=
by Masem (Monsignor) on Oct 06, 2001 at 15:35 UTC
    Basically, the := operator is a lazy assignment, which means that, in a conceptual manner, the calculation/operation is not really done until the result is absolutely needed as opposed to '=' and being done right then and there (from an implimentation standpoint, I would not be surprised to see that lazy evaluations are 'flattened' into the actual locations where needed.).

    If you've ever used a symbolic math program like Maple, Mathematica, or Mathcad, you're probably familar with this idea already. If not, then consider that using := is similar to an algebric statement; that is, if I say "$y := $x - 5", then y will ALWAYS being x - 5 until I redefine it or it goes out of scope.

    A better example would be how to use this to simplify conversions from a database when needed. Without lazy evaluation:

    while ( my ( $name, $height, $weight ) = $sth->fetchrow_array() ) { my $ratio = $height/$weight; send_to_html( $name, $ratio ); }
    With lazy eval:
    my ( $name , $height, $weight ); my $ratio := $height/$weight; # I would presure that # this would need to be # done under -w/strict send_to_html( $name, $ratio ) while ( $name, $height, $weight ) = $sth->fetchrow_array() );
    This may not seem as powerful now, but there's a lot of potental for it.

    Now, in regard to your swap example, the behavior there is currently undefined in that you're creating circular references with lazy evaluation (Just like you can do in Excel). I expect this to flag a runtime error , possibly a compile-time error. But until we have Perl 6 in our hands, we won't know for sure.

    Update as pointed out below, I got myself confused with the := operator and perl laziness.

    -----------------------------------------------------
    Dr. Michael K. Neylon - mneylon-pm@masemware.com || "You've left the lens cap of your mind on again, Pinky" - The Brain
    It's not what you know, but knowing how to find it if you don't know that's important

      I think not.

      Larry Wall's use of the word "unification" gave me similar hopes. However TheDamian's comment at Re: Re (tilly) 1: Apocalypse 3 put me straight, and then his comparison with typeglob aliasing made it obvious.

      Perl 5 has typeglobs. Perl 6 will not, but needs an equivalent way to do the same thing. := is the answer that they came up with.

      But since it is aliasing if you, for instance, try:

      $y := $x - 5;
      what will happen is that $x - 5 is calculated, that goes into a new (constant) variable, and then $y is aliased to that constant. If you later change $x, $y is still aliased to the constant.

      Sorry.

        Okay, so if I'm understanding these comments correctly (which is not guaranteed since I don't grok typeglbos and I've never touched Prolog or used a "with" statement, we're back to := just saving keystrokes. It isn't lazily evaluated.

        Which just doesn't seem right, I have to be missing something.

        So how is $bound := %data{$key} different from $bound = \%data{$key} aside from the latter being a reference? (And since we'll have automatic dereferencing to the expected context, that shouldn't be a problem, correct?)

        I now see that = still slurps, so (@a, @b) := (@b, @a) isn't easily reproduceable, and thus we have a clear use for :=....but is that really the extent of it?

      Weird. I'm utterly at a loss as to how you got this interpretation for the := operator from Exegesis 3 or from Apocalypse 3

      I dont think this new operator has anything to do with lazy evaluation. My reading of these docs is that it is fairly straightforward aliasing going on.

      Consider Exegesis clearly states that

      (@x,@y):=(@y,@x);
      is an efficient way to swap the contents of the two arrays. It would do this by simply aliasing the variable name @x with the array that the variable name @y refers to, and vice versa.

      tilly suggested that Re: Re (tilly) 1: Apocalypse 3 may be useful in understanding our different views :-)

      Yves
      --
      You are not ready to use symrefs unless you already know why they are bad. -- tadmc (CLPM)

      if it is really easily evealuated it wll be cute, i didn't thought it will work that way :")
      That way it will be possible to say :

      $x := $y + 5; ...code... $x := $z + 12 if cond1; ...code... $x := 6 + $p if cond2; ...code... print $x

      Now think if both cond1 and cond2 succeed ... in a normal assigment u will calculate $x three times.(what if the calculation is very complex).
      In our case it will be calculated only when we call 'print'..
      On the other hand using several subs for this thing is waste, not to mention that the call to sub is slow... So if I'm right := is/can-be-used-as :

      1. binding
      2. alaising
      3. simple-sub (mostly for expressions)
      4. assignment
      any other ideas.. :")

      =====
      raptor
Re: Comprehending Binary :=
by raptor (Sexton) on Oct 06, 2001 at 19:56 UTC
    I had the same question on perl-language list, and here is theDamian answer :

    > Is the following correct for := :
    >
    > left side is like function in the respect that the right side is treated
    > differently depending on the left-side-types i.e. left side is like
    > prototype!! for the right side.
    Yep.
    > (@a ,@b) := (@b,@a)
    > is the same as :
    > (\@a, \@b) = (\@b, \@a);#if we had ref-allowed on the
    left in perl5 of > cource :")

    Yep.

    > ($x,@y) := (@b, @a)
    > is the same as :
    > ($x, \@y) = ($b[0],\@a);

    Nope. The $x lvalue confers scalar context on the first rvalue, so it's the same as:

    ($x,\@y) := (\@b, \@a)

    > Which is most close explanation : BIND or ALIAS

    It's a bind *and* an alias! ;-)

Re: Comprehending Binary :=
by raptor (Sexton) on Oct 06, 2001 at 20:52 UTC
    hi,

    one other way to think about it is possibly if u think for the left side as sub-head and the right-side as the body of the function...
    If we extend the notion in some way it may become pretty close to Prolog ':-' i.e. :

    ($a,$b) :- $a > 10 && print $b;
    Prolog variant will look like this I think :
    name(A,B) :- A > 10, print B;
    I'll be glad if it is extended in such way, even I don't know what can-of-worms this can open..>>