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

"splice" and "shift" aren't strictly equivalent #17104

Open
p5pRT opened this issue Jul 23, 2019 · 7 comments
Open

"splice" and "shift" aren't strictly equivalent #17104

p5pRT opened this issue Jul 23, 2019 · 7 comments

Comments

@p5pRT
Copy link

p5pRT commented Jul 23, 2019

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

Searchable as RT134304$

@p5pRT
Copy link
Author

p5pRT commented Jul 23, 2019

From choroba@matfyz.cz

Created by choroba@matfyz.cz

"perldoc -f splice" says​:

  The following equivalences hold (assuming "$#a >= $i" )

  push(@​a,$x,$y) splice(@​a,@​a,0,$x,$y)
  pop(@​a) splice(@​a,-1)
  shift(@​a) splice(@​a,0,1)

They are equivalent in the sense of what happens to array @​a. They even return
the same thing in scalar context. But in list context, their return value is
different if the array is empty​:

  #!/usr/bin/perl
  use warnings;
  use strict;

  use Test​::More tests => 4;

  my @​y = my @​x = qw( a b );

  is_deeply [scalar splice @​x, 0, 1], [scalar shift @​y];
  is_deeply [splice @​x, 0, 1], [shift @​y];

  @​x = @​y = ();

  is_deeply [scalar splice @​x, 0, 1], [scalar shift @​y];
  is_deeply [splice @​x, 0, 1], [shift @​y]; # BOOM!

This behaviour is documented under "splice" and "shift", but the word
"equivalences" might be a bit misleading. Maybe we should assume "@​a > 0" as
well, or document that the equivalences are valid except for the return value.

Ch.

Perl Info

Flags:
     category=docs
     severity=low

Site configuration information for perl 5.31.1:

Configured by choroba at Tue Jun 18 09:46:42 CEST 2019.

Summary of my perl5 (revision 5 version 31 subversion 1) configuration:
   Commit id: fa068f6da2218ae85bae1e26ee7591c15276555f
   Platform:
     osname=linux
     osvers=4.4.179-99-default
     archname=x86_64-linux-thread-multi
     uname='linux lenonovo 4.4.179-99-default #1 smp tue may 14 18:07:16 utc 2019 (c775d39) x86_64 x86_64 x86_64 gnulinux '
     config_args='-rdes -Dusethreads -Dprefix=~/blead -Dusedevel'
     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='cc'
     ccflags ='-D_REENTRANT -D_GNU_SOURCE -fwrapv -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2'
     optimize='-O2'
     cppflags='-D_REENTRANT -D_GNU_SOURCE -fwrapv -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include'
     ccversion=''
     gccversion='4.8.5'
     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='cc'
     ldflags =' -fstack-protector -L/usr/local/lib'
     libpth=/usr/local/lib /usr/lib64/gcc/x86_64-suse-linux/4.8/include-fixed /usr/lib64/gcc/x86_64-suse-linux/4.8/../../../../x86_64-suse-linux/lib /usr/lib /lib/../lib64 /usr/lib/../lib64 /lib /lib64 /usr/lib64 /usr/local/lib64
     libs=-lpthread -lnsl -lgdbm -ldl -lm -lcrypt -lutil -lc -lgdbm_compat
     perllibs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc
     libc=libc-2.22.so
     so=so
     useshrplib=false
     libperl=libperl.a
     gnulibc_version='2.22'
   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'



@INC for perl 5.31.1:
     /home/choroba/blead/lib/perl5/site_perl/5.31.1/x86_64-linux-thread-multi
     /home/choroba/blead/lib/perl5/site_perl/5.31.1
     /home/choroba/blead/lib/perl5/5.31.1/x86_64-linux-thread-multi
     /home/choroba/blead/lib/perl5/5.31.1


Environment for perl 5.31.1:
     HOME=/home/choroba
     LANG=en_US.utf8
     LANGUAGE (unset)
     LC_CTYPE=en_US.UTF-8
     LD_LIBRARY_PATH (unset)
     LOGDIR (unset)
     PATH=/home/choroba/bin:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/home/choroba/perl5/bin:/home/choroba/opensource/worktime/bin:.
     PERL_BADLANG (unset)
     SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Oct 6, 2019

From @jkeenan

On Tue, 23 Jul 2019 15​:53​:47 GMT, choroba@​matfyz.cz wrote​:

This is a bug report for perl from choroba@​matfyz.cz,
generated with the help of perlbug 1.41 running under perl 5.31.1.

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

"perldoc -f splice" says​:

The following equivalences hold (assuming "$#a >= $i" )

push(@​a,$x,$y) splice(@​a,@​a,0,$x,$y)
pop(@​a) splice(@​a,-1)
shift(@​a) splice(@​a,0,1)

They are equivalent in the sense of what happens to array @​a. They
even return
the same thing in scalar context. But in list context, their return
value is
different if the array is empty​:

#!/usr/bin/perl
use warnings;
use strict;

use Test​::More tests => 4;

my @​y = my @​x = qw( a b );

is_deeply [scalar splice @​x, 0, 1], [scalar shift @​y];
is_deeply [splice @​x, 0, 1], [shift @​y];

@​x = @​y = ();

is_deeply [scalar splice @​x, 0, 1], [scalar shift @​y];
is_deeply [splice @​x, 0, 1], [shift @​y]; # BOOM!

This behaviour is documented under "splice" and "shift", but the word
"equivalences" might be a bit misleading. Maybe we should assume "@​a >
0" as
well, or document that the equivalences are valid except for the
return value.

I concur that this discussion of "equivalences" is highly misleading. The fact that 'splice' has 3 different cases for return value means that those return values are not at all comparable to those of the other 4 built-in functions. When the original list is empty, calls to 'pop' need to anticipate an exception.

See the 4 scripts attached.

In principle, we could modify the documentation to say that the original list must (sometimes) be non-empty and that the "equivalence" applies only to the result list and not to the return values -- but that's so complicated that I think we're better off just removing all the discussion of "equivalence".

Thank you very much.

--
James E Keenan (jkeenan@​cpan.org)

@p5pRT
Copy link
Author

p5pRT commented Oct 6, 2019

From @jkeenan

134304-pop-vs-slice.pl

@p5pRT
Copy link
Author

p5pRT commented Oct 6, 2019

From @jkeenan

134304-push-vs-slice.pl

@p5pRT
Copy link
Author

p5pRT commented Oct 6, 2019

From @jkeenan

134304-shift-vs-slice.pl

@p5pRT
Copy link
Author

p5pRT commented Oct 6, 2019

@p5pRT
Copy link
Author

p5pRT commented Oct 6, 2019

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

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

No branches or pull requests

2 participants