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

keys(@array) gives too many indices #11328

Closed
p5pRT opened this issue May 10, 2011 · 33 comments
Closed

keys(@array) gives too many indices #11328

p5pRT opened this issue May 10, 2011 · 33 comments

Comments

@p5pRT
Copy link

@p5pRT p5pRT commented May 10, 2011

Migrated from rt.perl.org#90240 (status was 'rejected')

Searchable as RT90240$

@p5pRT
Copy link
Author

@p5pRT p5pRT commented May 10, 2011

From @sciurius

Created by @sciurius

  my @​a = qw( zero one two three );
  $a[7] = "seven";
  say "number of elements = ", scalar(@​a);
  say "keys = ", join(" ", keys(@​a));
  say "elt 6 exists​: ", exists($a[6]) ? "yes" : "no";

returns​:

  number of elements = 8
  keys = 0 1 2 3 4 5 6 7
  elt 6 exists​: no

For the function keys(@​array) to be anything more useful than just an
alternative way to write 0..$#array, it should leave out indices for
nonexisting elements.

The same applies to values(@​array), which returns a series of
undefined values where elements are nonexisting.

Perl Info

Flags:
    category=core
    severity=medium

Site configuration information for perl 5.14.0:

Configured by jv at Wed May  4 19:54:10 CEST 2011.

Summary of my perl5 (revision 5 version 14 subversion 0) configuration:
   
  Platform:
    osname=linux, osvers=2.6.35.12-90.fc14.i686.pae, archname=i386-linux-thread-multi
    uname='linux phoenix.squirrel.nl 2.6.35.12-90.fc14.i686.pae #1 smp fri apr 22 16:08:03 utc 2011 i686 i686 i386 gnulinux '
    config_args='-des -Darchname=i386-linux -Dprefix=/opt/perl-5.14.0-RC2 -Dcf_email=jvromans@squirrel.nl -Dperladmin=jvromans@squirrel.nl -Uversiononly -Dusethreads -Duseithreads -Dusedevel'
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=define, usemultiplicity=define
    useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
    use64bitint=undef, use64bitall=undef, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-O2',
    cppflags='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include'
    ccversion='', gccversion='4.5.1 20100924 (Red Hat 4.5.1-4)', 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='cc', ldflags =' -fstack-protector -L/usr/local/lib'
    libpth=/usr/local/lib /lib /usr/lib
    libs=-lnsl -ldl -lm -lcrypt -lutil -lpthread -lc
    perllibs=-lnsl -ldl -lm -lcrypt -lutil -lpthread -lc
    libc=/lib/libc-2.13.so, so=so, useshrplib=false, libperl=libperl.a
    gnulibc_version='2.13'
  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:
    RC2


@INC for perl 5.14.0:
    /opt/perl-5.14.0-RC2/lib/site_perl/5.14.0/i386-linux-thread-multi
    /opt/perl-5.14.0-RC2/lib/site_perl/5.14.0
    /opt/perl-5.14.0-RC2/lib/5.14.0/i386-linux-thread-multi
    /opt/perl-5.14.0-RC2/lib/5.14.0
    .


Environment for perl 5.14.0:
    HOME=/home/jv
    LANG=en_US.utf-8
    LANGUAGE (unset)
    LC_PAPER=nl_NL
    LC_TIME=en_GB
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=.:/home/jv/bin:/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin
    PERL5LIB=
    PERL_BADLANG (unset)
    SHELL=/bin/tcsh

-- 
----------------------------------------------------------------------------
Johan Vromans                                           jvromans@squirrel.nl
Squirrel Consultancy                                  Exloo, the Netherlands
http://www.squirrel.nl                              http://johan.vromans.org
PGP Key 1024D/1298C2B4                  http://johan.vromans.org/pgpkey.html
----------------------- "Arms are made for hugging" ------------------------

@p5pRT
Copy link
Author

@p5pRT p5pRT commented May 10, 2011

From @xdg

On Tue, May 10, 2011 at 7​:46 AM, Johan Vromans
<perlbug-followup@​perl.org> wrote​:

For the function keys(@​array) to be anything more useful than just an
alternative way to write 0..$#array, it should leave out indices for
nonexisting elements.

The same applies to values(@​array), which returns a series of
undefined values where elements are nonexisting.

Dear Johan,

The concept of "exists" (and "delete") on arrays has been deprecated
after a lengthy discussion on this behavior.

With all due respect, I recommend closing this ticket as already
resolved with that prior deprecation decision.

Regards,
David

@p5pRT
Copy link
Author

@p5pRT p5pRT commented May 10, 2011

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

@p5pRT
Copy link
Author

@p5pRT p5pRT commented May 10, 2011

From tchrist@perl.com

Johan Vromans (via RT) <perlbug-followup@​perl.org> wrote
  on Tue, 10 May 2011 04​:46​:59 PDT​:

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

my @​a = qw( zero one two three );
$a[7] = "seven";
say "number of elements = ", scalar(@​a);
say "keys = ", join(" ", keys(@​a));
say "elt 6 exists​: ", exists($a[6]) ? "yes" : "no";

returns​:

number of elements = 8
keys = 0 1 2 3 4 5 6 7
elt 6 exists​: no

For the function keys(@​array) to be anything more useful than just an
alternative way to write 0..$#array, it should leave out indices for
nonexisting elements.

The same applies to values(@​array), which returns a series of
undefined values where elements are nonexisting.

I remember having gone over this some months ago. I don't have
the thread id handy though.

I note that the blead perlfunc contains

  delete() may also be used on arrays and array slices, but its
  behavior is less straightforward. Although exists() will
  return false for deleted entries, deleting array elements
  never changes indices of existing values; use shift() or
  splice() for that. However, if all deleted elements fall at
  the end of an array, the array's size shrinks to the position
  of the highest element that still tests true for exists(), or
  to 0 if none do.

  B<Be aware> that calling delete on array values is deprecated
  and likely to be removed in a future version of Perl.

--tom

@p5pRT
Copy link
Author

@p5pRT p5pRT commented May 10, 2011

From @sciurius

[Quoting David Golden via RT, on May 10 2011, 04​:59, in "Re​: [perl #90240] ke"]

The concept of "exists" (and "delete") on arrays has been deprecated
after a lengthy discussion on this behavior.

Could it be that the corresponding deprecation warning is missing?

  % blead -wlE 'my @​a = qw(1 2); say exists $a[7]'
  <no warning>

-- Johan

@p5pRT
Copy link
Author

@p5pRT p5pRT commented May 10, 2011

From @sciurius

[Quoting tchrist1 via RT, on May 10 2011, 05​:02, in "Re​: [perl #90240] ke"]

delete\(\) may also be used on arrays and array slices\, but its
behavior is less straightforward\.  Although exists\(\) will
return false for deleted entries\, deleting array elements
never changes indices of existing values; use shift\(\) or
splice\(\) for that\.  However\, if all deleted elements fall at
the end of an array\, the array's size shrinks to the position
of the highest element that still tests true for exists\(\)\, or
to 0 if none do\.

B\<Be aware> that calling delete on array values is deprecated
and likely to be removed in a future version of Perl\.

Noe of this covers the case that I mentioned​:

  my @​a = qw( zero one two three );
  $a[7] = "seven";
  say "keys = ", join(" ", keys(@​a));

No 'delete'. No 'exists'. Just an assignment and 'keys'.

Two conclusions​:

- Assigning a value to an array element that does not currently exist
  will add the element and all intermediate elements to the array.
  Intermediate elements will have undefined values.

- keys(@​a) is just an alternative and often more elegant way to write
  0..$#a.

-- Johan

@p5pRT
Copy link
Author

@p5pRT p5pRT commented May 10, 2011

From @xdg

On Tue, May 10, 2011 at 10​:31 AM, Johan Vromans <jvromans@​squirrel.nl> wrote​:

 - keys(@​a) is just an alternative and often more elegant way to write
  0..$#a.

The underlying interpreter code for keys, values and each is the same.
So, rather, think of this as being able to call each on arrays​:

  while ( my ($i,$v) = each @​array ) { ... }

The code to make that work gives us keys/values on arrays "for free".

FWIW, I believe that each on arrays returns elements in order, though
I don't think that's well documented (if at all).

-- David

@p5pRT
Copy link
Author

@p5pRT p5pRT commented May 10, 2011

From tchrist@perl.com

David Golden <xdaveg@​gmail.com> wrote
  on Tue, 10 May 2011 10​:49​:15 EDT​:

FWIW, I believe that each on arrays returns elements in order, though
I don't think that's well documented (if at all).

Arguably, one might be able to read that in what the second sentence
below does *not* say; that is, it says hash entries show up scrambled,
but omits mention of arrays.

  =item each HASH
  X<each> X<hash, iterator>

  =item each ARRAY
  X<array, iterator>

  =item each EXPR

  When called in list context, returns a 2-element list consisting of the key
  and value for the next element of a hash, or the index and value for the
  next element of an array, so that you can iterate over it. When called in
  scalar context, returns only the key (not the value) in a hash, or the index
  in an array.

  Hash entries are returned in an apparently random order. The actual random
  order is subject to change in future versions of Perl, but it is
  guaranteed to be in the same order as either the C<keys> or C<values>
  function would produce on the same (unmodified) hash. Since Perl
  5.8.2 the ordering can be different even between different runs of Perl
  for security reasons (see L<perlsec/"Algorithmic Complexity Attacks">).

And yes, it should be more explicit.

--tom

@p5pRT
Copy link
Author

@p5pRT p5pRT commented May 10, 2011

@ikegami - Status changed from 'open' to 'rejected'

@p5pRT
Copy link
Author

@p5pRT p5pRT commented May 10, 2011

From @ikegami

On Tue, May 10, 2011 at 10​:31 AM, Johan Vromans <jvromans@​squirrel.nl>wrote​:

[Quoting tchrist1 via RT, on May 10 2011, 05​:02, in "Re​: [perl #90240] ke"]

B\<Be aware> that calling delete on array values is deprecated
and likely to be removed in a future version of Perl\.

None of this covers the case that I mentioned​:

It goes to show that the behaviour you expect/desire is slated for removal
from Perl where it exists elsewhere in the code, and is thus wholly
inappropriate here.

number of elements = 8

  keys = 0 1 2 3 4 5 6 7

C<keys> returns the index of every element of a hash, so C<keys> should
return the index of every element of an array. You demonstrate that this is
what it does.

- Eric

@p5pRT
Copy link
Author

@p5pRT p5pRT commented May 11, 2011

From andrew@cleverdomain.org

On Tuesday, May 10, 2011 11​:41​:05 AM Eric Brine wrote​:

On Tue, May 10, 2011 at 10​:31 AM, Johan Vromans <jvromans@​squirrel.nl>wrote​:

[Quoting tchrist1 via RT, on May 10 2011, 05​:02, in "Re​: [perl #90240]
ke"]

B\<Be aware> that calling delete on array values is deprecated
and likely to be removed in a future version of Perl\.

None of this covers the case that I mentioned​:
It goes to show that the behaviour you expect/desire is slated for removal
from Perl where it exists elsewhere in the code, and is thus wholly
inappropriate here.

number of elements = 8

keys = 0 1 2 3 4 5 6 7

C<keys> returns the index of every element of a hash, so C<keys> should
return the index of every element of an array. You demonstrate that this is
what it does.

- Eric

C<keys> returns the indices of elements in a hash that have been assigned
C<undef> but not ones that have never been assigned, so C<keys> should return
the indices of elements in an array that have been assigned C<undef> but not
ones that have never been assigned.

Implementing keys/values/each on arrays has really just been a colossally
stupid waste of time and effort with the current behavior -- "values @​array"
is utterly useless, and "keys @​array" and "each @​array" are both useless
except to look *arguably* slightly prettier than the established idioms.

If, however, keys/values/each on arrays respected "exists", not only would
they gain a genuine reason for being; they would also make working with sparse
arrays actually useful — sure, nonexistent entries aren't *free*, but a null
pointer is still a lot smaller than a pointer plus an SV, and arrays have fast
indexing and support for push/pop/shift/unshift. Having keys/values/each on
arrays respect existence potentially *saves* delete/exist on arrays from
needing deprecation, by exposing them in a way that makes them part of a
useful feature instead of just esoteric internals weirdness.

@p5pRT
Copy link
Author

@p5pRT p5pRT commented May 11, 2011

From @ap

* David Golden <xdaveg@​gmail.com> [2011-05-10 14​:00]​:

With all due respect, I recommend closing this ticket as
already resolved with that prior deprecation decision.

I agree.

* Tom Christiansen <tchrist@​perl.com> [2011-05-10 14​:05]​:

I remember having gone over this some months ago. I don't have
the thread id handy though.

Here you are​:
http​://www.nntp.perl.org/group/perl.perl5.porters/;msgid=22846.1262929665@​chthon
http​://www.nntp.perl.org/group/perl.perl5.porters/;msgid=rt-3.6.HEAD-1505-1263414334-366.72064-75-0@​perl.org

* Johan Vromans <perlbug-followup@​perl.org> [2011-05-10 13​:50]​:

For the function keys(@​array) to be anything more useful than
just an alternative way to write 0..$#array, it should leave
out indices for nonexisting elements.

The same applies to values(@​array), which returns a series of
undefined values where elements are nonexisting.

* Andrew Rodland <andrew@​cleverdomain.org> [2011-05-11 04​:20]​:

C<keys> returns the indices of elements in a hash that have
been assigned C<undef> but not ones that have never been
assigned, so C<keys> should return the indices of elements in
an array that have been assigned C<undef> but not ones that
have never been assigned.

Implementing keys/values/each on arrays has really just been
a colossally stupid waste of time and effort with the current
behavior -- "values @​array" is utterly useless, and "keys
@​array" and "each @​array" are both useless except to look
*arguably* slightly prettier than the established idioms.

If, however, keys/values/each on arrays respected "exists", not
only would they gain a genuine reason for being; they would
also make working with sparse arrays actually useful — sure,
nonexistent entries aren't *free*, but a null pointer is still
a lot smaller than a pointer plus an SV, and arrays have fast
indexing and support for push/pop/shift/unshift. Having
keys/values/each on arrays respect existence potentially
*saves* delete/exist on arrays from needing deprecation, by
exposing them in a way that makes them part of a useful feature
instead of just esoteric internals weirdness.

Please read the aforelinked threads. This has already been argued
out at length.

(That reasoning should maybe be added to the docs. This issue is
sure to attract other people down the line whom think it obvious
that the other way is right, just like everyone does at first,
and What Were They Thinking.)

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

@p5pRT
Copy link
Author

@p5pRT p5pRT commented May 11, 2011

From @ikegami

On Tue, May 10, 2011 at 9​:57 PM, Andrew Rodland <andrew@​cleverdomain.org>wrote​:

On Tuesday, May 10, 2011 11​:41​:05 AM Eric Brine wrote​:

C<keys> returns the index of every element of a hash, so C<keys> should
return the index of every element of an array. You demonstrate that this
is
what it does.

- Eric

C<keys> returns the indices of elements in a hash that have been assigned
C<undef> but not ones that have never been assigned, so C<keys> should
return
the indices of elements in an array that have been assigned C<undef> but
not
ones that have never been assigned.

Not true.

perl -E"\$h{k}; say for keys %h"
k

Assignment doesn't matter, only existence. Since C<<my @​a; $a[7]="seven";>>
creates an array of 8 elements, they 8 elements must exist.

@p5pRT
Copy link
Author

@p5pRT p5pRT commented May 11, 2011

From @sciurius

[Quoting A. Pagaltzis via RT, on May 10 2011, 21​:24, in "Re​: [perl #90240] ke"]

* Tom Christiansen <tchrist@​perl.com> [2011-05-10 14​:05]​:

I remember having gone over this some months ago. I don't have
the thread id handy though.

Here you are​:
http​://www.nntp.perl.org/group/perl.perl5.porters/;msgid=22846.1262929665@​chthon
http​://www.nntp.perl.org/group/perl.perl5.porters/;msgid=rt-3.6.HEAD-1505-1263414334-366.72064-75-0@​perl.org

Thanks.

* David Golden <xdaveg@​gmail.com> [2011-05-10 14​:00]​:

With all due respect, I recommend closing this ticket as
already resolved with that prior deprecation decision.

I recommend leaving this ticket open at least until the deprecation
warning is in place.

Currently, there's only a line of text in perldelta and perlfun
that mentions the deprecation of delete/exists on arrays.
Unfortunately, people generally do not scan the docs to find out if
something happens to have been deprecated.

-- Johan

@p5pRT
Copy link
Author

@p5pRT p5pRT commented May 11, 2011

From vadim.konovalov@alcatel-lucent.com

From​: jvromans@​squirrel.nl

Currently, there's only a line of text in perldelta and perlfun
that mentions the deprecation of delete/exists on arrays.
Unfortunately, people generally do not scan the docs to find out if
something happens to have been deprecated.

Maybe list deprecations in a separate file, so to made looking for them more easily?
If "perldoc perldeprecated" would list all currently deprecated features
that would be 1) easy to find 2) generally useful so to be warned early.

Vadim.

@p5pRT
Copy link
Author

@p5pRT p5pRT commented May 11, 2011

From @sciurius

"Konovalov, Vadim (Vadim)** CTR **" <vadim.konovalov@​alcatel-lucent.com>
writes​:

Maybe list deprecations in a separate file, so to made looking for
them more easily?

Do you really think programmers will actively start looking for
deprecations?

I don't.

-- Johan

@p5pRT
Copy link
Author

@p5pRT p5pRT commented May 11, 2011

From vadim.konovalov@alcatel-lucent.com

From​: Johan Vromans
"Konovalov, Vadim (Vadim)** CTR **" writes​:

Maybe list deprecations in a separate file, so to made looking for
them more easily?

Do you really think programmers will actively start looking for
deprecations?

I don't.

I do think that if they will be collected together - I will browse these even more
often than I browse perldeltaXXXX.pod

But my approach is not universal of course :)

I even think deprecations deserve command line options​:

perl -V​:deprecations
perl -V​:deprecation-1
perl -V​:deprecation-2
....

Vadim.

@p5pRT
Copy link
Author

@p5pRT p5pRT commented May 11, 2011

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

@p5pRT
Copy link
Author

@p5pRT p5pRT commented May 11, 2011

From @obra

On Wed 11.May'11 at 9​:00​:19 +0200, Johan Vromans wrote​:

[Quoting A. Pagaltzis via RT, on May 10 2011, 21​:24, in "Re​: [perl #90240] ke"]

* Tom Christiansen <tchrist@​perl.com> [2011-05-10 14​:05]​:

I remember having gone over this some months ago. I don't have
the thread id handy though.

Here you are​:
http​://www.nntp.perl.org/group/perl.perl5.porters/;msgid=22846.1262929665@​chthon
http​://www.nntp.perl.org/group/perl.perl5.porters/;msgid=rt-3.6.HEAD-1505-1263414334-366.72064-75-0@​perl.org

Thanks.

* David Golden <xdaveg@​gmail.com> [2011-05-10 14​:00]​:

With all due respect, I recommend closing this ticket as
already resolved with that prior deprecation decision.

I recommend leaving this ticket open at least until the deprecation
warning is in place.

Currently, there's only a line of text in perldelta and perlfun
that mentions the deprecation of delete/exists on arrays.
Unfortunately, people generally do not scan the docs to find out if
something happens to have been deprecated.

My policy​: If we fail to implement a deprecation warning for something
we're capable of warning for in version X, it can't go away in the
stable release after X. If we fail to warn for it, it isn't properly
deprecated.

-Jesse

@p5pRT
Copy link
Author

@p5pRT p5pRT commented May 11, 2011

From @sciurius

Jesse Vincent <jesse@​fsck.com> writes​:

My policy​: If we fail to implement a deprecation warning for something
we're capable of warning for in version X, it can't go away in the
stable release after X. If we fail to warn for it, it isn't properly
deprecated.

Thanks Jesse, for this clear statement.

To get back to the originating bug report, we now can draw the
conclusion that array delete/exists is *NOT* deprecated in 5.14 and
hence the associated bug reports cannot yet be closed.

-- Johan

@p5pRT
Copy link
Author

@p5pRT p5pRT commented May 11, 2011

From @ikegami

On Wed, May 11, 2011 at 5​:39 PM, Johan Vromans <jvromans@​squirrel.nl> wrote​:

Jesse Vincent <jesse@​fsck.com> writes​:

My policy​: If we fail to implement a deprecation warning for something
we're capable of warning for in version X, it can't go away in the
stable release after X. If we fail to warn for it, it isn't properly
deprecated.

Thanks Jesse, for this clear statement.

To get back to the originating bug report, we now can draw the
conclusion that array delete/exists is *NOT* deprecated in 5.14 and
hence the associated bug reports cannot yet be closed.

The bug report was about keys() not returning the right thing.

Having delete/exists return a deprecation warning is a completely different
issue. I'll create a ticket with patch tonight.

@p5pRT
Copy link
Author

@p5pRT p5pRT commented May 12, 2011

From @xdg

On Wed, May 11, 2011 at 5​:39 PM, Johan Vromans <jvromans@​squirrel.nl> wrote​:

Jesse Vincent <jesse@​fsck.com> writes​:

My policy​: If we fail to implement a deprecation warning for something
we're capable of warning for in version X, it can't go away in the
stable release after X.  If we fail to warn for it, it isn't properly
deprecated.

Thanks Jesse, for this clear statement.

To get back to the originating bug report, we now can draw the
conclusion that array delete/exists is *NOT* deprecated in 5.14 and
hence the associated bug reports cannot yet be closed.

I think that's an incorrect read.

A deprecation *decision* may be *implemented* improperly (without
warnings), but that doesn't change the decision. What Jesse said is
that improperly deprecated features will not actually be removed until
at least one major version after the deprecation is proper (i.e.
warns).

-- David

@p5pRT
Copy link
Author

@p5pRT p5pRT commented May 15, 2011

From @cpansprout

On Tue May 10 21​:24​:21 2011, aristotle wrote​:

* David Golden <xdaveg@​gmail.com> [2011-05-10 14​:00]​:

With all due respect, I recommend closing this ticket as
already resolved with that prior deprecation decision.

I agree.

* Tom Christiansen <tchrist@​perl.com> [2011-05-10 14​:05]​:

I remember having gone over this some months ago. I don't have
the thread id handy though.

Here you are​:

http​://www.nntp.perl.org/group/perl.perl5.porters/;msgid=22846.1262929665@​chthon

http​://www.nntp.perl.org/group/perl.perl5.porters/;msgid=rt-3.6.HEAD-
1505-1263414334-366.72064-75-0@​perl.org

* Johan Vromans <perlbug-followup@​perl.org> [2011-05-10 13​:50]​:

For the function keys(@​array) to be anything more useful than
just an alternative way to write 0..$#array, it should leave
out indices for nonexisting elements.

The same applies to values(@​array), which returns a series of
undefined values where elements are nonexisting.

* Andrew Rodland <andrew@​cleverdomain.org> [2011-05-11 04​:20]​:

C<keys> returns the indices of elements in a hash that have
been assigned C<undef> but not ones that have never been
assigned, so C<keys> should return the indices of elements in
an array that have been assigned C<undef> but not ones that
have never been assigned.

Implementing keys/values/each on arrays has really just been
a colossally stupid waste of time and effort with the current
behavior -- "values @​array" is utterly useless, and "keys
@​array" and "each @​array" are both useless except to look
*arguably* slightly prettier than the established idioms.

If, however, keys/values/each on arrays respected "exists", not
only would they gain a genuine reason for being; they would
also make working with sparse arrays actually useful — sure,
nonexistent entries aren't *free*, but a null pointer is still
a lot smaller than a pointer plus an SV, and arrays have fast
indexing and support for push/pop/shift/unshift. Having
keys/values/each on arrays respect existence potentially
*saves* delete/exist on arrays from needing deprecation, by
exposing them in a way that makes them part of a useful feature
instead of just esoteric internals weirdness.

Please read the aforelinked threads. This has already been argued
out at length.

There are some things those threads did not bring up.

This was never mentioned​:
http​://www.nntp.perl.org/group/perl.perl5.porters/2000/01/msg5596.html

Nobody brought up array-based objects. I know I’m not the only one using
those. See Class​::ArrayObjects.

Here is my main objection to the deprecation (which I would have raised
earlier had there been a warning)​:

If Perl wants to follow a C-style array model, fine. If Perl wants to
follow a JavaScript-style array model, that’s fine too. Just don’t adopt
one model for a decade and then switch!

It doesn’t really matter whether we like a particular model or not. If
we’ve been supporting it for a long time and there code using it (do a
few thousand lines count?), it stays. Or at least I should hope so.

There are plenty of old features that I don’t like, but I’m not going to
go and delete, e.g., typeglob assignment (once aliases are reimplemented
some other way).

Here is another thing those threads did not bring up​: If you never use
delete on an array, then key/each/values will continue to work as they
do now, for your code, even if the implementation changes to match
delete/exists. So you won’t even *notice*.

@p5pRT
Copy link
Author

@p5pRT p5pRT commented May 15, 2011

From @sciurius

[Quoting Father Chrysostomos via RT, on May 15 2011, 13​:00, in "[perl #90240] keys(@​"]

Here is another thing those threads did not bring up​: If you never
use delete on an array, then key/each/values will continue to work
as they do now, for your code, even if the implementation changes to
match delete/exists. So you won’t even *notice*.

As stated earlier, I consider​:

  @​a = ( 1, 2, 3 );
  $a[4] = 5;

equivalent to​:

  @​a = ( 1, 2, 3, 4, 5 );
  delete $a[3];

In either case, exists($a[3]) returns false.

This has been so for a long time (5.6 at least).

Now we have added a new feature, each on arrays. Just like hashes it
should return the existing elements. So keys(@​a) should return ( 0, 1,
2, 4 ). Otherwise, it has no added value over 0..$#a.

It's the new feature that fails, not the old one.
So fix the feature, don't deprecate what has been good functionality
for over 10 years.

-- Johan

@p5pRT
Copy link
Author

@p5pRT p5pRT commented May 24, 2011

From @ikegami

On Wed, May 11, 2011 at 7​:20 PM, Eric Brine <ikegami@​adaelis.com> wrote​:

Having delete/exists return a deprecation warning is a completely different
issue. I'll create a ticket with patch tonight.

Not forgotten. The patch was written that night. Just handling a small issue
in cpan/.

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Jul 4, 2012

From @doy

Eric, was this patch ever written?

-doy

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Jul 4, 2012

From @ikegami

On Tue Jul 03 17​:17​:05 2012, doy wrote​:

Eric, was this patch ever written?

Both the ticket and the patches were created. It is #105278

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Jul 4, 2012

From @sciurius

On Tue Jul 03 23​:02​:49 2012, ikegami@​adaelis.com wrote​:

On Tue Jul 03 17​:17​:05 2012, doy wrote​:

Eric, was this patch ever written?

Both the ticket and the patches were created. It is #105278

Regardless of whether delete/exists on arrays will be actually
deprecated -- I still consider it a lost opportunity to not add value to
keys(@​array) over 0..$#array.

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Jul 4, 2012

From @ikegami

On Wed Jul 04 04​:50​:19 2012, jv wrote​:

On Tue Jul 03 23​:02​:49 2012, ikegami@​adaelis.com wrote​:

On Tue Jul 03 17​:17​:05 2012, doy wrote​:

Eric, was this patch ever written?

Both the ticket and the patches were created. It is #105278

Regardless of whether delete/exists on arrays will be actually
deprecated -- I still consider it a lost opportunity to not add value to
keys(@​array) over 0..$#array.

Feel free to create a function that does what you want. keys should
return the keys as far as I'm concerned.

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Jul 4, 2012

From @sciurius

[Quoting Eric Brine via RT, on July 4 2012, 13​:38, in "[perl #90240] keys(@​"]

On Wed Jul 04 04​:50​:19 2012, jv wrote​:

Regardless of whether delete/exists on arrays will be actually
deprecated -- I still consider it a lost opportunity to not add value to
keys(@​array) over 0..$#array.

Feel free to create a function that does what you want. keys should
return the keys as far as I'm concerned.

keys() should return the keys, we agree fully. Except that I consider
keys that have never been assigned a value as nonexistent.

-- Johan

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Dec 12, 2017

From zefram@fysh.org

keys(@​array) has a defined meaning that is consistent with the
array-as-unbroken-sequence model that is used in most places. To change
it to implement the equivalent operation for the sparse-array model
would be disruptive. We shouldn't do that. If you really like the
discouraged sparse arrays and want a key-listing operation for them, you
should implement that as an XS module and put it on CPAN. This ticket
should be closed.

-zefram

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Dec 12, 2017

@iabyn - Status changed from 'open' to 'rejected'

@p5pRT p5pRT closed this as completed Dec 12, 2017
@p5pRT
Copy link
Author

@p5pRT p5pRT commented May 12, 2018

From @ikegami

On Tue, Dec 12, 2017 at 1​:56 AM, Zefram <zefram@​fysh.org> wrote​:

keys(@​array) has a defined meaning that is consistent with the
array-as-unbroken-sequence model that is used in most places. To change
it to implement the equivalent operation for the sparse-array model
would be disruptive. We shouldn't do that. If you really like the
discouraged sparse arrays and want a key-listing operation for them, you
should implement that as an XS module and put it on CPAN. This ticket
should be closed.

Don't even need XS.

sub initialized_array_indexes(\@​) {
  my $array = shift;
  grep { exists($array[$_]) } 0..$#$array
}

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

1 participant