Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

possible documentation error in perldata #16288

Open
p5pRT opened this issue Dec 7, 2017 · 14 comments
Open

possible documentation error in perldata #16288

p5pRT opened this issue Dec 7, 2017 · 14 comments
Labels
Closable?

Comments

@p5pRT
Copy link

@p5pRT p5pRT commented Dec 7, 2017

Migrated from rt.perl.org#132537 (status was 'open')

Searchable as RT132537$

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Dec 7, 2017

From calestyo@scientia.net

This is a bug report for perl from calestyo@​scientia.net,
generated with the help of perlbug 1.40 running under perl 5.26.1.


Hi.

https://perldoc.perl.org/perldata.html says​:

LISTs do automatic interpolation of sublists. That is, when a LIST is evaluated,
each element of the list is evaluated in list context, and the resulting list
value is interpolated into LIST just as if each individual element were a member of LIST.

This seems to be wrong, in the sense, that the list
itself doesn't mandate its elements to be evaluated
in list context.
It's rather the context in which the list is evaluated
which determines the context which can be scalar
or list contect.

E.g.
$ perl -de1

Loading DB routines from perl5db.pl version 1.51
Editor support available.

Enter h or 'h h' for help, or 'man perldebug' for more help.

main​::(-e​:1)​: 1
  DB<1> @​a=("a", "b", "c", "d");

  DB<2> @​b=(1, 2, @​a);

  DB<3> print "@​b";
1 2 a b c d
  DB<4> $b=(1, 2, @​a);

  DB<5> print "$b";
4
  DB<6> @​a=("a", "b", "c", "d", "e", "f");

  DB<7> $b=(1, 2, @​a);

  DB<8> print "$b";
6
  DB<9>

When doing $b=(1, 2, @​a); the list is evaluated in scalar context
and thus $b gets the last element of the list assigned.
If the list itself, i.e. it's elements, would be evaluated in list
context, as the above text claims, the last element should become
"d", however it seems to be evaluated in scalar context, which means
@​a evaluates to the length of the array a, which is then also the
last element of the list, being assigned to $b.

Cheers,
Chris.



Flags​:
  category=docs
  severity=medium


Site configuration information for perl 5.26.1​:

Configured by Debian Project at Tue Nov 28 17​:44​:14 UTC 2017.

Summary of my perl5 (revision 5 version 26 subversion 1) configuration​:
 
  Platform​:
  osname=linux
  osvers=4.9.0
  archname=x86_64-linux-gnu-thread-multi
  uname='linux localhost 4.9.0 #1 smp debian 4.9.0 x86_64 gnulinux '
  config_args='-Dusethreads -Duselargefiles -Dcc=x86_64-linux-gnu-gcc -Dcpp=x86_64-linux-gnu-cpp -Dld=x86_64-linux-gnu-gcc -Dccflags=-DDEBIAN -Wdate-time -D_FORTIFY_SOURCE=2 -g -O2 -fdebug-prefix-map=/build/perl-w2lU16/perl-5.26.1=. -fstack-protector-strong -Wformat -Werror=format-security -Dldflags= -Wl,-z,relro -Dlddlflags=-shared -Wl,-z,relro -Dcccdlflags=-fPIC -Darchname=x86_64-linux-gnu -Dprefix=/usr -Dprivlib=/usr/share/perl/5.26 -Darchlib=/usr/lib/x86_64-linux-gnu/perl/5.26 -Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/x86_64-linux-gnu/perl5/5.26 -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.26.1 -Dsitearch=/usr/local/lib/x86_64-linux-gnu/perl/5.26.1 -Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 -Dsiteman1dir=/usr/local/man/man1 -Dsiteman3dir=/usr/local/man/man3 -Duse64bitint -Dman1ext=1 -Dman3ext=3perl
-Dpager=/usr/bin/sensible-pager -Uafs -Ud_csh -Ud_ualarm -Uusesfio -Uusenm -Ui_libutil -Ui_xlocale -Uversiononly -DDEBUGGING=-g -Doptimize=-O2 -dEs -Duseshrplib -Dlibperl=libperl.so.5.26.1'
  hint=recommended
  useposix=true
  d_sigaction=define
  useithreads=define
  usemultiplicity=define
  use64bitint=define
  use64bitall=define
  uselongdouble=undef
  usemymalloc=n
  default_inc_excludes_dot=define
  bincompat5005=undef
  Compiler​:
  cc='x86_64-linux-gnu-gcc'
  ccflags ='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fwrapv -fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'
  optimize='-O2 -g'
  cppflags='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fwrapv -fno-strict-aliasing -pipe -I/usr/local/include'
  ccversion=''
  gccversion='7.2.0'
  gccosandvers=''
  intsize=4
  longsize=8
  ptrsize=8
  doublesize=8
  byteorder=12345678
  doublekind=3
  d_longlong=define
  longlongsize=8
  d_longdbl=define
  longdblsize=16
  longdblkind=3
  ivtype='long'
  ivsize=8
  nvtype='double'
  nvsize=8
  Off_t='off_t'
  lseeksize=8
  alignbytes=8
  prototype=define
  Linker and Libraries​:
  ld='x86_64-linux-gnu-gcc'
  ldflags =' -fstack-protector-strong -L/usr/local/lib'
  libpth=/usr/local/lib /usr/lib/gcc/x86_64-linux-gnu/7/include-fixed /usr/include/x86_64-linux-gnu /usr/lib /lib/x86_64-linux-gnu /lib/../lib /usr/lib/x86_64-linux-gnu /usr/lib/../lib /lib
  libs=-lgdbm -lgdbm_compat -ldb -ldl -lm -lpthread -lc -lcrypt
  perllibs=-ldl -lm -lpthread -lc -lcrypt
  libc=libc-2.25.so
  so=so
  useshrplib=true
  libperl=libperl.so.5.26
  gnulibc_version='2.25'
  Dynamic Linking​:
  dlsrc=dl_dlopen.xs
  dlext=so
  d_dlsymun=undef
  ccdlflags='-Wl,-E'
  cccdlflags='-fPIC'
  lddlflags='-shared -L/usr/local/lib -fstack-protector-strong'

Locally applied patches​:
  DEBPKG​:debian/cpan_definstalldirs - Provide a sensible INSTALLDIRS default for modules installed from CPAN.
  DEBPKG​:debian/db_file_ver - https://bugs.debian.org/340047 Remove overly restrictive DB_File version check.
  DEBPKG​:debian/doc_info - Replace generic man(1) instructions with Debian-specific information.
  DEBPKG​:debian/enc2xs_inc - https://bugs.debian.org/290336 Tweak enc2xs to follow symlinks and ignore missing @​INC directories.
  DEBPKG​:debian/errno_ver - https://bugs.debian.org/343351 Remove Errno version check due to upgrade problems with long-running processes.
  DEBPKG​:debian/libperl_embed_doc - https://bugs.debian.org/186778 Note that libperl-dev package is required for embedded linking
  DEBPKG​:fixes/respect_umask - Respect umask during installation
  DEBPKG​:debian/writable_site_dirs - Set umask approproately for site install directories
  DEBPKG​:debian/extutils_set_libperl_path - EU​:MM​: set location of libperl.a under /usr/lib
  DEBPKG​:debian/no_packlist_perllocal - Don't install .packlist or perllocal.pod for perl or vendor
  DEBPKG​:debian/fakeroot - Postpone LD_LIBRARY_PATH evaluation to the binary targets.
  DEBPKG​:debian/instmodsh_doc - Debian policy doesn't install .packlist files for core or vendor.
  DEBPKG​:debian/ld_run_path - Remove standard libs from LD_RUN_PATH as per Debian policy.
  DEBPKG​:debian/libnet_config_path - Set location of libnet.cfg to /etc/perl/Net as /usr may not be writable.
  DEBPKG​:debian/mod_paths - Tweak @​INC ordering for Debian
  DEBPKG​:debian/perlivp - https://bugs.debian.org/510895 Make perlivp skip include directories in /usr/local
  DEBPKG​:debian/deprecate-with-apt - https://bugs.debian.org/747628 Point users to Debian packages of deprecated core modules
  DEBPKG​:debian/squelch-locale-warnings - https://bugs.debian.org/508764 Squelch locale warnings in Debian package maintainer scripts
  DEBPKG​:debian/patchlevel - https://bugs.debian.org/567489 List packaged patches for 5.26.1-3 in patchlevel.h
  DEBPKG​:fixes/document_makemaker_ccflags - https://bugs.debian.org/628522 [rt.cpan.org #68613] Document that CCFLAGS should include $Config{ccflags}
  DEBPKG​:debian/find_html2text - https://bugs.debian.org/640479 Configure CPAN​::Distribution with correct name of html2text
  DEBPKG​:debian/perl5db-x-terminal-emulator.patch - https://bugs.debian.org/668490 Invoke x-terminal-emulator rather than xterm in perl5db.pl
  DEBPKG​:debian/cpan-missing-site-dirs - https://bugs.debian.org/688842 Fix CPAN​::FirstTime defaults with nonexisting site dirs if a parent is writable
  DEBPKG​:fixes/memoize_storable_nstore - [rt.cpan.org #77790] https://bugs.debian.org/587650 Memoize​::Storable​: respect 'nstore' option not respected
  DEBPKG​:debian/makemaker-pasthru - https://bugs.debian.org/758471 Pass LD settings through to subdirectories
  DEBPKG​:debian/makemaker-manext - https://bugs.debian.org/247370 Make EU​::MakeMaker honour MANnEXT settings in generated manpage headers
  DEBPKG​:debian/kfreebsd-softupdates - https://bugs.debian.org/796798 Work around Debian Bug#796798
  DEBPKG​:fixes/autodie-scope - https://bugs.debian.org/798096 Fix a scoping issue with "no autodie" and the "system" sub
  DEBPKG​:fixes/memoize-pod - [rt.cpan.org #89441] Fix POD errors in Memoize
  DEBPKG​:debian/hurd-softupdates - https://bugs.debian.org/822735 Fix t/op/stat.t failures on hurd
  DEBPKG​:fixes/math_complex_doc_great_circle - https://bugs.debian.org/697567 [rt.cpan.org #114104] Math​::Trig​: clarify definition of great_circle_midpoint
  DEBPKG​:fixes/math_complex_doc_see_also - https://bugs.debian.org/697568 [rt.cpan.org #114105] Math​::Trig​: add missing SEE ALSO
  DEBPKG​:fixes/math_complex_doc_angle_units - https://bugs.debian.org/731505 [rt.cpan.org #114106] Math​::Trig​: document angle units
  DEBPKG​:fixes/cpan_web_link - https://bugs.debian.org/367291 CPAN​: Add link to main CPAN web site
  DEBPKG​:fixes/time_piece_doc - https://bugs.debian.org/817925 Time​::Piece​: Improve documentation for add_months and add_years
  DEBPKG​:fixes/extutils_makemaker_reproducible - https​://bugs.debian.org/835815 https://bugs.debian.org/834190 Make perllocal.pod files reproducible
  DEBPKG​:fixes/file_path_hurd_errno - File-Path​: Fix test failure in Hurd due to hard-coded ENOENT
  DEBPKG​:debian/hppa_op_optimize_workaround - https://bugs.debian.org/838613 Temporarily lower the optimization of op.c on hppa due to gcc-6 problems
  DEBPKG​:debian/installman-utf8 - https://bugs.debian.org/840211 Generate man pages with UTF-8 characters
  DEBPKG​:fixes/file_path_chmod_race - https://bugs.debian.org/863870 [rt.cpan.org #121951] Prevent directory chmod race attack.
  DEBPKG​:fixes/extutils_file_path_compat - Correct the order of tests of chmod(). (#294)
  DEBPKG​:fixes/getopt-long-2 - [rt.cpan.org #120300] Withdraw part of commit 5d9947fb445327c7299d8beb009d609bc70066c0, which tries to implement more GNU getopt_long campatibility. GNU
  DEBPKG​:fixes/getopt-long-3 - provide a default value for optional arguments
  DEBPKG​:fixes/getopt-long-4 - https://bugs.debian.org/864544 [rt.cpan.org #122068] Fix issue #122068.
  DEBPKG​:fixes/test-builder-reset - https://bugs.debian.org/865894 Reset inside subtest maintains parent
  DEBPKG​:debian/hppa_opmini_optimize_workaround - https://bugs.debian.org/869122 Lower the optimization level of opmini.c on hppa
  DEBPKG​:debian/sh4_op_optimize_workaround - https://bugs.debian.org/869373 Also lower the optimization level of op.c and opmini.c on sh4
  DEBPKG​:fixes/json-pp-example - [rt.cpan.org #92793] https://bugs.debian.org/871837 fix RT-92793​: bug in SYNOPSIS
  DEBPKG​:debian/perldoc-pager - https://bugs.debian.org/870340 [rt.cpan.org #120229] Fix perldoc terminal escapes when sensible-pager is less
  DEBPKG​:debian/prune_libs - https://bugs.debian.org/128355 Prune the list of libraries wanted to what we actually need.
  DEBPKG​:debian/configure-regen - https://bugs.debian.org/762638 Regenerate Configure et al. after probe unit changes
  DEBPKG​:fixes/rename-filexp.U-phase1 - regen-configure​: rename filexp.U to filexp_path.U, phase 1
  DEBPKG​:fixes/rename-filexp.U-phase2 - regen-configure​: rename filexp.U to filexp_path.U, phase 2
  DEBPKG​:fixes/packaging_test_skips - Skip various tests if PERL_BUILD_PACKAGING is set


@​INC for perl 5.26.1​:
  /etc/perl
  /usr/local/lib/x86_64-linux-gnu/perl/5.26.1
  /usr/local/share/perl/5.26.1
  /usr/lib/x86_64-linux-gnu/perl5/5.26
  /usr/share/perl5
  /usr/lib/x86_64-linux-gnu/perl/5.26
  /usr/share/perl/5.26
  /usr/local/lib/site_perl
  /usr/lib/x86_64-linux-gnu/perl-base


Environment for perl 5.26.1​:
  HOME=/home/calestyo
  LANG=en_DE.UTF-8
  LANGUAGE (unset)
  LD_LIBRARY_PATH (unset)
  LOGDIR (unset)
  PATH=/usr/local/bin​:/usr/bin​:/bin​:/usr/local/games​:/usr/games
  PERL_BADLANG (unset)
  SHELL=/bin/bash

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Dec 8, 2017

From @iabyn

On Wed, Dec 06, 2017 at 06​:02​:52PM -0800, via RT wrote​:

https://perldoc.perl.org/perldata.html says​:

LISTs do automatic interpolation of sublists. That is, when a LIST is evaluated,
each element of the list is evaluated in list context, and the resulting list
value is interpolated into LIST just as if each individual element were a member of LIST.

This seems to be wrong, in the sense, that the list
itself doesn't mandate its elements to be evaluated
in list context.

It does by definition​:

When doing $b=(1, 2, @​a); the list is evaluated in scalar context

No, in scalar context, there isn't a list; instead there is merely
a sequence of comma operators (which return their RH argument), with
parentheses added for the purpose of precedence.

--
Hofstadter's Law​: It always takes longer than you expect, even when you
take into account Hofstadter's Law.

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Dec 8, 2017

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

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Dec 8, 2017

From cm.perl@abtela.com

Le 08/12/2017 à 10​:12, Dave Mitchell a écrit :

On Wed, Dec 06, 2017 at 06​:02​:52PM -0800, via RT wrote​:

https://perldoc.perl.org/perldata.html says​:

LISTs do automatic interpolation of sublists. That is, when a LIST is evaluated,
each element of the list is evaluated in list context, and the resulting list
value is interpolated into LIST just as if each individual element were a member of LIST.

This seems to be wrong, in the sense, that the list
itself doesn't mandate its elements to be evaluated
in list context.

It does by definition​:

When doing $b=(1, 2, @​a); the list is evaluated in scalar context

No, in scalar context, there isn't a list; instead there is merely
a sequence of comma operators (which return their RH argument), with
parentheses added for the purpose of precedence.

FWIW I find the sentence above clearer than the current wording in perldata

  677 =head2 List value constructors
  678 X<list>
  679
  680 List values are denoted by separating individual values by commas
  681 (and enclosing the list in parentheses where precedence requires it)​:
  682
  683 (LIST)
  684
  685 In a context not requiring a list value, the value of what appears
  686 to be a list literal is simply the value of the final element, as
  687 with the C comma operator. For example,
  688
  689 @​foo = ('cc', '-E', $bar);
  690
  691 assigns the entire list value to array @​foo, but
  692
  693 $foo = ('cc', '-E', $bar);
  694
  695 assigns the value of variable $bar to the scalar variable $foo.

YMMV. From experience this is a significant hurdle for beginners.

@​array = (...)​: # OK
%hash = (...); # OK
$scalar = (...); # Possibly not what was intended,
  # consider $scalar = [...] instead ?

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Dec 14, 2017

From calestyo@scientia.net

On Fri, 2017-12-08 at 01​:12 -0800, Dave Mitchell via RT wrote​:

It does by definition​:
No, in scalar context, there isn't a list; instead there is merely
a sequence of comma operators (which return their RH argument), with
parentheses added for the purpose of precedence.

That's at least not how the text in perldata or perlop does it make
look like.
It's rather written as it's still a list (and it even says, that all
elements are actually evaluated), just that it doesn't "return" the
whole list, but rather only it's last element.

- (x, y, z) seems to be clearly what is defined to be a list, every
  beginner will consider it as such, regardless of its context
- other text places say that in both contexts (scalar/list) all
  elements are evaluated, just that in scalar context everything but
  the last is discarded

So conceptually it still seems to be a list, and then the text that I
was mentioning is still ambiguous...
People would think (by operator precedence)​:
1. evaluation of the x, y, z (i.e. the list)
  and the text says always in list context
2. for list context = return all evaluated elements as a list
  for scalar context = return only the last element (which would
  however, by the documentation, be evaluated in list context, which
  it is not.

Cheers,
Chris.

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Dec 14, 2017

From @Grinnz

On Sat, Dec 9, 2017 at 11​:11 PM, Christoph Anton Mitterer <
calestyo@​scientia.net> wrote​:

On Fri, 2017-12-08 at 01​:12 -0800, Dave Mitchell via RT wrote​:

It does by definition​:
No, in scalar context, there isn't a list; instead there is merely
a sequence of comma operators (which return their RH argument), with
parentheses added for the purpose of precedence.

That's at least not how the text in perldata or perlop does it make
look like.
It's rather written as it's still a list (and it even says, that all
elements are actually evaluated), just that it doesn't "return" the
whole list, but rather only it's last element.

- (x, y, z) seems to be clearly what is defined to be a list, every
beginner will consider it as such, regardless of its context
- other text places say that in both contexts (scalar/list) all
elements are evaluated, just that in scalar context everything but
the last is discarded

So conceptually it still seems to be a list, and then the text that I
was mentioning is still ambiguous...
People would think (by operator precedence)​:
1. evaluation of the x, y, z (i.e. the list)
and the text says always in list context
2. for list context = return all evaluated elements as a list
for scalar context = return only the last element (which would
however, by the documentation, be evaluated in list context, which
it is not.

The definition of 'list' in perl is more precise than that. In scalar
context x, y, z (with or without parentheses) is not a list, it is instead
a sequence of expressions like in C. They are evaluated in order and then
the last one is returned.

-Dan

@khwilliamson
Copy link
Contributor

@khwilliamson khwilliamson commented Apr 19, 2022

Is this closable?

@khwilliamson khwilliamson added the Closable? label Apr 19, 2022
@demerphq
Copy link
Contributor

@demerphq demerphq commented Apr 19, 2022

I think the OP has a point that this is a painful point for beginners and we could do better at documenting it, but there is no proposed language change, and the wording of the ticket isn't really correct. I think we could close it and create a new ticket that is more clear about what needs to be done.

@demerphq
Copy link
Contributor

@demerphq demerphq commented Apr 19, 2022

BTW, this language in perldata:

If you evaluate an array in scalar context, it returns the length
of the array.  (Note that this is not true of lists, which return
the last value, like the C comma operator, nor of built-in functions,
which return whatever they feel like returning.)  The following is
always true:
X<array, length>

seems to contradict what @iabyn and @Grinnz say in this ticket. I am not arguing with their interpretation which I agree with in principal, but it seems a slippery ground. Most people would say:

my $x= (1,2,3,4,5);

is a list in scalar context similar to what the docs I quoted above imply. However @iabyn and @Grinnz are arguing its not a list at all. If its not a list then what is it to be called? "comma operator with parens for precedence" doesn't exactly roll off the tongue.

@Grinnz
Copy link
Contributor

@Grinnz Grinnz commented Apr 19, 2022

I suppose you could call it syntactically/visually a list, but functionally no list is formed by the comma operator in that context. As a similar example my $x = 1..5; is neither syntactically nor functionally a list because that becomes the flipflop operator. The danger of referring to that construct as a list is extending assumptions about other list-like things which all behave differently (most commonly arrays).

@demerphq
Copy link
Contributor

@demerphq demerphq commented Apr 19, 2022

BTW, right next to the text that the OP quotes it basically says the same thing @Grinnz and @iabyn said. I think we can close this ticket. What do you think @Grinnz ?

@Grinnz
Copy link
Contributor

@Grinnz Grinnz commented Apr 19, 2022

If you're referring to In a context not requiring a list value, the value of what appears to be a list literal is simply the value of the final element, as with the C comma operator. - if anything it could be clearer which operators it's talking about, it only calls out arrays specifically after but there are some other exceptional cases. But really this section is about lists, so I don't think it's necessary for it to go too in depth about scalar context.

@demerphq
Copy link
Contributor

@demerphq demerphq commented Apr 19, 2022

@Grinnz
Copy link
Contributor

@Grinnz Grinnz commented Apr 19, 2022

Yes, I think it is sufficiently covered though improvements are always welcome

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Closable?
Projects
None yet
Development

No branches or pull requests

5 participants