rovf has asked for the wisdom of the Perl Monks concerning the following question:
I tried 3 different ways to write a function returning an empty list.
use strict;
use warnings;
sub empty_list1 {
@{ [] }
}
sub empty_list2 {
qw,,
}
sub empty_list3 {
()
}
$|=1;
print(scalar(empty_list1()),"\n");
print(scalar(empty_list2()),"\n");
print(scalar(empty_list3()),"\n");
For the print, the function is called in scalar context, so that the number of list elements should be printed. I thought the 3 variants are equivalent, but only for the first I get the expected value of 0. In the other two cases, Perl complains about uninitialized value being used.
I understand that in the first case, the return expression is an empty array, while in the non-working case, it is an empty list, but I don't understand the implications here.
--
Ronald Fischer <ynnor@mm.st>
Re: Empty List miracle(1)
by moritz (Cardinal) on Apr 29, 2010 at 09:28 UTC
|
Only arrays return the number of elements in scalar context, lists don't.
Some people say that lists don't exist in scalar context (and I disagree, but that's really a pointless discussion), but if we assume they do exist, then the default behaviour of a list is scalar context is to return its last element:
print scalar(1, 2, 3);
prrint the 3.
(Update) and the last element of an empty list is not defined, which is why you get the warning. | [reply] [d/l] |
|
There's no default.
If you say there's such a thing as a list in scalar context, it's because you're talking about list literals or the list operator. If so, the only behaviour for a list in scalar context is to return its last element after evaluating it in scalar context. undef is returned for empty lists.
# List literal in list context
>perl -E"sub c { @a=qw(d e f g); @a } say('a', 'b', c())"
abdefg
# List literal in scalar context
>perl -E"sub c { @a=qw(d e f g); @a } say(scalar('a', 'b', 'c'))"
c
# List literal in scalar context
>perl -E"sub c { @a=qw(d e f g); @a } say(scalar('a', 'b', c()))"
4 # scalar(@a)
| [reply] [d/l] [select] |
|
... the default behaviour of a list is scalar context is to return its last element...
... depending on associativity and precedence and arity and the presence of any prototypes in the surrounding expression which may change any of the former, so the choice of the word "default" is, at best, misleading.
| [reply] |
|
So what would be a better phrasing, in your opinion?
Perl 6 - links to (nearly) everything that is Perl 6.
| [reply] |
|
|
Re: Empty List miracle(1)
by JavaFan (Canon) on Apr 29, 2010 at 09:59 UTC
|
I thought the 3 variants are equivalent,
They aren't. The first is an array in scalar context. The second is qw in scalar context. The third is nothing in scalar context.
Note that none of them is a list in scalar context - there is no such thing on the language level (after all, it's context that makes list).
| [reply] [d/l] |
Re: Empty List miracle(1)
by Sandy (Curate) on Apr 29, 2010 at 13:46 UTC
|
If I understand things correctly:
qw,, in scalar context returns undef,
however in list context (assigning to an array), it will set the array to an empty array.
Similarly for ().
The real issue here is the differences between returning data in list and scalar context.
So, if you substitute your print statements for these, you will get '0' printed 3 times.
my @a;
print(scalar(@a=empty_list1()),"\n");
print(scalar(@a=empty_list2()),"\n");
print(scalar(@a=empty_list3()),"\n");
| [reply] [d/l] [select] |
|
Yes, but not for the reason you're implying. You're thinking @a is evaluated in scalar context when it's not. Both operands of the list assignment (@a and empty_listX()) are evaluated in list context.
If @a is an operand of the list assignment, what's the operand of the scalar() pseudo-operator? The list assignment. scalar() causes the list assignment to be evaluated in scalar context. In scalar context, the list assignment operator returns the number of elements returned by its right hand side operand.
Since it doesn't matter to what you are assigning, you could just as easily have written
print(scalar(()=empty_list1()),"\n"); # 0
print(scalar(()=empty_list2()),"\n"); # 0
print(scalar(()=empty_list3()),"\n"); # 0
print(scalar(()=(4..6) ),"\n"); # 3
| [reply] [d/l] [select] |
Re: Empty List miracle(1)
by ikegami (Patriarch) on Apr 30, 2010 at 14:42 UTC
|
the function is called in scalar context, so that the number of list elements should be printed.
That's not what scalar context does. Scalar context simply lets operators know they can only return a single scalar value. What that value is up to each individual operator.
Some operators (e.g. @array, grep) return the number of values that would otherwise be returned, but that's far from typical. The most common practice is to return exactly the same thing in every context.
Looking at your code, you have a number of subs evaluated in scalar context. That means their return expression is evaluated in scalar context. Your code is equivalent to
print(scalar( @{ [] } ),"\n");
print(scalar( qw,, ),"\n");
print(scalar( () ),"\n");
which the tokenizer changes into
print(scalar( @{ [] } ),"\n");
print(scalar( () ),"\n");
print(scalar( () ),"\n");
In the first case, you have an array lookup in scalar context. That returns the number of elements in the array being looked up, which is zero.
In the second and third case, you have a list literal in scalar context. That returns the last element of the list after evaluating it scalar context. If the list is empty, undef is returned.
| [reply] [d/l] [select] |
|
| [reply] [d/l] |
|
|