Re: Perl 5 list assignment idiom

2021-11-13 Thread rir


On Mon, Mar 13, 2017 at 11:32:25AM -0700, Sean McAfee wrote:
> In Perl 5 ...

> 1 == (my ($script) = $page->find('//script'))
>   or die "Other than exactly one script element found";

> Can a similar expression that avoids an intermediate array variable be
> written in Perl 6?

This does that:

1 == ( my $script = {1,}() ).elems or die 'Not a 1 element list.';

Rob


Re: list assignment

2021-01-20 Thread Parrot Raiser
The fundamental problem here seems to be the imprint of Perl's
behaviour on the mental model. Assigning arrays flattens them into a
list of their contents, which then gets used as input to the
assignment. That means that more complicated structures, such as
arrays of arrays need some faking.

Raku approaches arrays as thingies in their own right, so the
subconcious assumptions are no longer valid.  Vocalising the actions
of the code, (even if just internally) will probably overlay the old
model in time, (though the palimpsest may show through in unguarded
momants).

On 1/19/21, Ben Davies  wrote:
> On 2021-01-19 2:18 p.m., Brian Duggan 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 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;
>>
>> ..but I wonder if there's an idiomatic approach -- or
>> way of thinking about this -- that makes this flow more
>> intuitive.
>>
>> thanks
>> Brian
>
> Arrays always containerize their values with Scalar ("itemize"). This
> means that when they contain arrays as values, each array will get
> treated like a singular value that happens to be an Array instead of an
> array of values like they normally would elsewhere.
>
> Lists keep their values' containers as-is. These are what the , operator
> returns by default, so one way to leverage containers here is to bind to
> @both like you already discovered:
>
> my @both := @one, @two;
>
> Another is to type @both as a List and assign:
>
> my @both is List = @one, @two;
>
> But List lacks some of the luxuries Array provides over it, such as
> mutability and typed values. What I'd do here is decontainerize @both[0]
> with the <> postfix operator so @both's Array typing can be kept:
>
> my @first = @both[0]<>;
>
>


Re: list assignment

2021-01-19 Thread Ben Davies

On 2021-01-19 2:18 p.m., Brian Duggan 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 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;

..but I wonder if there's an idiomatic approach -- or
way of thinking about this -- that makes this flow more
intuitive.

thanks
Brian


Arrays always containerize their values with Scalar ("itemize"). This 
means that when they contain arrays as values, each array will get 
treated like a singular value that happens to be an Array instead of an 
array of values like they normally would elsewhere.


Lists keep their values' containers as-is. These are what the , operator 
returns by default, so one way to leverage containers here is to bind to 
@both like you already discovered:


my @both := @one, @two;

Another is to type @both as a List and assign:

my @both is List = @one, @two;

But List lacks some of the luxuries Array provides over it, such as 
mutability and typed values. What I'd do here is decontainerize @both[0] 
with the <> postfix operator so @both's Array typing can be kept:


my @first = @both[0]<>;



Re: list assignment

2021-01-19 Thread William Michels via perl6-users
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  wrote:
>
>
>
> > On Jan 19, 2021, at 12:18 PM, Brian Duggan  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 

Re: list assignment

2021-01-19 Thread Ralph Mellor
Food for thought...

Python:

one = 1,2,3
two = 4,5,6
both = one,two
first = both[0]
print(one) # (1, 2, 3)
print(first)   # (1, 2, 3)

Python's `=` operator is like Raku's `:=`.

my @one := 1,2,3;
my @two := 4,5,6;
my @both := @one,@two;
my @first := @both[0];
say @one.raku;   # (1, 2, 3)
say @first.raku;  # (1, 2, 3)

Precisely the same result.

Assignment introduces mutability, is O(N) in both time
and space, and adds Scalars. Do you really need that
additional overhead for the sake of saving a character?

Binding maintains status quo on (im)mutability of values,
is O(1) in both time and space, and doesn't add Scalars.

I think binding will become increasingly used idiomatically
and it's a natural for your code, whether you use it for just
the one line or for all of them.

love, ralph


Re: list assignment

2021-01-19 Thread Brian Duggan
Thanks everyone for the thoughtful replies.

I think this helped me the most --

On Tuesday, January 19, Vadim Belman wrote: 
> We have a documentation section on this: 
> https://docs.raku.org/language/list#Itemization

  "itemization in Arrays is assumed"

  ...

  "It was decided all those extra dollar signs and parentheses were more
  of an eye sore than a benefit to the user. Basically, when you see a
  square bracket, remember the invisible dollar signs."

With this in mind, using Bruce's suggestion of @( @both[0] ) makes
sense -- (though maybe because it reminds me of @{ ... } from Perl 5)

Brian


Re: list assignment

2021-01-19 Thread Bruce Gray



> On Jan 19, 2021, at 12:18 PM, Brian Duggan  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)



Re: list assignment

2021-01-19 Thread Vadim Belman
Hi,

I would like to give a perspective a bit different to what yary provided.

Your example here can be golfed down to:

my $a = [1,2,3];
my @v = $a;
say @v; # [[1,2,3],]

The reason for this behavior is $a being a scalar container. Correspondingly, 
when you  assign it to @v the assignment op see a single element, not a 
positional. So, it behaves correspondingly. Apparently:

my @v = [1,2,3];
say @v; 

Do what's expected. The reason is [1,2,3] on RHS is a positional. It's a 
non-containerized value. So, if we put one and one together we come to the 
following assignment: 

my @v = $a<>;
say @v; # [1,2,3]

Because by stripping of the container with <> operator we get a positional on 
RHS. Now, if we unroll it all back your case, the only thing we should remember 
is that arrays containerize any value assigned into them. I.e.:

constant foo = 4;
my @v;
@v[0] = foo; 
say 4.VAR.^name; # Int
say @v[0].VAR.^name; # Scalar

Therefore, when you do @first = @both[0] – it is equivalent to @v = $a in the 
first example.

We have a documentation section on this: 
https://docs.raku.org/language/list#Itemization

Best regards,
Vadim Belman

> On Jan 19, 2021, at 1:18 PM, Brian Duggan  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 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;
> 
> ..but I wonder if there's an idiomatic approach -- or
> way of thinking about this -- that makes this flow more
> intuitive.
> 
> thanks
> Brian
> 



Re: list assignment

2021-01-19 Thread ToddAndMargo via perl6-users

On 1/19/21 10:42 AM, yary wrote:

Let's dig in a little

  my @one = 1,2,3;
  my @two = 4,5,6;
  my @both = @one,@two;

at this point @both is an array containing two arrays

 > dd @both
Array @both = [[1, 2, 3], [4, 5, 6]]

Showing that assigning into an array variable gives an array, each 
element of which can itself be an array.


What is @both[0] - ah it is an array

 > dd @both[0]
Array @both = $[1, 2, 3]

So I expect assigning it intoan array to result in an array containing a 
single array


 > my @first = @both[0];
[[1 2 3]]
 > dd @first
Array @first = [[1, 2, 3],]


And if I want it to match the original @one array, then I should 
retrieve from index 0


 > dd @first[0]
Array @first = $[1, 2, 3]
 > dd @first[0] === @one
Bool::True

When you use binding := Raku no longer puts items into a new container, 
it makes the thing on the left an alias for the thing on the right. No 
new container means no outer array holding things assigned to it.


That all matches my intuition... does it help you?

-y


On Tue, Jan 19, 2021 at 1:18 PM Brian Duggan > 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 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;
 >
 > ..but I wonder if there's an idiomatic approach -- or
 > way of thinking about this -- that makes this flow more
 > intuitive.
 >
 > thanks
 > Brian


Hi Brian,

As Yary already pointed out, you created an array of arrays:

my @one = 1,2,3;
my @two = 4,5,6;
my @both = @one,@two;
my @first = @both[0];

say @first.raku;
[[1, 2, 3],]

say @both[0]
[1 2 3]

say @both[1]
[4 5 6]

say @both
[[1 2 3] [4 5 6]]

-T




Re: list assignment

2021-01-19 Thread yary
Let's dig in a little

 my @one = 1,2,3;
 my @two = 4,5,6;
 my @both = @one,@two;

at this point @both is an array containing two arrays

> dd @both
Array @both = [[1, 2, 3], [4, 5, 6]]

Showing that assigning into an array variable gives an array, each element
of which can itself be an array.

What is @both[0] - ah it is an array

> dd @both[0]
Array @both = $[1, 2, 3]

So I expect assigning it intoan array to result in an array containing a
single array

> my @first = @both[0];
[[1 2 3]]
> dd @first
Array @first = [[1, 2, 3],]


And if I want it to match the original @one array, then I should retrieve
from index 0

> dd @first[0]
Array @first = $[1, 2, 3]
> dd @first[0] === @one
Bool::True

When you use binding := Raku no longer puts items into a new container, it
makes the thing on the left an alias for the thing on the right. No new
container means no outer array holding things assigned to it.

That all matches my intuition... does it help you?

-y


On Tue, Jan 19, 2021 at 1:18 PM Brian Duggan  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 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;
>
> ..but I wonder if there's an idiomatic approach -- or
> way of thinking about this -- that makes this flow more
> intuitive.
>
> thanks
> Brian


list assignment

2021-01-19 Thread Brian Duggan
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 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;

..but I wonder if there's an idiomatic approach -- or
way of thinking about this -- that makes this flow more
intuitive.

thanks
Brian


Re: Basic question about lexical binding in relationship with "list assignment"

2019-01-02 Thread Elizabeth Mattijsen
Fixed with https://github.com/rakudo/rakudo/commit/23663609a7

> On 27 Dec 2018, at 09:29, Raymond Dresens  wrote:
> 
> Hello,
> 
> I'm getting up to speed with Perl 6 again after a long while, and I more
> or less 'hit my nose' against something that I can reduce to the
> following very basic snippet of code:
> 
>my $foo = 3;
>say $foo;
> 
>{
>say $foo;
> 
>my $foo = 6;
> 
>say $foo;
>}
> 
> This will not compile with Perl 6 (Rakudo 2018.12) -- lexical symbol
> '$foo' is already bound to an outer symbol; the implicit outer binding
> must be rewritten as OUTER::<$foo> before you can unambiguously declare
> a new '$foo' in this scope.
> 
> This will compile with Perl 5 when I add 'use v5.14;' at the top and it
> will then print 3, then 3 then 6 (as expected).
> 
> Well, it seems that I can 'cheat' by simply doing a list assignment:
> 
>my $foo = 3;
>say $foo;
> 
>{
>say $foo;
> 
>my ($foo) = 6; # avoid `... '$foo' is already bound ...'
> 
>say $foo;
>say $foo.WHAT; # is it really an integer?
>}
> 
> The output is:
> 
>3
>(Any)
>6
>(Int)
> 
> This behavior is fine I think (but a little unexpected due to my
> experience with Perl 5).
> 
> Is this behavior normal/wanted/intented (from a language/compiler
> perspective?).
> 
> Perhaps this shouldn't be and the compiler should also complain in this
> list assignment case, or perhaps generate a warning?
> 
> I'm not that confident to state that this is a bug ;)
> 
> Hence the reason why I kind-of report this,
> 
> I hope this is somewhat useful,
> 
> Thanks for your time,
> 
> Regards,
> 
> Raymond Dresens.


Re: Basic question about lexical binding in relationship with "list assignment"

2018-12-27 Thread Elizabeth Mattijsen
I’d say it is a bug you do not get the error with “my ($foo) = 6”, as clearly 
the first “say $foo” inside the scope is referring to the inner $foo, not the 
outer $foo.  So I’d suggest filing an issue for that: 
https://github.com/rakudo/rakudo/issues

> On 27 Dec 2018, at 09:29, Raymond Dresens  wrote:
> 
> Hello,
> 
> I'm getting up to speed with Perl 6 again after a long while, and I more
> or less 'hit my nose' against something that I can reduce to the
> following very basic snippet of code
> 
>my $foo = 3;
>say $foo;
> 
>{
>say $foo;
> 
>my $foo = 6;
> 
>say $foo;
>}
> 
> This will not compile with Perl 6 (Rakudo 2018.12) -- lexical symbol
> '$foo' is already bound to an outer symbol; the implicit outer binding
> must be rewritten as OUTER::<$foo> before you can unambiguously declare
> a new '$foo' in this scope.
> 
> This will compile with Perl 5 when I add 'use v5.14;' at the top and it
> will then print 3, then 3 then 6 (as expected).
> 
> Well, it seems that I can 'cheat' by simply doing a list assignment:
> 
>my $foo = 3;
>say $foo;
> 
>{
>say $foo;
> 
>my ($foo) = 6; # avoid `... '$foo' is already bound ...'
> 
>say $foo;
>say $foo.WHAT; # is it really an integer?
>}
> 
> The output is:
> 
>3
>(Any)
>6
>(Int)
> 
> This behavior is fine I think (but a little unexpected due to my
> experience with Perl 5).
> 
> Is this behavior normal/wanted/intented (from a language/compiler
> perspective?).
> 
> Perhaps this shouldn't be and the compiler should also complain in this
> list assignment case, or perhaps generate a warning?
> 
> I'm not that confident to state that this is a bug ;)
> 
> Hence the reason why I kind-of report this,
> 
> I hope this is somewhat useful,
> 
> Thanks for your time,
> 
> Regards,
> 
> Raymond Dresens.


Re: Basic question about lexical binding in relationship with "list assignment"

2018-12-27 Thread JJ Merelo
Hi,

El jue., 27 dic. 2018 a las 9:30, Raymond Dresens (<
raymond.dres...@gmail.com>) escribió:

> Hello,
>
> I'm getting up to speed with Perl 6 again after a long while, and I more
> or less 'hit my nose' against something that I can reduce to the
> following very basic snippet of code:
>
> my $foo = 3;
> say $foo;
>
> {
> say $foo;
>
> my $foo = 6;
>
> say $foo;
> }
>
> This will not compile with Perl 6 (Rakudo 2018.12) -- lexical symbol
> '$foo' is already bound to an outer symbol; the implicit outer binding
> must be rewritten as OUTER::<$foo> before you can unambiguously declare
> a new '$foo' in this scope.
>

But where's that error? In the first "say $foo"?

>
> This will compile with Perl 5 when I add 'use v5.14;' at the top and it
> will then print 3, then 3 then 6 (as expected).
>
> Well, it seems that I can 'cheat' by simply doing a list assignment:
>
> my $foo = 3;
> say $foo;
>
> {
> say $foo;
>
> my ($foo) = 6; # avoid `... '$foo' is already bound ...'
>

That should make no difference...

>
> say $foo;
> say $foo.WHAT; # is it really an integer?
> }
>
> The output is:
>
> 3
> (Any)
>

That's the first say $foo in the block, I guess...

6
> (Int)
>
> This behavior is fine I think (but a little unexpected due to my
> experience with Perl 5).
>
> Is this behavior normal/wanted/intented (from a language/compiler
> perspective?).
>
> Perhaps this shouldn't be and the compiler should also complain in this
> list assignment case, or perhaps generate a warning?
>
> I'm not that confident to state that this is a bug ;)
>
> Hence the reason why I kind-of report this,
>


It might be a documentation bug... Which you might want to report anyway.
The thing with Perl 6 is that parsing, compiling and runtime are quite
different. In Perl, far as I can tell, you are actually assigning scope to
$foo when you run that sentence. That's not the case in Perl 6, or does not
seem to be. However, this should be quite clear from the get go.

Cheers

JJ


Re: Perl 5 list assignment idiom

2017-03-13 Thread Brock Wilcox
The == operator coerces to Numeric, so like:

> sub one-thing { return ("hi",) }
sub one-thing () { #`(Sub|93867233982256) ... }
> one-thing.Numeric
1

(mentioned in https://docs.perl6.org/routine/$EQUALS_SIGN$EQUALS_SIGN)

I think my does indeed do some fancy precidenting with the assignment.

--Brock


On Mon, Mar 13, 2017 at 3:56 PM, Sean McAfee  wrote:

> sub one-thing { return ("hi",) }


Re: Perl 5 list assignment idiom

2017-03-13 Thread Sean McAfee
On Mon, Mar 13, 2017 at 12:37 PM, Will Coleda  wrote:

> Works the same in Perl 6, and you can avoid the parens. Using helper
> subs that return one or two item lists, here's some sample code:
>
> $ perl6
> > sub one-thing { return ("hi",) }
> sub one-thing () { #`(Sub|140454852043936) ... }
> > 1 == my $script = one-thing
> True
> > $script
> (hi)
>
>
But then:

> $script.WHAT
(List)

In the Perl 5 version, $script is assigned the single element of the
returned list.  In your code, it refers to the list itself.

(Also, wait: It looks like "=" has higher precedence than "=="?  Or does
the "my" affect the parsing somehow?)


Re: Perl 5 list assignment idiom

2017-03-13 Thread Will Coleda
Works the same in Perl 6, and you can avoid the parens. Using helper
subs that return one or two item lists, here's some sample code:

$ perl6
> sub one-thing { return ("hi",) }
sub one-thing () { #`(Sub|140454852043936) ... }
> 1 == my $script = one-thing
True
> $script
(hi)


> sub two-things { return  }
sub two-things () { #`(Sub|140454852044088) ... }
> 1 == my $bar = two-things
False
> $bar
(hi there)



On Mon, Mar 13, 2017 at 2:32 PM, Sean McAfee <eef...@gmail.com> wrote:
> In Perl 5, list assignment in scalar context evaluates to the number of list
> elements on the right-hand side.  That enables an idiom that I rather like:
>
> 1 == (my ($script) = $page->find('//script'))
>   or die "Other than exactly one script element found";
>
> Can a similar expression that avoids an intermediate array variable be
> written in Perl 6?
>



-- 
Will "Coke" Coleda