Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Re^2: Array/List Strangeness (why)

by tye (Sage)
on Aug 05, 2009 at 14:20 UTC ( [id://786122]=note: print w/replies, xml ) Need Help??


in reply to Re: Array/List Strangeness
in thread Array/List Strangeness

Most of the stuff about "a list" vs "an array" so far in this thread is just bull; making up stuff to explain observations without actually hitting on anything real.

Perl has code that decides what to return when an array slice is done and it has code that decides what to return when a list slice is done. These different sections of code are not forced to return undef versus "nothing" based on some underlying difference in what an array is versus what a list is.

The real reason why those sections of code were written to handle these cases differently is documented just below the already quoted section of the documentation (perldata):

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:

@a = (1)[1,0]; # @a has two elements @b = (1,undef)[1,0,2]; # @b has three elements

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

while ( ($home, $user) = (getpwent)[7,0]) { printf "%-8s %s\n", $user, $home; }

And I think it is easy to see that somebody is much less likely to write like:

while( ( $home, $user )= @results[7,0] ) { ... }

But I actually consider part of the documentation to be documenting a bug that was an accident of implementation. Quoting just the relevent parts:

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

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

You see that @c is the result of a list slice of a non-empty list. The stated motivation explains why we want a list slice of an empty list to be empty (so that "failure" inside of the list slice gets communicated out to the "list assignment"). It doesn't explain why we want a slice of non-existent elements from the slicing of a list to magically disappear.

Sure, making out-of-bounds elements of a list slice disappear is one way to implement things in order to get "a slice of an empty list is empty". But I'd rather the implementation not have such side effects. That is, I'd rather the slicing of a non-empty list treated out-of-bound elements consistently with how they are handled with array slices (and hash slices). Heck, the documented behavior for all-out-of-bounds items is even inconsistent with how list slices themselves behave:

@d= (1,2,3)[9,1,8]; # @d= (undef,2,undef);

I also believe that this behavior has changed subtly over the years. I know I've discussed/argued with Larry over this at least once.

BTW, if you want to avoid this particular bit of magic, you can rewrite your list slice as an array slice: [get_a_list()]->[7,0]. And, as quietly noted in the documentation, if you want this behavior for an array slice, just write it as a list slice: (@array)[7,0].

- tye        

Replies are listed 'Best First'.
Re^3: Array/List Strangeness (why)
by LanX (Saint) on Aug 05, 2009 at 17:46 UTC
    Talking about bull ;-)

    BTW, if you want to avoid this particular bit of magic, you can rewrite your list slice as an array slice: [get_a_list()]->[7,0]. And, as quietly noted in the documentation, if you want this behavior for an array slice, just write it as a list slice: (@array)[7,0].

    I am pretty sure that slicing while dereferencing with right-arrow isn't (yet) implemented in perl!

    DB<71> x [qw/a b c/]->[2] # works like expected 0 'c' DB<72> x [qw/a b c/]->[1,0] # oops! 0 'a' DB<73> x [qw/a b c/]->[0,1] 0 'b'

    Seems that instead to try slicing, the comma is interpreted in scalar context. Hence the last element of the slice-list is chosen as index!

    UPDATE: the only way I know to slice lists like arrays is:

    DB<83> x @{[ qw// ]}[0,1] 0 undef 1 undef DB<84> x @{[ qw/a b c/ ]}[0,1] 0 'a' 1 'b'

    Cheers Rolf

      Sorry, multi-value slices require more complex syntax: @{[1,2,3]}[8,1,9]. The -> only works when you just want one value back. The @{ } form isn't actually much more verbose, but it is rather uglier. There was a patch to allow [...]->@[...] syntax (and I believe there is even a fork of Perl5 that includes such a patch) but it never got applied to official Perl 5 (I don't think I ever saw a good reason given for why it shouldn't be applied, though).

      - tye        

        multi-value slices require more complex syntax

        which is really a pity since it breaks the "always dereference with arrow" rule in PBP.

        I don't think I ever saw a good reason given for why it shouldn't be applied, though

        "Mythical" backwards compability? ;-)

        Personally i'd like to have a pragma like strict that bans the "scalar comma operator" ... I have much more trouble than fun with it ... 8(

        Cheers Rolf

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://786122]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others taking refuge in the Monastery: (4)
As of 2024-04-25 09:17 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found