Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Re^6: If you believe in Lists in Scalar Context, Clap your Hands

by oshalla (Deacon)
on Oct 24, 2008 at 15:49 UTC ( #719376=note: print w/ replies, xml ) Need Help??


in reply to Re^5: If you believe in Lists in Scalar Context, Clap your Hands
in thread If you believe in Lists in Scalar Context, Clap your Hands

Yes. I'd say that an array is a variable whose value is a list. Using the name or some other reference to an array yields that value or its length, depending on Context. In that sense, yes, I was implying that arrays do not make lists. A slice operation, on the other hand, takes a list value and makes a list which is a subset. (I'm open minded, though: if there is, in fact and invisible operator that makes lists out of arrays I would not be surprised.)
No.
An array returns a list in list context, but it isn't a list. Just as localtime() isn't a list, although it will return a list in list context. In fact, every expression will return a list in list context, although that list may be empty or just contain a single value.

A flat "No". Goodness.

I'm puzzled by what you are contradicting here. Is it controversial to say that an array is a variable ? Is it then controversial to say the the value of that variable is a list ? Or to note that in an expression, the part of the value used (the list itself or its length) depends on the Context, is that controversial ?

As for the slice operation, yes, it will take a subset of a list. On arrays though, it can return more.
@a = ()[3, 5, 6]; @b = @c[3, 5, 6]; say 0 + @a; say 0 + @b; __END__ 0 3

Well, that's amusing. I note that it doesn't matter whether @c is undefined or defined but empty. So, slices of lists are different from slices of arrays. Splendid. Thank you.

(I realise also that subset might be the wrong word, since a slice can also include repeated values, which might not pass as a subset. Also, as you point out, some items in the slice may be undef, which may or may not be considered as part of the original.)

You are quite wrong here. The list assignment operator in scalar context DOES NOT RETURN A LIST. It returns the number of elements on its right hand side. It sets $a and $b as side-effects - it doesn't return its left hand side.

SO IT WOULD APPEAR.

I was trying to say: to fully understand $r = ($a, $b) = 0..11;   it is necessary to know what a many-splendored thing '=' is. Understanding the more common-place notion of right-associativity is not enough. I'm sorry if that wasn't as clear as I had hoped.

I do not know how this is actually implemented. I can see how the documentation describes it. The effect remains as if the scalar assignment reaches round the list assignment, but I am more than happy to take your word for it that it doesn't actually work like that.

Further, I withdraw unreservedly any implication, imputation or suggestion that this (or any other) mechanism in Perl might, through a glass darkly, or otherwise, appear to be magical to even the slightest degree. I throw myself on the mercy of the court, and hope, as only a true penitent can hope, for a light sentence involving the minimum of pain, and if at all possible, no permanent disfigurement.


Comment on Re^6: If you believe in Lists in Scalar Context, Clap your Hands
Select or Download Code
Re^7: If you believe in Lists in Scalar Context, Clap your Hands
by JavaFan (Canon) on Oct 24, 2008 at 16:07 UTC
    Understanding the more common-place notion of right-associativity is not enough.
    Indeed. You must also know the return value of the operator (= in this case). But that's the same as trying to understand the result of
    2 ** 3 ** 4
    you need to understand the return value of ** beside understanding right-associativity.
    I do not know how this is actually implemented.
    Associativity is a parser/compiler issue. By the time the code is running, associativity no longer plays a role. As for the implementation of assignment, they are actually two different operators, scalar assignment (pp_sassign in pp_hot.c) and list assignment (pp_aassign in pp_hot.c).

    And if you look in pp_hot.c, you see there's check on context to determine what is returned:

    if (gimme == G_VOID) SP = firstrelem - 1; else if (gimme == G_SCALAR) { dTARGET; SP = firstrelem; SETi(lastrelem - firstrelem + 1 - duplicates); } else { if (ary) SP = lastrelem; else if (hash) { if (duplicates) { /* Removes from the stack the entries which ended up a +s * duplicated keys in the hash (fix for [perl #24380]) + */ Move(firsthashrelem + duplicates, firsthashrelem, duplicates, SV**); lastrelem -= duplicates; } SP = lastrelem; } else SP = firstrelem + (lastlelem - firstlelem); lelem = firstlelem + (relem - firstrelem); while (relem <= SP) *relem++ = (lelem <= lastlelem) ? *lelem++ : &PL_sv_undef; } RETURN;
    Now, I don't expect you to understand everything (neither do I), but I do hope you see that in VOID context, nothing is returned, in SCALAR context, a single value is returned, and in LIST context, more things are returned.

    One more piece of evidence that it isn't the scalar assignment that is reaching all the way behind, here we have a list assignment in scalar context where the scalar context isn't given by another assignment:

    $ perl -E 'say scalar(() = ($a, $b, $c))' 3 $
      One more piece of evidence that it isn't the scalar assignment that is reaching all the way behind, here we have a list assignment in scalar context where the scalar context isn't given by another assignment:

      If you can't have a list in a scalar context, how can you have the assignment of a list in scalar context? You have even said in this thread that lists don't even exist.

      To pick your own nit, perhaps you meant "the result of the list assignment operator upon assigning a series of scalars to an empty series of scalars".

      It's very difficult for there to be a list assignment in scalar context there if lists don't exist. What does a "list assignment" assign? It's also very difficult to support the idea that lists don't exist when you show the code that returns multiple scalars ("atoms" and references to other complex structures) in order (a "list") in LIST context with variables named 'lelem' and similar. The "elem" part of those clearly stands for "element". Elements of what?

      You can argue that there is another, clearer concept to use to understand this topic. It's very difficult to support the idea that the concept used in the documentation, the source code, the tutorials, and the in concepts and culture of other programming languages from which Perl borrows ideas does not exist in Perl, though. Call it flawed if you like, but saying it doesn't exist is inaccurate.

        If you can't have a list in a scalar context, how can you have the assignment of a list in scalar context? You have even said in this thread that lists don't even exist.

        The list assignment imposes a list context on its operands. So while the list assignment is in scalar context, the assignee and assigned lists aren't.

        A B C D <-- labels $x = ( $i, $j ) = ( $p, $q ); S ? L L L S L L L <-- context | | | | | | | | \__ Propogated by right-most list op'tor (D). | | | | | | | \____ Imposed by the list assignment (C). | | | | | | \______ Propogated by right-most list op'tor (D). | | | | | \__________ Imposed by the scalar assignment (A). | | | | \_______________ Propogated by left-most list op'tor (B). | | | \__________________ Imposed by the list assignment (C). | | \___________________ Propogated by left-most list op'tor (B). | \_______________________ Determined by outside code. \__________________________ Imposed by scalar assignment (A).
        If you can't have a list in a scalar context, how can you have the assignment of a list in scalar context?
        Because any operator can be scalar context; it's the context that determines its context, not their operands. Here are a few examples of operators in scalar context:
        scalar ($a + $b); # Addition scalar (($a) x $b); # Repetition scalar ($a =~ $b); # Matching scalar ($a .. $b); # Range/FlipFlop scalar ($a = $b); # Scalar assignment scalar (($a) = ($b)); # List assignment
        Here are some examples of operators in list context:
        say ($a + $b); # Addition say (($a) x $b); # Repetition say ($a =~ $b); # Matching say ($a .. $b); # Range/Flipflop say ($a = $b); # Scalar assignment say (($a) = ($b)); # List assignment
        One should realise that 'scalar assignment' and 'list assignment' are two different operators (sassign and aassign in pp_hot.c). It's the LHS of the '=' that determines which operator it is (this is unlike the '..' operator where it's the context that determines whether it's the range or the flipflop operator). The side-effects (that is, the actual assignment) of both sassign and aassign are independent of the context. However, the return value of the aassign operator is context dependent. In scalar context, it returns the number of elements appearing on its RHS.
Re^7: If you believe in Lists in Scalar Context, Clap your Hands
by ysth (Canon) on Oct 28, 2008 at 06:03 UTC
    Further, I withdraw unreservedly any implication, imputation or suggestion that this (or any other) mechanism in Perl might, through a glass darkly, or otherwise, appear to be magical to even the slightest degree.
    Now that's worth an upvote :)

    FWIW, I took the "flat No" as applying to "arrays do not make lists".

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (7)
As of 2014-09-18 10:06 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (110 votes), past polls