in reply to Re^2: Skipping parameters in sprintf %, elegantly
in thread Skipping parameters in sprintf %, elegantly

I regret that the distinction between an ARRAY and a LIST in Perl is lost on me :-(. I humbly beg that you initiate me into this mystery.

  • Comment on Re^3: Skipping parameters in sprintf %, elegantly

Replies are listed 'Best First'.
Re^4: Skipping parameters in sprintf %, elegantly
by kyle (Abbot) on Aug 20, 2008 at 03:05 UTC

    One way to think of it is that a list is a series of things (scalars) separated by commas while an array is a single variable that contains a list. Some would say (and have said) that an array is a list.

    An array in a scalar context will evaluate to the number of items in the array. A list in a scalar context evaluates to whatever the last item in the list would be in a scalar context, and the other items in the list receive a context that's, um, based on context (see Re^3: ||= oddity).

    Hope this helps.

      Thank you. The FAQ y'all referred me to says:

      What is the difference between a list and an array?
      An array has a changeable length. A list does not. An array is something you can push or pop, while a list is a set of values. Some people make the distinction that a list is a value while an array is a variable. Subroutines are passed and return lists, you put things into list context, you initialize arrays with lists, and you foreach() across a list. @ variables are arrays, anonymous arrays are arrays, arrays in scalar context behave like the number of elements in them, subroutines access their arguments through the array @_ , and push/pop/shift only work on arrays.

      OK, so a list has most of the properties of an array, but is ephemeral -- appearing in expressions as terms or results. Hence 'list context', not 'array context'.

      The FAQ also says:

      As a side note, there's no such thing as a list in scalar context. When you say
      $scalar = (2, 5, 7, 9);
      you're using the comma operator in scalar context, so it uses the scalar comma operator. There never was a list there at all! This causes the last value to be returned: 9.

      Which is vintage Perl :-) It may look like a list, it may even quack in a list-ish sort of a way, but it's not a list 'cos it's in scalar context. Hurrah !

      With subroutines, context is a form of action over a distance -- quantum entanglement is, perhaps, a less tricky concept. Consider:

      my $a = proc_a('fred') ; my $b = proc_b('bill') ; print "proc_a: $a\n" ; print "proc_b: $b\n" ; sub proc_a { my ($x) = @_ ; my @a = ($x.'_0', $x.'_1', $x.'_2', $x.'_3') ; return @a ; } ; sub proc_b { my ($x) = @_ ; return ($x.'_0', $x.'_1', $x.'_2', $x.'_3') ; } ;

      gives:

      proc_a: 4 proc_b: bill_3

      So the occasional non-list-ness of the apparent list in proc_b is even less obvious. And the deceptive similarity between proc_a and proc_b is one of those optical illusions that remind us that evolution is a process, not a destination.

      As a matter of Good Practice, where a subroutine expects to return a list (FX: checks definition... yes! subroutines return lists, not arrays) it should ensure that it has been invoked in the appropriate context, or responds in some well defined way in scalar context. Let me see, how does one do that ? Ah.... of course: wantarray (natch).

      One way to think of it is that a list is a series of things (scalars) separated by commas while an array is a single variable that contains a list.

      You appear to be conflating two of the most common things that Perl people tend to mean when they say "list": a "list literal" and a "list of scalar values". In a list literal, things are separated by commas but those things don't need to be scalars. An array contains a list of scalar values (but these aren't separated by commas inside of the array, of course).

      A list in a scalar context evaluates to whatever the last item in the list would be in a scalar context

      That is true of a "list literal" and not lots of other types of lists.

      Despite the rampant ubiquity of "what is the difference between array vs. list in Perl" questions and musings, the question itself should mostly just be rejected. Once you pick your definition for "list" to not be a hodge-podge of concepts from quite different categories ("list literal" is a construct of Perl syntax while "list of scalar values" is an abstract concept while "list of SVs on perl's stack" doesn't fall into either of those categories). While an array is a Perl variable type and there is no "list" Perl variable type.

      So "list vs. array" is like "what is the difference between a structure and an object method". The responses that should come to mind are "what do you mean by 'structure'?" (that is, "what do you mean by 'list'?") and "you are comparing apple software vs. orangutans".

      And the most common declaration that comes out of 'list vs. array' is "a list in scalar context returns it's last item" for which a common response is "there is no such thing as a list in a scalar context". That last "list" is talking about a "list of scalar values" or, more specifically "a list of SVs on a perl stack". But that is also incorrect. It is almost true while also being an important Perl concept. For most cases, there being a scalar context means that no list of SVs will be generated and pushed onto the stack. But there are several cases where the list of SVs is generated and the scalar context just means that all but one of them gets thrown away.

      Now, an important and more general concept in Perl that can be called "list", is "list expression" (of which "list literal" is a subset). But "list expression" is a bit misleading in Perl given that previous note that most such don't actually involve a "list" (of scalar values) when evaluated in a scalar context. So a more precise name would be "expression that would produce a list of scalar values if evaluated in a list context". So you can see why this important concept gets called just "list" which leads to confusion especially when mixed with people who have adopted a definition of "Perl list" equal to either "list literal" or "list of SVs on a stack".

      Then there are things like the "list" of characters that go between square brackets in a regular expression's character class, to name just one...

      - tye        

        Thanks again for another patient explanation. I think this could be a good subject for a meditation (or five).

Re^4: Skipping parameters in sprintf %, elegantly
by bart (Canon) on Aug 20, 2008 at 09:00 UTC