List context versus list context

Discussion in 'Perl Misc' started by Bo Lindbergh, Jun 21, 2006.

  1. Bo Lindbergh

    Bo Lindbergh Guest

    Consider this snippet:
    {
    sub foo {
    print scalar(@_)," arguments\n";
    }

    foo((17)[2,1]);
    foo(my @foo=(17)[2,1]);
    }

    When run by my perl 5.8.8, it produces these two lines of output:
    2 arguments
    0 arguments

    So there seems to be (at least) two kinds of list context,
    one used for evaluating function arguments and another one used
    for evaluating the rhs of an assignment. I can't find any mention
    of this in perldata.pod. What's up?


    /Bo Lindbergh
    Bo Lindbergh, Jun 21, 2006
    #1
    1. Advertising

  2. Bo Lindbergh

    Ch Lamprecht Guest

    Bo Lindbergh schrieb:
    > Consider this snippet:
    > {
    > sub foo {
    > print scalar(@_)," arguments\n";
    > }
    >
    > foo((17)[2,1]);

    this calls foo with two parameters

    > foo(my @foo=(17)[2,1]);


    this assigns a slice containing an emty list to @foo and calls foo() with that.


    try this, to see the difference:
    foo(my @foo=(17,3,6)[2,1]);

    > }
    >
    > When run by my perl 5.8.8, it produces these two lines of output:
    > 2 arguments
    > 0 arguments
    >
    > So there seems to be (at least) two kinds of list context,
    > one used for evaluating function arguments and another one used
    > for evaluating the rhs of an assignment. I can't find any mention
    > of this in perldata.pod. What's up?
    >
    >
    > /Bo Lindbergh


    Christoph
    --

    perl -e "print scalar reverse q//"
    Ch Lamprecht, Jun 21, 2006
    #2
    1. Advertising

  3. Bo Lindbergh

    Ch Lamprecht Guest

    Ch Lamprecht schrieb:
    > Bo Lindbergh schrieb:
    >
    >> Consider this snippet:
    >> {
    >> sub foo {
    >> print scalar(@_)," arguments\n";
    >> }
    >>
    >> foo((17)[2,1]);

    >
    > this calls foo with two parameters
    >
    >> foo(my @foo=(17)[2,1]);

    >
    >
    > this assigns a slice containing an emty list to @foo and calls foo()
    > with that.
    >
    >
    > try this, to see the difference:
    > foo(my @foo=(17,3,6)[2,1]);
    >
    >> }
    >>
    >> When run by my perl 5.8.8, it produces these two lines of output:
    >> 2 arguments
    >> 0 arguments
    >>
    >> So there seems to be (at least) two kinds of list context,
    >> one used for evaluating function arguments and another one used
    >> for evaluating the rhs of an assignment. I can't find any mention
    >> of this in perldata.pod. What's up?
    >>
    >>
    >> /Bo Lindbergh

    >
    >
    > Christoph


    sorry, I missed your point ;(

    Christoph

    --

    perl -e "print scalar reverse q//"
    Ch Lamprecht, Jun 21, 2006
    #3
  4. Bo Lindbergh <> wrote:
    > Consider this snippet:
    > {
    > sub foo {
    > print scalar(@_)," arguments\n";
    > }
    >
    > foo((17)[2,1]);
    > foo(my @foo=(17)[2,1]);
    > }
    >
    > When run by my perl 5.8.8, it produces these two lines of output:
    > 2 arguments
    > 0 arguments



    > So there seems to be (at least) two kinds of list context,
    > one used for evaluating function arguments and another one used
    > for evaluating the rhs of an assignment.



    It isn't really a context issue. It is a slice issue.

    Slices are special-cased for list assignment.


    > I can't find any mention
    > of this in perldata.pod.



    @c = (0,1)[2,3]; # @c has no elements
    ...
    This makes it easy to write loops that terminate when a null list
    is returned
    ...


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
    Tad McClellan, Jun 21, 2006
    #4
  5. Bo Lindbergh

    Guest

    Tad McClellan <> wrote:
    > Bo Lindbergh <> wrote:
    > > Consider this snippet:
    > > {
    > > sub foo {
    > > print scalar(@_)," arguments\n";
    > > }
    > >
    > > foo((17)[2,1]);
    > > foo(my @foo=(17)[2,1]);
    > > }
    > >
    > > When run by my perl 5.8.8, it produces these two lines of output:
    > > 2 arguments
    > > 0 arguments

    >
    > > So there seems to be (at least) two kinds of list context,
    > > one used for evaluating function arguments and another one used
    > > for evaluating the rhs of an assignment.

    >
    > It isn't really a context issue. It is a slice issue.
    >
    > Slices are special-cased for list assignment.
    >
    > > I can't find any mention
    > > of this in perldata.pod.

    >
    > @c = (0,1)[2,3]; # @c has no elements
    > ...
    > This makes it easy to write loops that terminate when a null list
    > is returned
    > ...


    I don't quite get the documentation. It says:

    A slice of an empty list is still an empty list. Thus:

    @a = ()[1,0]; # @a has no elements
    @b = (@a)[0,1]; # @b has no elements
    @c = (0,1)[2,3]; # @c has no elements

    But the third example is not the slice of an empty list! So while
    an example is provided, that example doesn't match the description it
    is supposedly an example of.

    It seems that this would be more accurate:

    A slice of an empty list is still an empty list. Thus:

    @a = ()[1,0]; # @a has no elements
    @b = (@a)[0,1]; # @b has no elements

    Also, a slice completely after the end of a non-empty list is
    an empty list. Thus:

    @c = (0,1)[2,3]; # @c has no elements


    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    Usenet Newsgroup Service $9.95/Month 30GB
    , Jun 22, 2006
    #5
  6. <> wrote:
    > Tad McClellan <> wrote:
    >> Bo Lindbergh <> wrote:


    >> It isn't really a context issue. It is a slice issue.
    >>
    >> Slices are special-cased for list assignment.
    >>
    >> > I can't find any mention
    >> > of this in perldata.pod.



    > I don't quite get the documentation. It says:
    >
    > A slice of an empty list is still an empty list. Thus:
    >
    > @a = ()[1,0]; # @a has no elements
    > @b = (@a)[0,1]; # @b has no elements
    > @c = (0,1)[2,3]; # @c has no elements
    >
    > But the third example is not the slice of an empty list!



    I was annoyed by that too.


    > So while
    > an example is provided, that example doesn't match the description it
    > is supposedly an example of.
    >
    > It seems that this would be more accurate:
    >
    > A slice of an empty list is still an empty list. Thus:
    >
    > @a = ()[1,0]; # @a has no elements
    > @b = (@a)[0,1]; # @b has no elements
    >
    > Also, a slice completely after the end of a non-empty list is
    > an empty list. Thus:
    >
    > @c = (0,1)[2,3]; # @c has no elements



    Looks like a docs patch to me...


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
    Tad McClellan, Jun 22, 2006
    #6
  7. Bo Lindbergh

    Ch Lamprecht Guest

    Tad McClellan wrote:
    > Bo Lindbergh <> wrote:
    >
    >>Consider this snippet:
    >>{
    >> sub foo {
    >> print scalar(@_)," arguments\n";
    >> }
    >>
    >> foo((17)[2,1]);
    >> foo(my @foo=(17)[2,1]);
    >>}
    >>
    >>When run by my perl 5.8.8, it produces these two lines of output:
    >>2 arguments
    >>0 arguments

    >
    >
    >
    >>So there seems to be (at least) two kinds of list context,
    >>one used for evaluating function arguments and another one used
    >>for evaluating the rhs of an assignment.

    >
    >
    >
    > It isn't really a context issue. It is a slice issue.
    >
    > Slices are special-cased for list assignment.
    >
    >
    >
    >>I can't find any mention
    >>of this in perldata.pod.

    >
    >
    >
    > @c = (0,1)[2,3]; # @c has no elements
    > ...
    > This makes it easy to write loops that terminate when a null list
    > is returned
    > ...
    >
    >

    I thought the context question was, why in this case
    foo((17)[2,1]);
    the expression (17)[2,1] evaluates to (undef,undef) ??

    Maybe it has something to do with aliasing of function arguments...

    Christoph

    --

    perl -e "print scalar reverse q//"
    Ch Lamprecht, Jun 22, 2006
    #7
  8. Bo Lindbergh

    Guest

    Ch Lamprecht <> wrote:
    > Tad McClellan wrote:
    > > Bo Lindbergh <> wrote:
    > >
    > >>Consider this snippet:
    > >>{
    > >> sub foo {
    > >> print scalar(@_)," arguments\n";
    > >> }
    > >>
    > >> foo((17)[2,1]);
    > >> foo(my @foo=(17)[2,1]);
    > >>}
    > >>
    > >>When run by my perl 5.8.8, it produces these two lines of output:
    > >>2 arguments
    > >>0 arguments

    > >
    > >
    > >
    > >>So there seems to be (at least) two kinds of list context,
    > >>one used for evaluating function arguments and another one used
    > >>for evaluating the rhs of an assignment.

    > >
    > >
    > >
    > > It isn't really a context issue. It is a slice issue.
    > >
    > > Slices are special-cased for list assignment.
    > >
    > >
    > >
    > >>I can't find any mention
    > >>of this in perldata.pod.

    > >
    > >
    > >
    > > @c = (0,1)[2,3]; # @c has no elements
    > > ...
    > > This makes it easy to write loops that terminate when a null list
    > > is returned
    > > ...
    > >
    > >

    > I thought the context question was, why in this case
    > foo((17)[2,1]);
    > the expression (17)[2,1] evaluates to (undef,undef) ??
    >
    > Maybe it has something to do with aliasing of function arguments...


    It is starting to look like a bug.

    A slice of an empty list is an empty list in both assignment and sub-arg.

    A slice off the end of a nonempty list is an empty list in an assignment,
    but not as the arg to a sub.


    > perl -e 'use Data::Dumper; sub foo {return @_}; \

    print Dumper [foo(()[4..6])]'
    $VAR1 = [];

    > perl -e 'use Data::Dumper; sub foo {return @_}; \

    print Dumper [(()[4..6])]'
    $VAR1 = [];

    > perl -e 'use Data::Dumper; sub foo {return @_}; \

    print Dumper [((1)[4..6])]'
    $VAR1 = [];

    > perl -e 'use Data::Dumper; sub foo {return @_}; \

    print Dumper [foo((1)[4..6])]'
    $VAR1 = [
    undef,
    undef,
    undef
    ];


    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    Usenet Newsgroup Service $9.95/Month 30GB
    , Jun 22, 2006
    #8
  9. Ch Lamprecht <> wrote:
    > Tad McClellan wrote:
    >> Bo Lindbergh <> wrote:
    >>
    >>>Consider this snippet:
    >>>{
    >>> sub foo {
    >>> print scalar(@_)," arguments\n";
    >>> }
    >>>
    >>> foo((17)[2,1]);
    >>> foo(my @foo=(17)[2,1]);
    >>>}
    >>>
    >>>When run by my perl 5.8.8, it produces these two lines of output:
    >>>2 arguments
    >>>0 arguments



    [snip my explanation of why you get the "0 arguments" output]


    > I thought the context question was, why in this case
    > foo((17)[2,1]);
    > the expression (17)[2,1] evaluates to (undef,undef) ??



    Ah ha.

    The OP didn't say which of the two he understood and I ended up
    picking the wrong one.

    The real question here is why we're getting the "2 arguments" output.


    > Maybe it has something to do with aliasing of function arguments...



    I believe you are onto something there, since the only place I
    can get "2" is with the 4 things (are there more?) that do aliasing:
    map, grep, foreach and sub arguments.


    perl -le 'push @a, map $_, (17)[2,1]; print scalar @a'

    perl -le 'push @a, grep 1, (17)[2,1]; print scalar @a'

    perl -le 'foreach ( (17)[2,1] ) {push @a, $_} print scalar @a'

    perl -le 'push @a, sub {return @_}->( (17)[2,1] ); print scalar @a'


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
    Tad McClellan, Jun 22, 2006
    #9
  10. Bo Lindbergh

    Bo Lindbergh Guest

    In article <>,
    Tad McClellan <> wrote:

    > Ch Lamprecht <> wrote:
    > > Maybe it has something to do with aliasing of function arguments...

    >
    >
    > I believe you are onto something there, since the only place I
    > can get "2" is with the 4 things (are there more?) that do aliasing:
    > map, grep, foreach and sub arguments.


    sort does aliasing too, but you get 0 elements in that context:
    {
    my @a = sort { $b<=>$a; } ((17)[2,1]);
    print scalar @a," elements\n";
    # outputs "0 elements"
    }

    Wrapping the slice in a do-block gives you 0 elements
    and still allows aliasing:
    {
    my($x,$y,@a)=(10,20);

    foreach ( do { ((17)[2,1], $x, $y); } ) {
    push(@a,$_++);
    }
    print scalar(@a)," elements, x=$x, y=$y\n";
    # outputs "2 elements, x=11, y=21"
    }

    I'm afraid that any complete description of this is going to sound
    badly incoherent.


    /Bo Lindbergh
    Bo Lindbergh, Jun 22, 2006
    #10
  11. wrote:
    > Ch Lamprecht <> wrote:
    >> Tad McClellan wrote:

    >...
    >
    > It is starting to look like a bug.
    > ...
    >
    > A slice off the end of a nonempty list is an empty list in an assignment,
    > but not as the arg to a sub.
    >


    The "off-the-end" semantics in the 2 assignment examples below looks
    unexpected to me too.

    I can see that the 2nd example becomes a non-empty list but why should
    it generate the additional undef's while the 1st example remains mired
    in its own emptiness...:)



    $ perl -MData::Dumper -le 'my @x = (0)[2,4,6]; print Dumper \@x'
    $VAR1 = [];

    $ perl -MData::Dumper -le 'my @x = (0)[0, 2,4,6];print Dumper \@x'
    $VAR1 = [
    0,
    undef,
    undef,
    undef
    ];


    --
    Charles DeRykus
    Charles DeRykus, Jun 27, 2006
    #11
  12. Charles DeRykus <> wrote:
    > wrote:
    >> Ch Lamprecht <> wrote:
    >>> Tad McClellan wrote:

    >>...
    >>
    >> It is starting to look like a bug.
    >> ...
    >>
    >> A slice off the end of a nonempty list is an empty list in an assignment,
    >> but not as the arg to a sub.
    >>

    >
    > The "off-the-end" semantics in the 2 assignment examples below looks
    > unexpected to me too.
    >
    > I can see that the 2nd example becomes a non-empty list but why should
    > it generate the additional undef's



    It doesn't generate any "additional" undefs, 4 indexes, 4 values.


    > while the 1st example remains mired
    > in its own emptiness...:)



    Because when it is _all_ undefs (ie. _all_ of the indexes are off
    the end), the special case of returning an empty list kicks in.

    perldata says

    This makes it easy to write loops that terminate when a null list
    is returned

    as a "justification" for this behavior.


    > $ perl -MData::Dumper -le 'my @x = (0)[2,4,6]; print Dumper \@x'
    > $VAR1 = [];
    >
    > $ perl -MData::Dumper -le 'my @x = (0)[0, 2,4,6];print Dumper \@x'
    > $VAR1 = [
    > 0,
    > undef,
    > undef,
    > undef
    > ];



    Neither of these display the bug that is under discussion.

    The 1st one generates the empty list rather than the non-empty list
    that the bug gives.

    The 2nd one is not _all_ off of the end, so a non-empty list is expected.

    The bug is when all of the indexes are off the end and it returns
    a non-empty list.


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
    Tad McClellan, Jun 27, 2006
    #12
  13. Tad McClellan wrote:
    > Charles DeRykus <> wrote:
    >> wrote:
    >>> Ch Lamprecht <> wrote:
    >>>> Tad McClellan wrote:
    >>> ...
    >>>
    >>> It is starting to look like a bug.
    >>> ...
    >>>
    >>> A slice off the end of a nonempty list is an empty list in an assignment,
    >>> but not as the arg to a sub.
    >>>

    >> The "off-the-end" semantics in the 2 assignment examples below looks
    >> unexpected to me too.
    >>
    >> I can see that the 2nd example becomes a non-empty list but why should
    >> it generate the additional undef's

    >
    >
    > It doesn't generate any "additional" undefs, 4 indexes, 4 values.
    >
    >
    >> while the 1st example remains mired
    >> in its own emptiness...:)

    >
    >
    > Because when it is _all_ undefs (ie. _all_ of the indexes are off
    > the end), the special case of returning an empty list kicks in.
    >
    > perldata says
    >
    > This makes it easy to write loops that terminate when a null list
    > is returned
    >
    > as a "justification" for this behavior.
    >


    Thanks, I read that earlier and it went in one ear and breezed straight
    through..

    >
    >
    >> $ perl -MData::Dumper -le 'my @x = (0)[2,4,6]; print Dumper \@x'
    >> $VAR1 = [];
    >>
    >> $ perl -MData::Dumper -le 'my @x = (0)[0, 2,4,6];print Dumper \@x'
    >> $VAR1 = [
    >> 0,
    >> undef,
    >> undef,
    >> undef
    >> ];

    >
    >
    > Neither of these display the bug that is under discussion.
    >
    > The 1st one generates the empty list rather than the non-empty list
    > that the bug gives.
    >
    > The 2nd one is not _all_ off of the end, so a non-empty list is expected.
    >
    > The bug is when all of the indexes are off the end and it returns
    > a non-empty list.
    >
    >


    Got it now. The bug seems to manifest only as an argument call rather
    than a direct assignment.


    --
    Charles DeRykus
    Charles DeRykus, Jun 28, 2006
    #13
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Matthew Louden
    Replies:
    1
    Views:
    6,906
    Scott M.
    Oct 11, 2003
  2. Russ

    script versus code versus ?

    Russ, Jun 10, 2004, in forum: ASP .Net
    Replies:
    1
    Views:
    2,493
  3. Alf P. Steinbach
    Replies:
    10
    Views:
    3,083
    Alf P. Steinbach
    Jul 27, 2011
  4. Christoffer Sawicki
    Replies:
    5
    Views:
    249
    Christoffer Sawicki
    Sep 2, 2006
  5. Paul Butcher
    Replies:
    12
    Views:
    702
    Gary Wright
    Nov 28, 2007
Loading...

Share This Page