Hi Brian (and Bruce),

Just a short note to say that we had a conversation entitled "Extra .
needed" on this mailing list a few weeks ago, for which the solution
(per Brad Gilbert) was a sort of "double-dereferencing" (for lack of a
better terminology):

https://www.nntp.perl.org/group/perl.perl6.users/2021/01/msg9605.html

To my eyes there seems to be a (possibly distant) relationship between
Brian's issue and Richard's issue from a few weeks ago. Anyone care to
comment? And is there a unifying principle that can be distilled
out...to help new (and not-so-new) users?

Best, Bill.



On Tue, Jan 19, 2021 at 12:27 PM Bruce Gray <robertbrucegr...@gmail.com> wrote:
>
>
>
> > On Jan 19, 2021, at 12:18 PM, Brian Duggan <bdug...@matatu.org> wrote:
> >
> > Hi Folks,
> >
> > I ran into this situation today, which seems counterintuitive:
> >
> > my @one = 1,2,3;
> > my @two = 4,5,6;
> > my @both = @one,@two;
> > my @first = @both[0];
> > say @one.raku;
> > say @first.raku;
> >
> > output:
> >
> >       [1, 2, 3]
> >       [[1, 2, 3],]
> >
> > I was expecting @first and @one to be the same.
>
> I agree that @first not equalling @one is a bit counterintuitive, since the 
> formation of @both as a two-element array, and the extraction of its first 
> element, seems to be exact opposite operations.
> In fact, let’s make it even more exactly opposite:
>         my @one = 1,2,3;
>         my @both;
>         @both[0] = @one;        # Stuff it into first element
>         my @first = @both[0];  # Yank it out of first element
>         say @one.raku;
>         say @first.raku;
> This produces the same output as your original code, even though the two 
> commented lines appear to cancel (like in algebra) to produce an identical 
> result.
>
> But wait! This version makes this issue clearer (at least to my 
> Raku-accustomed eyes).
> The first commented line is a version of this:
>         $scalar_var = @some_array;
> , in which $scalar_var _captures_ @some_array during the assignment. (Similar 
> to “references" in Perl: `$z = \@y;`)
> To exactly invert, we need to also counteract the capturing in the second 
> commented line.
> (continued below)
>
> > I discovered that I could instead write either of these --
> >
> >  my (@first) = @both[0];
> >  my @first := @both[0];
> >
> > or I could change the @both assignment to be
> >
> >       my @both := @one, @two;
>
> To discuss those three alternatives, let’s extend your original code:
>         my @one = 1,2,3;
>         my @two = 4,5,6;
>         my @both = @one,@two;
>         my @first = @both[0];
>         say @one.raku;
>         say @first.raku;
>
>         my (@a) = @both[0];
>         my @b  := @both[0];
>         my @both_bound := @one,@two;
>         my @c  := @both_bound[0];
>         say .raku for @a, @b, @c; # They all look right, but only because 
> nothing wrote to them.
>         @a[1] = 7; say @one;      # [1 2 3] , independent as expected
>         @b[1] = 8; say @one;      # [1 8 3] , bound/aliased!
>         @c[1] = 9; say @one;      # [1 9 3] , bound/aliased!
>
> The first form, `my (@array) = …`, I read as quite clever (as in “I didn’t 
> think of it myself”). it does what I think you intended.
> Our community is still in the idiom-forming phase, but this would not be a 
> preferred form for me.
> I think that is (mostly?) due to it being a LHS-manipulation, so it cannot 
> easily work as part of a larger expression without some temp array on the 
> left-hand side.
> [
>         I admit that part of my dislike is because it looks too much like 
> this from Perl:
>                 my ($only_want_the_first_element) = @some_array;
>         , and having a @-sigiled variable inside that expression looks like a 
> a redundant use of parens.
>         Please give zero weight to that biased part of my assessment.
> ]
>
> The second and third forms both use “binding”, which would be fine if “live 
> links” between @one and @first was your need and intention, but would be a 
> source of bugs otherwise.
> Your original code looks like you want @first to contain independent copies 
> of the @one elements.
> If I were refactoring your code, I would not assume that changing assignment 
> to binding would be OK to do.
> (I suspect that you already knew that, and were just showing us all of the 
> variants that “worked”)
>
> > ..but I wonder if there's an idiomatic approach -- or
> > way of thinking about this -- that makes this flow more
> > intuitive.
>
> (continued from above)
> I would probably write it as:
>         my @first = @both[0].list;
> , but for this exact case I might instead say:
>         my @first = @( @both[0] );
> . They do the same thing here, and both look idiomatic to me,
> but .list looks like an action/command to @both[0],
> and @(...) is the List Contextualizer,
> so which one I would use would depend on the surrounding code,
> and who I expected to be reading the code.
>         https://docs.raku.org/type/Any#index-entry-@_list_contextualizer
>
> So, I recommend .list or @(…) as more intuitive, maybe even *sufficiently* 
> intuitive :^)
>
> > thanks
> > Brian
>
> —
> Hope this helps,
> Bruce Gray (Util of PerlMonks)
>

Reply via email to