Perl / perl5

đŸȘ The Perl programming language
https://dev.perl.org/perl5/
Other
1.96k stars 556 forks source link

definition of truthiness in the perldocs #11485

Closed p5pRT closed 13 years ago

p5pRT commented 13 years ago

Migrated from rt.perl.org#94350 (status was 'resolved')

Searchable as RT94350$

p5pRT commented 13 years ago

From @mauke

Created by @mauke

So I was looking for the official definition of "truth" in the perldocs.

perldata says​:

| A scalar value is interpreted as TRUE in the Boolean sense if it is not | the null string or the number 0 (or its string equivalent\, "0").

perlsyn says​:

| The number 0\, the strings C\<'0'> and C\<''>\, the empty list C\<()>\, and | C\ are all false in a boolean context. All other values are true.

I think both are wrong. perldata is missing undef in its list of false values\, and perlsyn claims the empty list is false\, which doesn't even make sense. There are no lists in scalar context. Booleans are scalars. Therefore you can't have an "empty list" in boolean context (C\<()> simply evaluates to C\ but I don't know if that's documented anywhere).

I propose the following changes​:

* perldata​: A scalar value is interpreted as TRUE in the Boolean sense if it is not undef\, the empty string\, or the number 0 (or its string equivalent\, "0").

* perlsyn​: The number 0\, the strings C\<'0'> and C\<''>\, and C\ are all false in a boolean context. All other values are true.

Perl Info ``` Flags: category=docs severity=low This perlbug was built using Perl 5.12.1 - Thu Jun 3 20:09:15 CEST 2010 It is being executed now by Perl 5.14.1 - Wed Jun 22 01:57:37 CEST 2011. Site configuration information for perl 5.14.1: Configured by mauke at Wed Jun 22 01:57:37 CEST 2011. Summary of my perl5 (revision 5 version 14 subversion 1) configuration: Platform: osname=linux, osvers=2.6.37-gentoo-r4, archname=i686-linux uname='linux nora 2.6.37-gentoo-r4 #3 preempt thu may 5 20:36:24 cest 2011 i686 amd athlon(tm) 64 processor 3200+ authenticamd gnulinux ' config_args='' hint=recommended, useposix=true, d_sigaction=define useithreads=undef, usemultiplicity=undef useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef use64bitint=undef, use64bitall=undef, uselongdouble=undef usemymalloc=n, bincompat5005=undef Compiler: cc='gcc', ccflags ='-fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64', optimize='-O2', cppflags='-fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include' ccversion='', gccversion='4.6.0', gccosandvers='' intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12 ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8 alignbytes=4, prototype=define Linker and Libraries: ld='gcc', ldflags =' -fstack-protector -L/usr/local/lib' libpth=/usr/local/lib /lib /usr/lib libs=-lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc -lgdbm_compat perllibs=-lnsl -ldl -lm -lcrypt -lutil -lc libc=/lib/libc-2.12.2.so, so=so, useshrplib=false, libperl=libperl.a gnulibc_version='2.12.2' Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E' cccdlflags='-fPIC', lddlflags='-shared -O2 -L/usr/local/lib -fstack-protector' Locally applied patches: SAVEARGV0 - disable magic open in @INC for perl 5.14.1: /home/mauke/usr/local/lib/perl5/site_perl/5.14.1/i686-linux /home/mauke/usr/local/lib/perl5/site_perl/5.14.1 /home/mauke/usr/local/lib/perl5/5.14.1/i686-linux /home/mauke/usr/local/lib/perl5/5.14.1 /home/mauke/usr/local/lib/perl5/site_perl/5.14.0/i686-linux /home/mauke/usr/local/lib/perl5/site_perl/5.14.0 /home/mauke/usr/local/lib/perl5/site_perl . Environment for perl 5.14.1: HOME=/home/mauke LANG=en_US.UTF-8 LANGUAGE (unset) LC_COLLATE=POSIX LD_LIBRARY_PATH=/home/mauke/usr/local/lib LOGDIR (unset) PATH=/home/mauke/usr/local/bin:/usr/local/bin:/usr/bin:/bin:/opt/bin:/usr/i686-pc-linux-gnu/gcc-bin/4.4.5:/opt/sun-jdk-1.4.2.13/bin:/opt/sun-jdk-1.4.2.13/jre/bin:/opt/sun-jdk-1.4.2.13/jre/javaws:/opt/dmd/bin:/usr/games/bin PERL_BADLANG (unset) PERL_UNICODE=SAL SHELL=/bin/bash ```
p5pRT commented 13 years ago

From @ap

* l.mai@​web.de \perlbug\-followup@&#8203;perl\.org [2011-07-08 07​:15]​:

So I was looking for the official definition of "truth" in the perldocs.

perldata says​:

A scalar value is interpreted as TRUE in the Boolean sense
if it is not the null string or the number 0 \(or its string
equivalent\, "0"\)\.

perlsyn says​:

The number 0\, the strings C\<'0'> and C\<''>\, the empty list
C\<\(\)>\, and C\<undef> are all false in a boolean context\. All
other values are true\.

I think both are wrong.

perldata is missing undef in its list of false values

Agreed.

and perlsyn claims the empty list is false\, which doesn't even make sense. There are no lists in scalar context. Booleans are scalars. Therefore you can't have an "empty list" in boolean context (C\<()> simply evaluates to C\ but I don't know if that's documented anywhere).

I never really understood the point of the “no lists in scalar context” orthodoxy. I don’t see how it helps in reasoning about

  $foo = ();

And likewise you can write `if (()) { this_never_runs }`.

I don’t see what mistakes are caused by the inaccurate mental model in “a list in scalar context evaluates to its last element or to undef if it’s empty” or what you stand to gain by going through the gymnastics required to re-interpret list-ish syntax as being special set of operators in scalar context\, even if it’s true on a grammar level.

In any case\, the fact that you can write `if (())` remains. And I argue that it needs to be called out as another way to express falsity. If you want to be fastidious\, be my guest\, but you are going to end up with contortions like “Note that expressions that look like empty lists yield undef in scalar context\, so in the boolean sense they’ll also be false.”

But to omit it entirely because of the fact that it evaluates to undef would in my view be a disservice to anyone who does not read the document already primed with knowledge of that consequence. It’s a matter of how you approach documentation​: are you trying to be exact and concise\, or trying help the user achieve an aim?

I propose the following changes​:

* perldata​: A scalar value is interpreted as TRUE in the Boolean sense if it is not undef\, the empty string\, or the number 0 (or its string equivalent\, "0").

I don’t like the double negation in “if it is not undef”. I would reverse the sense just how perlsyn does​: a scalar value is FALSE if it is undefined\, 0\, "0" or the empty string\, and it is TRUE if it is anything else.

* perlsyn​: The number 0\, the strings C\<'0'> and C\<''>\, and C\ are all false in a boolean context. All other values are true.

As per above\, I’d want some note about empty lists here.

Regards\, -- Aristotle Pagaltzis // \<http​://plasmasturm.org/>

p5pRT commented 13 years ago

The RT System itself - Status changed from 'new' to 'open'

p5pRT commented 13 years ago

From @cowens

On Fri\, Jul 8\, 2011 at 01​:12\, l.mai@​web.de \perlbug\-followup@&#8203;perl\.org wrote​: snip

perldata is missing undef in its list of false values\, and perlsyn claims the empty list is false\, which doesn't even make sense. There are no lists in scalar context. Booleans are scalars. Therefore you can't have an "empty list" in boolean context (C\<()> simply evaluates to C\ but I don't know if that's documented anywhere). snip

The normal explanation for why there are no lists in scalar context is that what is really happening is the comma operator is in scalar context and has different behavior. There is no comma in () and ()'s name is the empty list. What logic says that you can't have an empty list in scalar context? What is () if it isn't an empty list?

It seems to be call the null list as well (from perldata)​:

The null list is represented by (). Interpolating it in a list has no effect. Thus (()\,()\,()) is equivalent to (). Similarly\, interpolating an array with no elements is the same as if no array had been interpolated at that point.

In Perl glossary it says​:

null list A list value with zero elements\, represented in Perl by () .

A quick grep for empty list\, null list\, and () revealed no documentation about what () (whatever it is called) is in scalar context.

-- Chas. Owens wonkden.net The most important skill a programmer can have is the ability to read.

p5pRT commented 13 years ago

From @cowens

On Sat\, Aug 6\, 2011 at 13​:11\, Chas. Owens \chas\.owens@&#8203;gmail\.com wrote​:

On Fri\, Jul 8\, 2011 at 01​:12\, l.mai@​web.de \perlbug\-followup@&#8203;perl\.org wrote​: snip

perldata is missing undef in its list of false values\, and perlsyn claims the empty list is false\, which doesn't even make sense. There are no lists in scalar context. Booleans are scalars. Therefore you can't have an "empty list" in boolean context (C\<()> simply evaluates to C\ but I don't know if that's documented anywhere). snip

The normal explanation for why there are no lists in scalar context is that what is really happening is the comma operator is in scalar context and has different behavior.  There is no comma in () and ()'s name is the empty list.  What logic says that you can't have an empty list in scalar context?  What is () if it isn't an empty list?

It seems to be call the null list as well (from perldata)​:

The null list is represented by (). Interpolating it in a list has no effect. Thus (()\,()\,()) is equivalent to (). Similarly\, interpolating an array with no elements is the same as if no array had been interpolated at that point.

In Perl glossary it says​:

null list A list value with zero elements\, represented in Perl by () .

A quick grep for empty list\, null list\, and () revealed no documentation about what () (whatever it is called) is in scalar context.

-- Chas. Owens wonkden.net The most important skill a programmer can have is the ability to read.

The StackOverflow user [FMc makes a good point][1]​: the () in my $s = (); might not be order of precedence parentheses\, not list parentheses. So all we have to do is define () in scalar context to be a valueless expression (and therefore undef and false) and we no longer have the contradiction; however\, I fail to see how that is easier to understand than just lying about lists in scalar context.

[1] : http​://stackoverflow.com/questions/6968393/can-the-empty-list-be-in-scalar-context

-- Chas. Owens wonkden.net The most important skill a programmer can have is the ability to read.

p5pRT commented 13 years ago

From ebhanssen@cpan.org

On Sat\, Aug 6\, 2011 at 7​:11 PM\, Chas. Owens \chas\.owens@&#8203;gmail\.com wrote​:

On Fri\, Jul 8\, 2011 at 01​:12\, l.mai@​web.de \perlbug\-followup@&#8203;perl\.org wrote​: snip

perldata is missing undef in its list of false values\, and perlsyn claims the empty list is false\, which doesn't even make sense. There are no lists in scalar context. Booleans are scalars. Therefore you can't have an "empty list" in boolean context (C\<()> simply evaluates to C\ but I don't know if that's documented anywhere). snip

The normal explanation for why there are no lists in scalar context is that what is really happening is the comma operator is in scalar context and has different behavior. There is no comma in () and ()'s name is the empty list. What logic says that you can't have an empty list in scalar context? What is () if it isn't an empty list?

It seems to be call the null list as well (from perldata)​:

The null list is represented by (). Interpolating it in a list has no effect. Thus (()\,()\,()) is equivalent to (). Similarly\, interpolating an array with no elements is the same as if no array had been interpolated at that point.

In Perl glossary it says​:

null list A list value with zero elements\, represented in Perl by () .

A quick grep for empty list\, null list\, and () revealed no documentation about what () (whatever it is called) is in scalar context.

  I've taken to calling C\<()> nil – where nil is neither a proper value nor properly an expression\, but a generic expression that in list context evaluates to the empty list\, and in scalar context evaluates to undef.

  There are other ways to get nils. \<do{}> is nil. C\<return;> will return nil\, and so the function call will be nil. C\<()> is just the shortest way to write it. (One character shorter than a keyword C\ would be\, even.)

  But there are other expressions that evaluate to the empty list (or null list) in list context\, and do not evaluate to undef in scalar context. C\<my @​x>\, for instance\, is an empty list in list context. In scalar context\, it is a 0. Hence not a nil.

  Referring to C\<()> as simply an empty list\, misses the scalar-context distinction\, and may so be misleading.

  In list context\, you could call C\<()> an empty list. No problem.

  In unspecified or generic context\, you could call C\<()> a "literal empty list". That will do\, if a but of a mouthful. Or\, to avoid the hateful list-in-scalar-context idiom\, something else.

  Like "nil". :)

Eirik

p5pRT commented 13 years ago

From @cowens

On Sat\, Aug 6\, 2011 at 13​:47\, Eirik Berg Hanssen \ebhanssen@&#8203;cpan\.org wrote​:

On Sat\, Aug 6\, 2011 at 7​:11 PM\, Chas. Owens \chas\.owens@&#8203;gmail\.com wrote​:

On Fri\, Jul 8\, 2011 at 01​:12\, l.mai@​web.de \perlbug\-followup@&#8203;perl\.org wrote​: snip

perldata is missing undef in its list of false values\, and perlsyn claims the empty list is false\, which doesn't even make sense. There are no lists in scalar context. Booleans are scalars. Therefore you can't have an "empty list" in boolean context (C\<()> simply evaluates to C\ but I don't know if that's documented anywhere). snip

The normal explanation for why there are no lists in scalar context is that what is really happening is the comma operator is in scalar context and has different behavior.  There is no comma in () and ()'s name is the empty list.  What logic says that you can't have an empty list in scalar context?  What is () if it isn't an empty list?

It seems to be call the null list as well (from perldata)​:

The null list is represented by (). Interpolating it in a list has no effect. Thus (()\,()\,()) is equivalent to (). Similarly\, interpolating an array with no elements is the same as if no array had been interpolated at that point.

In Perl glossary it says​:

null list A list value with zero elements\, represented in Perl by () .

A quick grep for empty list\, null list\, and () revealed no documentation about what () (whatever it is called) is in scalar context.

  I've taken to calling C\<()> nil – where nil is neither a proper value nor properly an expression\, but a generic expression that in list context evaluates to the empty list\, and in scalar context evaluates to undef.

  There are other ways to get nils.  \<do{}> is nil.  C\<return;> will return nil\, and so the function call will be nil.    C\<()> is just the shortest way to write it.  (One character shorter than a keyword C\ would be\, even.)

  But there are other expressions that evaluate to the empty list (or null list) in list context\, and do not evaluate to undef in scalar context.  C\<my @​x>\, for instance\, is an empty list in list context.  In scalar context\, it is a 0.  Hence not a nil.

  Referring to C\<()> as simply an empty list\, misses the scalar-context distinction\, and may so be misleading.

  In list context\, you could call C\<()> an empty list.  No problem.

  In unspecified or generic context\, you could call C\<()> a "literal empty list".  That will do\, if a but of a mouthful.  Or\, to avoid the hateful list-in-scalar-context idiom\, something else.

  Like "nil". :)

Eirik

my $s = my @​a;

isn't the empty list in scalar context\, it is an array in scalar context. We can tell it isn't a list because you can push onto it​:

perl -E 'push my @​a\, 5; say @​a'

-- Chas. Owens wonkden.net The most important skill a programmer can have is the ability to read.

p5pRT commented 13 years ago

From @cowens

On Sat\, Aug 6\, 2011 at 13​:58\, Chas. Owens \chas\.owens@&#8203;gmail\.com wrote​:

On Sat\, Aug 6\, 2011 at 13​:47\, Eirik Berg Hanssen \ebhanssen@&#8203;cpan\.org wrote​:

On Sat\, Aug 6\, 2011 at 7​:11 PM\, Chas. Owens \chas\.owens@&#8203;gmail\.com wrote​:

On Fri\, Jul 8\, 2011 at 01​:12\, l.mai@​web.de \perlbug\-followup@&#8203;perl\.org wrote​: snip

perldata is missing undef in its list of false values\, and perlsyn claims the empty list is false\, which doesn't even make sense. There are no lists in scalar context. Booleans are scalars. Therefore you can't have an "empty list" in boolean context (C\<()> simply evaluates to C\ but I don't know if that's documented anywhere). snip

The normal explanation for why there are no lists in scalar context is that what is really happening is the comma operator is in scalar context and has different behavior.  There is no comma in () and ()'s name is the empty list.  What logic says that you can't have an empty list in scalar context?  What is () if it isn't an empty list?

It seems to be call the null list as well (from perldata)​:

The null list is represented by (). Interpolating it in a list has no effect. Thus (()\,()\,()) is equivalent to (). Similarly\, interpolating an array with no elements is the same as if no array had been interpolated at that point.

In Perl glossary it says​:

null list A list value with zero elements\, represented in Perl by () .

A quick grep for empty list\, null list\, and () revealed no documentation about what () (whatever it is called) is in scalar context.

  I've taken to calling C\<()> nil – where nil is neither a proper value nor properly an expression\, but a generic expression that in list context evaluates to the empty list\, and in scalar context evaluates to undef.

  There are other ways to get nils.  \<do{}> is nil.  C\<return;> will return nil\, and so the function call will be nil.    C\<()> is just the shortest way to write it.  (One character shorter than a keyword C\ would be\, even.)

  But there are other expressions that evaluate to the empty list (or null list) in list context\, and do not evaluate to undef in scalar context.  C\<my @​x>\, for instance\, is an empty list in list context.  In scalar context\, it is a 0.  Hence not a nil.

  Referring to C\<()> as simply an empty list\, misses the scalar-context distinction\, and may so be misleading.

  In list context\, you could call C\<()> an empty list.  No problem.

  In unspecified or generic context\, you could call C\<()> a "literal empty list".  That will do\, if a but of a mouthful.  Or\, to avoid the hateful list-in-scalar-context idiom\, something else.

  Like "nil". :)

Eirik

my $s = my @​a;

isn't the empty list in scalar context\, it is an array in scalar context.  We can tell it isn't a list because you can push onto it​:

perl -E 'push my @​a\, 5; say @​a' snip

That said\, renaming () to nil isn't a bad idea. It avoids the confusion causing word "list". Of course\, we still have to explain why the syntax () (which looks like a list) produces a nil value.

-- Chas. Owens wonkden.net The most important skill a programmer can have is the ability to read.

p5pRT commented 13 years ago

From ebhanssen@cpan.org

On Sat\, Aug 6\, 2011 at 8​:05 PM\, Chas. Owens \chas\.owens@&#8203;gmail\.com wrote​:

my $s = my @​a;

isn't the empty list in scalar context\, it is an array in scalar context.

  I didn't say it was. Lists in scalar context? Nope. Not me.

  I said C\<my @​x> *in list context* is an empty list. I also said C\<my @​x> is 0 *in scalar context.* Such as the scalar assignment into which you've placed it here. (In list assignment\, like C\<my ($s) = my @​a;>\, it would still be an empty list. Element 0 of which is undef ...)

That said\, renaming () to nil isn't a bad idea. It avoids the confusion causing word "list". Of course\, we still have to explain why the syntax () (which looks like a list) produces a nil value.

  Well\, nil\, as I sketched it\, isn't exactly a value. It evaluates to different values in different contexts. Like expressions.

  And C\<()> does not look like a list unless you're conditioned to think of parentheses making a list. (They don't – list context makes lists.) And that is one conditioning I would like to challenge.

  C\<()> is an expression. One (of several) I've taken to call nil.

Eirik

p5pRT commented 13 years ago

From @druud62

On 2011-08-06 18​:28\, Aristotle Pagaltzis wrote​:

you can write `if (()) { this_never_runs }`.

And also `if ( (1\, 0) ) { this_never_runs }`.

-- Ruud

p5pRT commented 13 years ago

From @cowens

On Sat\, Aug 6\, 2011 at 14​:05\, Chas. Owens \chas\.owens@&#8203;gmail\.com wrote​:

On Sat\, Aug 6\, 2011 at 13​:58\, Chas. Owens \chas\.owens@&#8203;gmail\.com wrote​:

On Sat\, Aug 6\, 2011 at 13​:47\, Eirik Berg Hanssen \ebhanssen@&#8203;cpan\.org wrote​:

On Sat\, Aug 6\, 2011 at 7​:11 PM\, Chas. Owens \chas\.owens@&#8203;gmail\.com wrote​:

On Fri\, Jul 8\, 2011 at 01​:12\, l.mai@​web.de \perlbug\-followup@&#8203;perl\.org wrote​: snip

perldata is missing undef in its list of false values\, and perlsyn claims the empty list is false\, which doesn't even make sense. There are no lists in scalar context. Booleans are scalars. Therefore you can't have an "empty list" in boolean context (C\<()> simply evaluates to C\ but I don't know if that's documented anywhere). snip

The normal explanation for why there are no lists in scalar context is that what is really happening is the comma operator is in scalar context and has different behavior.  There is no comma in () and ()'s name is the empty list.  What logic says that you can't have an empty list in scalar context?  What is () if it isn't an empty list?

It seems to be call the null list as well (from perldata)​:

The null list is represented by (). Interpolating it in a list has no effect. Thus (()\,()\,()) is equivalent to (). Similarly\, interpolating an array with no elements is the same as if no array had been interpolated at that point.

In Perl glossary it says​:

null list A list value with zero elements\, represented in Perl by () .

A quick grep for empty list\, null list\, and () revealed no documentation about what () (whatever it is called) is in scalar context.

  I've taken to calling C\<()> nil – where nil is neither a proper value nor properly an expression\, but a generic expression that in list context evaluates to the empty list\, and in scalar context evaluates to undef.

  There are other ways to get nils.  \<do{}> is nil.  C\<return;> will return nil\, and so the function call will be nil.    C\<()> is just the shortest way to write it.  (One character shorter than a keyword C\ would be\, even.)

  But there are other expressions that evaluate to the empty list (or null list) in list context\, and do not evaluate to undef in scalar context.  C\<my @​x>\, for instance\, is an empty list in list context.  In scalar context\, it is a 0.  Hence not a nil.

  Referring to C\<()> as simply an empty list\, misses the scalar-context distinction\, and may so be misleading.

  In list context\, you could call C\<()> an empty list.  No problem.

  In unspecified or generic context\, you could call C\<()> a "literal empty list".  That will do\, if a but of a mouthful.  Or\, to avoid the hateful list-in-scalar-context idiom\, something else.

  Like "nil". :)

Eirik

my $s = my @​a;

isn't the empty list in scalar context\, it is an array in scalar context.  We can tell it isn't a list because you can push onto it​:

perl -E 'push my @​a\, 5; say @​a' snip

That said\, renaming () to nil isn't a bad idea.  It avoids the confusion causing word "list".  Of course\, we still have to explain why the syntax () (which looks like a list) produces a nil value. snip

ikegami over on StackOverflow makes [another good point][1]​: () is treat by perl as stub. stub is not a list. It can be a (non-)value in a list (which winks out of existence when you look at it)\, or it can be assigned to a scalar (in which case it becomes undef)​:

perl -MO=Concise -e '(()\,5\,())' 7 \<@​> leave[1 ref] vKP/REFC ->(end) 1 \<0> enter ->2 2 \<;> nextstate(main 1 -e​:1) v​:{ ->3 6 \<@​> list vKP ->7 3 \<0> pushmark v ->4 4 \<0> stub vP ->5 - \<0> ex-const v ->5 5 \<0> stub vP ->6 -e syntax OK

Even when used by itself in list assignment\, it isn't a list​:

perl -MO=Concise -e 'my @​a = ()' 7 \<@​> leave[1 ref] vKP/REFC ->(end) 1 \<0> enter ->2 2 \<;> nextstate(main 1 -e​:1) v​:{ ->3 6 \<2> aassign[t2] vKS ->7 - \<1> ex-list lK ->4 3 \<0> pushmark s ->4 - \<0> stub lP ->- - \<1> ex-list lK ->6 4 \<0> pushmark s ->5 5 \<0> padav[@​a​:1\,2] lRM*/LVINTRO ->6 -e syntax OK

A list is built around the stub.

Given this\, I would say that it is appropriate to call the null list a false value. I think the change we need is in perlglossary​:

Inline Patch ```diff diff --git a/pod/perlglossary.pod b/pod/perlglossary.pod index 2389872..22c815b 100644 --- a/pod/perlglossary.pod +++ b/pod/perlglossary.pod @@ -950,6 +950,10 @@ When something is contained in something else, ```

particularly when that might be considered surprising​: "I've embedded a complete Perl interpreter in my editor!"

+=item empty list + +See \</null list>. + =item empty subclass test

The notion that an empty L\</derived class> should behave exactly like @​@​ -1067\,7 +1071\,8 @​@​ such as multithreading.

In Perl\, any value that would look like C\<""> or C\<"0"> if evaluated in a string context. Since undefined values evaluate to C\<"">\, all -undefined values are false\, but not all false values are undefined. +undefined values are false (including the L\</null list>)\, but not all +false values are undefined.

=item FAQ

@​@​ -2023\,7 +2028\,7 @​@​ strings\, but Perl allows strings to contain a null.

=item null list

-A L\</list value> with zero elements\, represented in Perl by C\<()>. +A valueless value represented in Perl by C\<()>. It is not really a L\\, but a value that yields L\ in L\</scalar context> and a L\</list value> with zero elements in L\</list context>.

=item null string

[1] : http​://stackoverflow.com/questions/6968393/can-the-empty-list-be-in-scalar-context/6970812#6970812

-- Chas. Owens wonkden.net The most important skill a programmer can have is the ability to read.

p5pRT commented 13 years ago

From @cpansprout

On Sat Aug 06 09​:29​:22 2011\, aristotle wrote​:

* l.mai@​web.de \perlbug\-followup@&#8203;perl\.org [2011-07-08 07​:15]​:

So I was looking for the official definition of "truth" in the perldocs.

perldata says​:

A scalar value is interpreted as TRUE in the Boolean sense
if it is not the null string or the number 0 \(or its string
equivalent\, "0"\)\.

perlsyn says​:

The number 0\, the strings C\<'0'> and C\<''>\, the empty list
C\<\(\)>\, and C\<undef> are all false in a boolean context\. All
other values are true\.

I think both are wrong.

perldata is missing undef in its list of false values

Agreed.

and perlsyn claims the empty list is false\, which doesn't even make sense. There are no lists in scalar context. Booleans are scalars. Therefore you can't have an "empty list" in boolean context (C\<()> simply evaluates to C\ but I don't know if that's documented anywhere).

I never really understood the point of the “no lists in scalar context” orthodoxy. I don’t see how it helps in reasoning about

$foo = \(\);

And likewise you can write `if (()) { this_never_runs }`.

I don’t see what mistakes are caused by the inaccurate mental model in “a list in scalar context evaluates to its last element or to undef if it’s empty” or what you stand to gain by going through the gymnastics required to re-interpret list-ish syntax as being special set of operators in scalar context\, even if it’s true on a grammar level.

In any case\, the fact that you can write `if (())` remains. And I argue that it needs to be called out as another way to express falsity. If you want to be fastidious\, be my guest\, but you are going to end up with contortions like “Note that expressions that look like empty lists yield undef in scalar context\, so in the boolean sense they’ll also be false.”

But to omit it entirely because of the fact that it evaluates to undef would in my view be a disservice to anyone who does not read the document already primed with knowledge of that consequence. It’s a matter of how you approach documentation​: are you trying to be exact and concise\, or trying help the user achieve an aim?

I propose the following changes​:

* perldata​: A scalar value is interpreted as TRUE in the Boolean sense if it is not undef\, the empty string\, or the number 0 (or its string equivalent\, "0").

I don’t like the double negation in “if it is not undef”. I would reverse the sense just how perlsyn does​: a scalar value is FALSE if it is undefined\, 0\, "0" or the empty string\, and it is TRUE if it is anything else.

* perlsyn​: The number 0\, the strings C\<'0'> and C\<''>\, and C\ are all false in a boolean context. All other values are true.

As per above\, I’d want some note about empty lists here.

Regards\,

I’ve just made a change (32860eee) that mentions undefined in perldata and removes the double negative.

I don’t think perldata needs to mention the empty list\, because the empty-list-as-undef is a side effect of *syntax*\, and does not apply to data. (Hence perlsyn should keep it.)

p5pRT commented 13 years ago

@cpansprout - Status changed from 'open' to 'resolved'

p5pRT commented 13 years ago

From @cpansprout

On Sun Aug 07 04​:04​:34 2011\, cowens wrote​:

A list is built around the stub.

Given this\, I would say that it is appropriate to call the null list a false value. I think the change we need is in perlglossary​:

diff --git a/pod/perlglossary.pod b/pod/perlglossary.pod index 2389872..22c815b 100644 --- a/pod/perlglossary.pod +++ b/pod/perlglossary.pod @​@​ -950\,6 +950\,10 @​@​ When something is contained in something else\, particularly when that might be considered surprising​: "I've embedded a complete Perl interpreter in my editor!"

+=item empty list + +See \</null list>. + =item empty subclass test

The notion that an empty L\</derived class> should behave exactly like @​@​ -1067\,7 +1071\,8 @​@​ such as multithreading.

In Perl\, any value that would look like C\<""> or C\<"0"> if evaluated in a string context. Since undefined values evaluate to C\<"">\, all -undefined values are false\, but not all false values are undefined. +undefined values are false (including the L\</null list>)\, but not all +false values are undefined.

=item FAQ

@​@​ -2023\,7 +2028\,7 @​@​ strings\, but Perl allows strings to contain a null.

=item null list

-A L\</list value> with zero elements\, represented in Perl by C\<()>. +A valueless value represented in Perl by C\<()>. It is not really a L\\, but a value that yields L\ in L\</scalar context> and a L\</list value> with zero elements in L\</list context>.

=item null string

[1] : http​://stackoverflow.com/questions/6968393/can-the-empty-list- be-in-scalar-context/6970812#6970812

Thank you. Applied as 3097ec40\, with a tweak in commit 9303c02d1.

p5pRT commented 13 years ago

From @ikegami

On Fri\, Jul 8\, 2011 at 1​:12 AM\, l.mai@​web.de \perlbug\-followup@&#8203;perl\.orgwrote​:

# New Ticket Created by l.mai@​web.de # Please include the string​: [perl #94350] # in the subject line of all future correspondence about this issue. # \<URL​: https://rt-archive.perl.org/perl5/Ticket/Display.html?id=94350 >

This is a bug report for perl from l.mai@​web.de\, generated with the help of perlbug 1.39 running under perl 5.14.1.

----------------------------------------------------------------- [Please describe your issue here]

So I was looking for the official definition of "truth" in the perldocs.

perldata says​:

| A scalar value is interpreted as TRUE in the Boolean sense if it is not | the null string or the number 0 (or its string equivalent\, "0").

perlsyn says​:

| The number 0\, the strings C\<'0'> and C\<''>\, the empty list C\<()>\, and | C\ are all false in a boolean context. All other values are true.

The most concise and accurate definition I've come across is​:

Anything that stringifies to "" or "0" is a false value

This definition covers objects with overrides. Examples can be appended.

perlsyn claims the empty list is false\, which doesn't even make sense. There are no lists in scalar context.

There's no such thing as a list *value* in scalar context\, but the list *operator* can definitely be used in scalar context.

my $x = (1\,2\,3);

Booleans are scalars. Therefore you can't have an "empty list"

in boolean context (C\<()> simply evaluates to C\ but I don't know if that's documented anywhere).

True\, "()" evaluates to undef. But that's false\, so what's the issue?

- Eric

p5pRT commented 13 years ago

From tchrist@perl.com

Eric Brine \ikegami@&#8203;adaelis\.com wrote   on Sun\, 18 Sep 2011 00​:44​:21 EDT​:

So I was looking for the official definition of "truth" in the perldocs.

perldata says​:

| A scalar value is interpreted as TRUE in the Boolean sense if it is not | the null string or the number 0 (or its string equivalent\, "0").

perlsyn says​:

| The number 0\, the strings C\<'0'> and C\<''>\, the empty list C\<()>\, and | C\ are all false in a boolean context. All other values are true.

The most concise and accurate definition I've come across is​:

Anything that stringifies to "" or "0" is a false value

This definition covers objects with overrides. Examples can be appended.

That seems sounds good.

perlsyn claims the empty list is false\, which doesn't even make sense. There are no lists in scalar context.

There's no such thing as a list *value* in scalar context\, but the list *operator* can definitely be used in scalar context.

my $x = \(1\,2\,3\);

What is this thing you are calling "*the* list operator"? I know what "*a* list operator" is\, but I don't get the "the" part.

In what you have written there\, there is nothing listy happening anywhere\, so I cannot see "the" list operator you speak of.

  % perl -wle 'my $x = (9\,8\,7\,6); print $x'   Useless use of a constant (9) in void context at -e line 1.   Useless use of a constant (8) in void context at -e line 1.   Useless use of a constant (7) in void context at -e line 1.   6

Regarding ()\, I don't want to risk people getting confused about what () really is\, and what it is really doing. The empty list evaporates during list interpolation​:

  % perl -wle 'print for 9\,8\,()\,(())\,7\,6\,()'   9   8   7   6

There are no blank output lines there​:

  % perl -wle 'print for (9\,8\,()\,( () )\,7\,6\, ())' | cat -n   1 9   2 8   3 7   4 6

In contrast\, here there is​:

  % perl -wle 'my $x = (9\,8\,()\,( () )\,7\,6\, ()); print $x' | cat -n   Useless use of a constant (9) in void context at -e line 1.   Useless use of a constant (8) in void context at -e line 1.   Useless use of a constant (7) in void context at -e line 1.   Useless use of a constant (6) in void context at -e line 1.   Use of uninitialized value $x in print at -e line 1.   1

Booleans are scalars. Therefore you can't have an "empty list"

What would you prefer to call () when it is used in scalarly\, then? Empty parens? I'm not sure that that is especially useful.

  % perl -wE 'say "what" unless ()'   what

  % perl -wE 'say "what" unless my $x=()'   what

  % perl -wE 'unless (()) { say "what" }'   what

Interestingly\, these are completely equivalent​:

  return;   return ();

in boolean context (C\<()> simply evaluates to C\ but I don't know if that's documented anywhere).

True\, "()" evaluates to undef. But that's false\, so what's the issue?

I *think* he's trying to say whether something is false without having to run it through stringification\, since boolean tests don't actually need to do that to determine their truth value.

--tom

p5pRT commented 13 years ago

From @ikegami

On Sun\, Sep 18\, 2011 at 2​:24 PM\, Tom Christiansen \tchrist@&#8203;perl\.com wrote​:

Eric Brine \ikegami@&#8203;adaelis\.com wrote

There's no such thing as a list *value* in scalar context\, but the list

*operator* can definitely be used in scalar context.

my $x = \(1\,2\,3\);

What is this thing you are calling "*the* list operator"? I know what "*a* list operator" is\, but I don't get the "the" part.

It's an operator that evaluates each of its operands in turn. It is called that internally\, by perlop (indirectly\, along with "comma operator") and by Perl users.

perl -MO=Concise -e"my $x = (1\,2\,3);" 8 \<@​> leave[1 ref] vKP/REFC ->(end) 1 \<0> enter ->2 2 \<;> nextstate(main 1 -e​:1) v​:{ ->3 7 \<2> sassign vKS/2 ->8 5 \<@​> list sKP ->6 3 \<0> pushmark v ->4 - \<0> ex-const v ->- - \<0> ex-const v ->4 4 \<$> const[IV 3] s ->5 6 \<0> padsv[$x​:1\,2] sRM*/LVINTRO ->7 -e syntax OK

Pretending it doesn't exist is causing a lot confusion among users.

Regarding ()\, I don't want to risk people getting confused about

what () really is\, and what it is really doing. The empty list evaporates during list interpolation​:

% perl -wle 'print for 9\,8\,()\,(())\,7\,6\,()' 9 8 7 6

There are no blank output lines there​:

% perl -wle 'print for (9\,8\,()\,( () )\,7\,6\, ())' | cat -n 1 9 2 8 3 7 4 6

In contrast\, here there is​:

% perl -wle 'my $x = (9\,8\,()\,( () )\,7\,6\, ()); print $x' | cat -n Useless use of a constant (9) in void context at -e line 1. Useless use of a constant (8) in void context at -e line 1. Useless use of a constant (7) in void context at -e line 1. Useless use of a constant (6) in void context at -e line 1. Use of uninitialized value $x in print at -e line 1. 1

"Nil" evaluates to nothing an empty list context and to undef in scalar context\, so no surprise there.

What would you prefer to call () when it is used in scalarly\,

then? Empty parens? I'm not sure that that is especially useful.

Are you asking me? Internally\, it's called "stub"\, but I don't like that. I like the "nil" someone recommended.

Interestingly\, these are completely equivalent​:

return; return ();

The opcode tree is different\, so they are only functionally equivalent. return (((()))) is completely equivalent to return ()\, though.

in boolean context (C\<()> simply evaluates to C\ but I don't know if that's documented anywhere).

True\, "()" evaluates to undef. But that's false\, so what's the issue?

I *think* he's trying to say whether something is false without having to run it through stringification\, since boolean tests don't actually need to do that to determine their truth value.

The stringification of () isn't undef\, so I don't follow.

- Eric