in reply to Re^7: Scalar context of slice ("list")
in thread Scalar context of slice

You ... make an argument about how you can claim that "grep doesn't really 'return a list'". ... But slices and grep are both examples where Perl ... will do exactly that: produce a list of scalar values (on the stack) despite that list being produced "in a scalar context".
Actually, it is the source that make that argument:

Um, the second "..." above was "(at least some versions of Perl)" so showing source code for some other version of Perl isn't much of a counter argument. Exactly which versions of Perl was even noted elsewhere in this thread in reply to you.

So are you arguing that grep used to return a list so it used to give the last item in scalar context? Or are you arguing that grep was designed to not return the last item because it was known that one day grep would be optimized to no longer "return a list"? Or are you going off on some tangent unrelated to my point, which is that it makes no sense to claim that a slice returns the "last item" because "a slice returns a list and a list ..."?

That is, there is, in fact, no general "just return the last item of the list" code in Perl.
6 <@> list sK ->7 <<< And yet, there it is.

I'm not sure what you are talking about. I don't see where you show code that does the "take the last item of a list" for any construct that "returns a list", such as for the three different types of slice.

If there were such code, then there would have been no need for me to patch one of those slice forms to add yet another copy of the code that takes the last item (and Perl wouldn't have dumped core).

Despite Perls' celebration of TIMTOWTDI, it has become derigour to only accept one abstract description of many of those affects.

Whatever. I'm not arguing for some "one true" abstraction. I've often argued for the opposite and several places in the node that you replied to I mention multiple ways of describing things. There doesn't have to be only "one true" abstaction for me to point out that "a slice returns a list therefore it ..." is a bizarre rationalization.

So, if a list literal in the source, becomes a 'list' when it is pushed into the stack, doesn't it hold that when the multiple scalars produced by slicing an array is pushed onto the stack, it also becomes a list?

Yes, they both (in recent versions of Perl) produce an intermediate list of scalar values on the stack (which is often called just "list" but is also certainly not the same thing as the "list literal" construct, as evidenced by your own sentence).

And that all but the last element of that stack-held list of scalars are then discarded when in a scalar context?

No, not in the least. The code that selects the last item of the list (of scalar values on the stack) for a list literal is completely separate from the three versions of that code that exist for the three types of slices (hash slices, array slices, and list slices)1. It is trivial to make a version of Perl where a hash slice in scalar context returns the number of items, an array slice in scalar context returns the first item, and a list slice in scalar context does something else. There are 4 different pieces of code representing four different design decisions (or, for most of those, more like "non-decisions", I expect, especially since I wrote one and made no design decision when doing so).

1 See the bottom of pp_aslice(), the bottom of pp_hslice(), and the middle of pp_lslice() all (probably) in pp.c for 3 of those four separate checks against GIMME.

Just as the code for grep (in older versions of Perl) that selects a count (after pushing a list onto the stack) was separate.

If your argument made sense, then surely grep in Perl prior to 5.010 would also have to return the last item when in a scalar context.

Just as we say "I've boiled the kettle" not "I boiled the water in the kettle", with the subtle inaccuracy understood and glossed over.

I never objected to using simply "list" in places2. Now, if one tried to make a proclamation "I've boiled the kettle and driving while boiled is likely to make the coppers boiled, therefore if the kettle drives it will be a police officer" switching between three different meanings of "boiled" in the same sentence, few would be convinced.

2 Now, it is best to make clear more precisely what you mean by "list" in that particular context. And it is important for readers of text about Perl to realize that "list" can mean quite a few different things. Without those two conditions, we get things like a SoPW node asking about writing [('a','b','c')] in a regex because the documentation says you put a "list of characters" between the brackets (true story, though I couldn't think of a likely strategy for finding it with a reasonable amount of time/effort, so I didn't look and it was many years ago so the details are surely imperfectly remembered).

Similarly, it makes no sense to use two (or even three) different definitions of "list" in an argument "X is a 'list', a 'list' does Y, therefore X does Y".

Is it such a "bad meme" to say: A slice results in a list. And a list in a scalar context will return the last element of the slice? Rather than: an array slice constructor pushes the selected element of the array onto the markstack and if that array slice constructor is used within the confines of a scalar context then the stack pointer will be adjusted leaving just the last element accessible.

Strawman. I simply say "a slice in scalar context returns the last item". If somebody asks "why?", then I certainly don't say "because it is a list, not an array". Further, when I've seen other people claim that or hear it claimed, I've often also seen them later tripping over the misconceptions involved. Otherwise it would just be a semantic argument and not something I'd find worth wasting much time or effort on.

And, yes, a simple but wrong explanation of "why?" is worse than a correct explanation of "why?" whether it is simpler or more complex. Simply "because that was the way Perl was built" is a reasonable answer. I've certainly never written the horrid explanation that you offered as the strawman alternative.

The oft-made observation that because of the scalar context, the comma operator reduces the thing (set of things, collection of things...) to a scalar before it ever became a list is both technically incorrect, and abstractly absurd.

I wrote above that "there is no such thing as 'a list in scalar context'" "is actually an incorrect statement". Though, I've never noticed it being "oft-made" regarding comma operators. Nor do I find it "abstractly absurd".

- tye        

Replies are listed 'Best First'.
Re^9: Scalar context of slice ("list")
by BrowserUk (Patriarch) on Oct 06, 2008 at 08:25 UTC
    I simply say "a slice in scalar context returns the last item".

    If you (and others) confined yourselves to "simply saying": It would be more accurate to say that 'a slice' rather than 'a list' in a scalar context returns the last item., then this exchange would probably never have taken place.

    Instead we get long, rambling, high-horse rants about how "there is no such thing as a list in a scalar context", when there patently is: print scalar(1,2,3);.

    Which inevitably leads to further long, rambling tirades about how there are many different meaning of the term 'list' in Perl.

    Using the term unqualified inevitably brings the language pedants crawling out of the woodwork to demonstrate their superior understanding, despite that most readers will:

    1. understand what the writer meant;
    2. intellectually gloss over any exceptional, technical inaccuracies that the unqualified use of the term might be subject to;
    3. understand that most of us neither want nor need to add a dozen levels of footnotes to our writings;
    4. nor want to bother trying to decipher the writings of those that do feel that need.

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

      Instead we get long, rambling, high-horse rants about how "there is no such thing as a list in a scalar context", when there patently is: print scalar(1,2,3);.

      Since even that list doesn't return a list, would it be accurate to say "a list can't be returned in scalar context" (for when it happens, Perl core dumps)?

        Since even that list doesn't return a list, would it be accurate to say "a list can't be returned in scalar context"

        Sorry for the delay in getting back to you, but this was one of those things that I had to allow to wash over me for a while before deciding how to respond.

        If for no other reason than you believe it is more accurate, then I would have to conclude that it probably is more accurate. And as a generality, most of what you say is accurate. That's (for me) a given.

        But the real question is: whom does that greater accuracy benefit?

        I thik we can agree, this (1,2,3) is a list; and this return (1,2,3) a return statement; and this

        sub x{ return(1,2,3); }

        is a function (attempting) to return a list.

        If we place a call to that function in a scalar context my $x = x(); then the return statement doesn't cease to be a return statement, nor does the list cease to be a list. At some point, the list is transformed to a scalar, which, in this case, happens to be the last element of the list.

        So at that point, immediately before the transformation--and the very reason the transformation is performed--the list is in a scalar context.

        Now you could conclude either of:

        • If a return statement with a list argument, is found, (or finds itself), in a scalar context, that it transforms the list to a scalar and returns that scalar.
        • Or: The return statement returns the list, and when it (the list), finds itself in a scalar context, it transforms itself to a scalar, prior to the assignment.
        • Or: The when assignment operator is given a list to assign to a scalar, it transforms the list to a scalar.

        But whichever way, and to be honest it does matter which is more accurate, the list existed; the scalar context existed and the list was within the auspices of that scalar context; and so, was transformed.

        So, I see no clearer, simpler or conceptually more accurate way of describing that than: "the results of a list in a scalar context is the last element of that list".

        And this does not apply to map & grep in scalar contexts, not because the description or concept is wrong, but because those functions do not attempt to return a list when they find themselves in a scalar context. They instead choose to return something, a scalar, that is considered more useful.


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.