Tom Christiansen wrote:
>

First off, thanks for taking the time to present such a thorough
document. Well-reasoned arguments is exactly what the Perl 6 project
needs, IMO.

I read this early last night, and have been postulating on it ever
since. In the process of trying what feels like 100's of examples, I've
hit on some very interesting inconsistencies in Perl's list context. 

Also, in the process I found an absolutely huge^Wenormous hole in the
RFC I wrote. Look at these examples:

   $count = list split /!/; # easy
   $count = () = split /!/; # not as easy

   my($arg1) = func;        # easy
   my $arg1 = list func;    # not as easy

There's absolutely no way any single operator could do both. For that
reason alone, consider the RFC as-written dropped. That's doesn't mean
the issue's dropped, just that the RFC's complete garbage.

However, let that not overshadow the points I'm about to make, because I
think they indicate fundamental problems with Perl's context engine. I'm
only going to address one of your examples, because they're all
fundamentally the same:

>     If you write
> 
>         $burp = LISTIFY( grep {EXPR} @data );
>
>     What's in the burp?

By this argument, then why aren't these different?

   @data = qw(this that and the other thing);

   $x = @lines = grep /th/, @data;
   $y = ($first, $second) = grep /th/, @data;
   $z = () = grep /th/, @data;
   
   print "$x, $y, $z";     # 5, 5, 5

If list() were to return something different than the above, then "()="
is not really a list constructor. Perhaps it's an array constructor? Of
special interest is the second one, which while appearing to set only
two values, actually creates a list (array?) of 5 somewhere. Then it
turns around and $y gets its length.

However, curiously, split() does *NOT* do the same thing:

   $data = qq(this that and the other thing);

   $a = @lines = split /\s+/, $data;
   $b = ($first, $second) = split /\s+/, $data;
   $c = () = split /\s+/, $data;

   print "$a, $b, $c";     # 6, 3, 1

Whoa. That's bad. I don't care which way you look at it, but that's bad.

We have the same exact operators, but one constructs a true list while
the other constructs an array behind the scenes? Has anyone noticed this
before?

We need to choose one behavior or the other. This is not TMTOWTDI, it's
inconsistent and downright confusing. I'd be very surprised if anyone
doesn't consider this a bug, even if you understand why it happens.

If we want two separate behaviors, then we need two separate operators,
perhaps left-side [] to force a true array context, and left-side () to
force a true list context.

I just want to make one more point on your email before coming back to
this point:

>     If you write
> 
>         $burp = LISTIFY( <FH> );
> 
>     Then you have a potentially biggissimo temporary list in memory,

Yes, and this would be just as stupid as doing something like this:

   $burp = () = <FH>;

Which you can do currently. So I think your point here is better taken
as "don't be an idiot", not really "list() is a bad thing".
 
> As Damian has pointed out, there's some confusion about just what
> this C<sub list> thing (which I, above, have written LISTIFY) would
> look like. 

Yes, and as the simple examples above showed, there's some serious
issues here with Perl 5's list context, IMO.

One example you didn't address was this:

   foo( () = bar() );

This, more than any others, is the one that drives me batty. It seems
the solution for this to me is:

   1. Always have bar() interpreted as a list context

   2. Let foo()'s prototype specify arg1 as $ if it
      wants a scalar

That's certainly the most useful behavior that I can see. And if I just
wanted to force the scalar then I could use:

   foo( scalar bar() );

As far as I can tell through my examples, this is pretty much what
happens now. So it might be worth just clarifying this concept.

I would gladly drop the list() idea entirely if (a) we fix the broken
stuff and (b) clarify what we're doing with chained subs so the above
foo() example never has to be used again.

-Nate

Reply via email to