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

List::Util::uniqnum() broken in current Scalar-List-Utils #17174

Closed
p5pRT opened this issue Oct 5, 2019 · 21 comments
Closed

List::Util::uniqnum() broken in current Scalar-List-Utils #17174

p5pRT opened this issue Oct 5, 2019 · 21 comments
Labels
cpan-dual-life issues regarding dual-life cpan-first distributions
Milestone

Comments

@p5pRT
Copy link

p5pRT commented Oct 5, 2019

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

Searchable as RT134481$

@p5pRT
Copy link
Author

p5pRT commented Oct 5, 2019

From @sisyphus

The dual-life module Scalar-List-Utils is currently at version 1.52.
It's List​::Util​::uniqnum() function is prone to errors.

The pull request at Dual-Life/Scalar-List-Utils#79
fixes those errors.
It also amends the test script t/uniq.t so that the failures of version
1.52 are exposed. Those amendments to t/uniq.t further serve to verify that
the pull request fixes those failures.
Attached is that amended version of t/uniq.t. Run it using current blead to
see the current failures.

All perl configurations are subject to uniqnum() failures, though not all
configurations fail in exactly the same way.

How should I proceed to have this fixed in time for perl-5.32 ?

Cheers,
Rob

Summary of my perl5 (revision 5 version 31 subversion 4) configuration​:

  Platform​:
  osname=MSWin32
  osvers=6.1.7601
  archname=MSWin32-x64-multi-thread
  uname=''
  config_args='undef'
  hint=recommended
  useposix=true
  d_sigaction=undef
  useithreads=define
  usemultiplicity=define
  use64bitint=define
  use64bitall=undef
  uselongdouble=undef
  usemymalloc=n
  default_inc_excludes_dot=define
  bincompat5005=undef
  Compiler​:
  cc='gcc'
  ccflags =' -s -O2 -DWIN32 -DWIN64 -DCONSERVATIVE
-DPERL_TEXTMODE_SCRIPTS -DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_SYS
-DUSE_PERLIO -D__USE_MINGW_ANSI_STDIO -fwrapv -fno-strict-aliasing
-mms-bitfields'
  optimize='-s -O2'
  cppflags='-DWIN32'
  ccversion=''
  gccversion='8.3.0'
  gccosandvers=''
  intsize=4
  longsize=4
  ptrsize=8
  doublesize=8
  byteorder=12345678
  doublekind=3
  d_longlong=define
  longlongsize=8
  d_longdbl=define
  longdblsize=16
  longdblkind=3
  ivtype='long long'
  ivsize=8
  nvtype='double'
  nvsize=8
  Off_t='long long'
  lseeksize=8
  alignbytes=8
  prototype=define
  Linker and Libraries​:
  ld='g++'
  ldflags ='-s -L"C​:\_64\blead-5.31.4\lib\CORE"
-L"C​:\_64\gcc-straw-830\mingw64\lib"'
  libpth=C​:\_64\gcc-straw-830\mingw64\lib
C​:\_64\gcc-straw-830\mingw64\x86_64-w64-mingw32\lib
C​:\_64\msys_830\1.0\local\lib
C​:\_64\gcc-straw-830\mingw64\lib\gcc\x86_64-w64-mingw32\8.3.0
  libs= -lmoldname -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32
-ladvapi32 -lshell32 -lole32 -loleaut32 -lnetapi32 -luuid -lws2_32 -lmpr
-lwinmm -lversion -lodbc32 -lodbccp32 -lcomctl32
  perllibs= -lmoldname -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32
-ladvapi32 -lshell32 -lole32 -loleaut32 -lnetapi32 -luuid -lws2_32 -lmpr
-lwinmm -lversion -lodbc32 -lodbccp32 -lcomctl32
  libc=
  so=dll
  useshrplib=true
  libperl=libperl531.a
  gnulibc_version=''
  Dynamic Linking​:
  dlsrc=dl_win32.xs
  dlext=dll
  d_dlsymun=undef
  ccdlflags=' '
  cccdlflags=' '
  lddlflags='-mdll -s -L"C​:\_64\blead-5.31.4\lib\CORE"
-L"C​:\_64\gcc-straw-830\mingw64\lib"'

Characteristics of this binary (from libperl)​:
  Compile-time options​:
  HAS_TIMES
  HAVE_INTERP_INTERN
  MULTIPLICITY
  PERLIO_LAYERS
  PERL_COPY_ON_WRITE
  PERL_DONT_CREATE_GVSV
  PERL_IMPLICIT_CONTEXT
  PERL_IMPLICIT_SYS
  PERL_MALLOC_WRAP
  PERL_OP_PARENT
  PERL_PRESERVE_IVUV
  USE_64_BIT_INT
  USE_ITHREADS
  USE_LARGE_FILES
  USE_LOCALE
  USE_LOCALE_COLLATE
  USE_LOCALE_CTYPE
  USE_LOCALE_NUMERIC
  USE_LOCALE_TIME
  USE_PERLIO
  USE_PERL_ATOF
  Built under MSWin32
  Compiled at Sep 21 2019 10​:05​:36
  @​INC​:
  C​:/_64/blead-5.31.4/site/lib
  C​:/_64/blead-5.31.4/lib

@p5pRT
Copy link
Author

p5pRT commented Oct 5, 2019

From @sisyphus

#!./perl

use strict;
use warnings;
use Config; # to determine nvsize
use Test​::More tests => 37;
use List​::Util qw( uniqnum uniqstr uniq );

use Tie​::Array;

is_deeply( [ uniqstr ],
  [],
  'uniqstr of empty list' );

is_deeply( [ uniqstr qw( abc ) ],
  [qw( abc )],
  'uniqstr of singleton list' );

is_deeply( [ uniqstr qw( x x x ) ],
  [qw( x )],
  'uniqstr of repeated-element list' );

is_deeply( [ uniqstr qw( a b a c ) ],
  [qw( a b c )],
  'uniqstr removes subsequent duplicates' );

is_deeply( [ uniqstr qw( 1 1.0 1E0 ) ],
  [qw( 1 1.0 1E0 )],
  'uniqstr compares strings' );

{
  my $warnings = "";
  local $SIG{__WARN__} = sub { $warnings .= join "", @​_ };

  is_deeply( [ uniqstr "", undef ],
  [ "" ],
  'uniqstr considers undef and empty-string equivalent' );

  ok( length $warnings, 'uniqstr on undef yields a warning' );

  is_deeply( [ uniqstr undef ],
  [ "" ],
  'uniqstr on undef coerces to empty-string' );
}

SKIP​: {
  skip 'Perl 5.007003 with utf8​::encode is required', 3 if $] lt "5.007003";
  my $warnings = "";
  local $SIG{__WARN__} = sub { $warnings .= join "", @​_ };

  my $cafe = "cafe\x{301}";

  is_deeply( [ uniqstr $cafe ],
  [ $cafe ],
  'uniqstr is happy with Unicode strings' );

  SKIP​: {
  skip "utf8​::encode not available", 1
  unless defined &utf8​::encode;
  utf8​::encode( my $cafebytes = $cafe );

  is_deeply( [ uniqstr $cafe, $cafebytes ],
  [ $cafe, $cafebytes ],
  'uniqstr does not squash bytewise-equal but differently-encoded strings' );
  }

  is( $warnings, "", 'No warnings are printed when handling Unicode strings' );
}

if($Config{nvsize} == 8 && $Config{ivsize} == 8) {

  is_deeply( [ uniqnum qw( 1 1.0 1E0 2 3 9223372036854775808 9.2233720368547758e+18) ],
  [ 1, 2, 3, 9223372036854775808 ],
  'uniqnum compares numbers' );
}

else {

  is_deeply( [ uniqnum qw( 1 1.0 1E0 2 3 ) ],
  [ 1, 2, 3 ],
  'uniqnum compares numbers' );
}

is_deeply( [ uniqnum qw( 1 1.1 1.2 1.3 ) ],
  [ 1, 1.1, 1.2, 1.3 ],
  'uniqnum distinguishes floats' );

{
  my @​nums = map $_+0.1, 1e7..1e7+5;
  is_deeply( [ uniqnum @​nums ],
  [ @​nums ],
  'uniqnum distinguishes large floats' );

  my @​strings = map "$_", @​nums;
  is_deeply( [ uniqnum @​strings ],
  [ @​strings ],
  'uniqnum distinguishes large floats (stringified)' );
}

my ($uniq_count1, $uniq_count2, $equiv);

if($Config{nvsize} == 8) {
  # NV is either 'double' or 8-byte 'long double'

  # The 2 values should be unequal - but just in case perl is buggy​:
  $equiv = 1 if 1.4142135623730951 == 1.4142135623730954;

  $uniq_count1 = List​::Util​::uniqnum (1.4142135623730951,
  1.4142135623730954 );

  $uniq_count2 = List​::Util​::uniqnum('1.4142135623730951',
  '1.4142135623730954' );
}

elsif(length(sqrt(2)) > 25) {
  # NV is either IEEE 'long double' or '__float128' or doubledouble

  if(1 + (2 ** -1074) != 1) {
  # NV is doubledouble

  # The 2 values should be unequal - but just in case perl is buggy​:
  $equiv = 1 if 1 + (2 ** -1074) == 1 + (2 ** - 1073);

  $uniq_count1 = List​::Util​::uniqnum (1 + (2 ** -1074),
  1 + (2 ** -1073) );
  # The 2 values should be unequal - but just in case perl is buggy​:
  $equiv = 1 if 4.0564819207303340847894502572035e31 == 4.0564819207303340847894502572034e31;

  $uniq_count2 = List​::Util​::uniqnum('4.0564819207303340847894502572035e31',
  '4.0564819207303340847894502572034e31' );
  }

  else {
  # NV is either IEEE 'long double' or '__float128'

  # The 2 values should be unequal - but just in case perl is buggy​:
  $equiv = 1 if 1.7320508075688772935274463415058722 == 1.73205080756887729352744634150587224;

  $uniq_count1 = List​::Util​::uniqnum (1.7320508075688772935274463415058722,
  1.73205080756887729352744634150587224 );

  $uniq_count2 = List​::Util​::uniqnum('1.7320508075688772935274463415058722',
  '1.73205080756887729352744634150587224' );
  }
}

else {
  # NV is extended precision 'long double'

  # The 2 values should be unequal - but just in case perl is buggy​:
  $equiv = 1 if 2.2360679774997896963 == 2.23606797749978969634;

  $uniq_count1 = List​::Util​::uniqnum (2.2360679774997896963,
  2.23606797749978969634 );

  $uniq_count2 = List​::Util​::uniqnum('2.2360679774997896963',
  '2.23606797749978969634' );
}

if($equiv) {
  is($uniq_count1, 1, 'uniqnum preserves uniqness of high precision floats');
  is($uniq_count2, 1, 'uniqnum preserves uniqness of high precision floats (stringified)');
}

else {
  is($uniq_count1, 2, 'uniqnum preserves uniqness of high precision floats');
  is($uniq_count2, 2, 'uniqnum preserves uniqness of high precision floats (stringified)');
}

SKIP​: {
  skip ('test not relevant for this perl configuration', 1) unless $Config{nvsize} == 8
  && $Config{ivsize} == 8;

  my @​in = (~0, ~0 - 1, 18446744073709551614.0, 18014398509481985, 1.8014398509481985e16);
  my(@​correct);

  # On perl-5.6.2 (and perhaps other old versions), ~0 - 1 is assigned to an NV.
  # This affects the outcome of the following test, so we need to first determine
  # whether ~0 - 1 is an NV or a UV​:

  if("$in[1]" eq "1.84467440737096e+19") {

  # It's an NV and $in[2] is a duplicate of $in[1]
  @​correct = (~0, ~0 - 1, 18014398509481985, 1.8014398509481985e16);
  }
  else {

  # No duplicates in @​in
  @​correct = @​in;
  }

  is_deeply( [ uniqnum @​in ],
  [ @​correct ],
  'uniqnum correctly compares UV/IVs that overflow NVs' );
}

# Hard to know for sure what an Inf is going to be. Lets make one
my $Inf = 0 + 1E1000;
my $NaN;
$Inf **= 1000 while ( $NaN = $Inf - $Inf ) == $NaN;

is_deeply( [ uniqnum 0, 1, 12345, $Inf, -$Inf, $NaN, 0, $Inf, $NaN ],
  [ 0, 1, 12345, $Inf, -$Inf, $NaN ],
  'uniqnum preserves the special values of +-Inf and Nan' );

SKIP​: {
  my $maxuint = ~0;
  my $maxint = ~0 >> 1;
  my $minint = -(~0 >> 1) - 1;

  my @​nums = ($maxuint, $maxuint-1, -1, $Inf, $NaN, $maxint, $minint, 1 );

  is_deeply( [ uniqnum @​nums, 1.0 ],
  [ @​nums ],
  'uniqnum preserves uniqness of full integer range' );

  my @​strs = map "$_", @​nums;

  if($maxuint !~ /\A[0-9]+\z/) {
  skip( "Perl $] doesn't stringify UV_MAX right ($maxuint)", 1 );
  }
  elsif($] < 5.022 && $^O =~ /MSWin32/i) {
  skip( "On MS Windows,perl $] stringifies infs and nans into something unusable", 1 );
  }
 

  is_deeply( [ uniqnum @​strs, "1.0" ],
  [ @​strs ],
  'uniqnum preserves uniqness of full integer range (stringified)' );
}

{
  my $warnings = "";
  local $SIG{__WARN__} = sub { $warnings .= join "", @​_ };

  is_deeply( [ uniqnum 0, undef ],
  [ 0 ],
  'uniqnum considers undef and zero equivalent' );

  ok( length $warnings, 'uniqnum on undef yields a warning' );

  is_deeply( [ uniqnum undef ],
  [ 0 ],
  'uniqnum on undef coerces to zero' );
}

is_deeply( [uniqnum 0, -0.0 ],
  [0],
  'uniqnum handles negative zero');

is_deeply( [ uniq () ],
  [],
  'uniq of empty list' );

{
  my $warnings = "";
  local $SIG{__WARN__} = sub { $warnings .= join "", @​_ };

  is_deeply( [ uniq "", undef ],
  [ "", undef ],
  'uniq distintinguishes empty-string from undef' );

  is_deeply( [ uniq undef, undef ],
  [ undef ],
  'uniq considers duplicate undefs as identical' );

  ok( !length $warnings, 'uniq on undef does not warn' );
}

is( scalar( uniqstr qw( a b c d a b e ) ), 5, 'uniqstr() in scalar context' );

{
  package Stringify;

  use overload '""' => sub { return $_[0]->{str} };

  sub new { bless { str => $_[1] }, $_[0] }

  package main;

  my @​strs = map { Stringify->new( $_ ) } qw( foo foo bar );

  is_deeply( [ map "$_", uniqstr @​strs ],
  [ map "$_", $strs[0], $strs[2] ],
  'uniqstr respects stringify overload' );
}

{
  package Numify;

  use overload '0+' => sub { return $_[0]->{num} };

  sub new { bless { num => $_[1] }, $_[0] }

  package main;
  use Scalar​::Util qw( refaddr );

  my @​nums = map { Numify->new( $_ ) } qw( 2 2 5 );

  # is_deeply wants to use eq overloading
  my @​ret = uniqnum @​nums;
  ok( scalar @​ret == 2 &&
  refaddr $ret[0] == refaddr $nums[0] &&
  refaddr $ret[1] == refaddr $nums[2],
  'uniqnum respects numify overload' );
}

{
  package DestroyNotifier;

  use overload '""' => sub { "SAME" };

  sub new { bless { var => $_[1] }, $_[0] }

  sub DESTROY { ${ $_[0]->{var} }++ }

  package main;

  my @​destroyed = (0) x 3;
  my @​notifiers = map { DestroyNotifier->new( \$destroyed[$_] ) } 0 .. 2;

  my @​uniqstr = uniqstr @​notifiers;
  undef @​notifiers;

  is_deeply( \@​destroyed, [ 0, 1, 1 ],
  'values filtered by uniqstr() are destroyed' );

  undef @​uniqstr;
  is_deeply( \@​destroyed, [ 1, 1, 1 ],
  'all values destroyed' );
}

{
  "a a b" =~ m/(.) (.) (.)/;
  is_deeply( [ uniqstr $1, $2, $3 ],
  [qw( a b )],
  'uniqstr handles magic' );

  "1 1 2" =~ m/(.) (.) (.)/;
  is_deeply( [ uniqnum $1, $2, $3 ],
  [ 1, 2 ],
  'uniqnum handles magic' );
}

{
  my @​array;
  tie @​array, 'Tie​::StdArray';
  @​array = (
  ( map { ( 1 .. 10 ) } 0 .. 1 ),
  ( map { ( 'a' .. 'z' ) } 0 .. 1 )
  );

  my @​u = uniq @​array;
  is_deeply(
  \@​u,
  [ 1 .. 10, 'a' .. 'z' ],
  'uniq uniquifies mixed numbers and strings correctly in a tied array'
  );
}

@p5pRT
Copy link
Author

p5pRT commented Oct 5, 2019

From @jkeenan

On Sat, 05 Oct 2019 04​:23​:25 GMT, sisyphus359@​gmail.com wrote​:

The dual-life module Scalar-List-Utils is currently at version 1.52.
It's List​::Util​::uniqnum() function is prone to errors.

The pull request at Dual-Life/Scalar-List-Utils#79
fixes those errors.
It also amends the test script t/uniq.t so that the failures of version
1.52 are exposed. Those amendments to t/uniq.t further serve to verify that
the pull request fixes those failures.
Attached is that amended version of t/uniq.t. Run it using current blead to
see the current failures.

All perl configurations are subject to uniqnum() failures, though not all
configurations fail in exactly the same way.

How should I proceed to have this fixed in time for perl-5.32 ?

Cheers,
Rob

It's unclear from this ticket what the failures in List​::Util​::uniqnum() actually are. Perhaps more to the point, the ticket doesn't make clear *where* they occur. Is this a Windows-specific problem?

Thank you very much.

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

@p5pRT
Copy link
Author

p5pRT commented Oct 5, 2019

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

@p5pRT
Copy link
Author

p5pRT commented Oct 5, 2019

From @sisyphus

On Sat, 05 Oct 2019 05​:03​:46 -0700, jkeenan wrote​:

It's unclear from this ticket what the failures in
List​::Util​::uniqnum() actually are. Perhaps more to the point, the
ticket doesn't make clear *where* they occur. Is this a Windows-
specific problem?

Thank you very much.

It's something that afflicts all systems, and all configurations of perl.

Here's one example of a failure that will appear on all configurations of blead​:

$ perl -MList​::Util="uniqnum" -le '@​x = uniqnum(1.4142135623730951, 1.4142135623730954); print "@​x";'
1.4142135623731

Here uniqnum() is asserting that 1.4142135623730951 and 1.4142135623730954 are the same value, even though perl itself recognizes that the 2 values are distinct​:

$ perl -le 'print "ok" if 1.4142135623730951 != 1.4142135623730954;'
ok

Another failure across all configurations is​:

perl -MList​::Util="uniqnum" -le '@​x = uniqnum(0, -0.0); print "@​x";'
0 0

In this instance, uniqnum() is asserting that 0 and -0.0 are different values.

And here's a third example that afflicts only those perl configurations where both $Config{ivsize} and $Config{nvsize} are 8​:

$ perl -MList​::Util="uniqnum" -le '@​x = uniqnum(9223372036854775808, 9.2233720368547758e+18); print "@​x";'
9223372036854775808 9.22337203685478e+18

Here, uniqnum() asserts that 9223372036854775808 and 9.2233720368547758e+18 are different values even though they are both exact representations of 2 ** 63.

These examples are drawn from the extended version of uniq.t that I attached to my initial bug report.

Cheers,
Rob

@p5pRT
Copy link
Author

p5pRT commented Oct 5, 2019

From @leonerd

On Fri, 04 Oct 2019 21​:23​:25 -0700
"sisyphus \(via RT\)" <perlbug-followup@​perl.org> wrote​:

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

The dual-life module Scalar-List-Utils is currently at version 1.52.
It's List​::Util​::uniqnum() function is prone to errors.

The pull request at
Dual-Life/Scalar-List-Utils#79 fixes those
errors. It also amends the test script t/uniq.t so that the failures
of version 1.52 are exposed. Those amendments to t/uniq.t further
serve to verify that the pull request fixes those failures.
Attached is that amended version of t/uniq.t. Run it using current
blead to see the current failures.

I've been waiting until you get to the end of adjusting that PR before
I take a look at it, as you seemed to be continuing to work on it.

Is it now ready to merge?

--
Paul "LeoNerd" Evans

leonerd@​leonerd.org.uk | https://metacpan.org/author/PEVANS
http​://www.leonerd.org.uk/ | https://www.tindie.com/stores/leonerd/

@p5pRT
Copy link
Author

p5pRT commented Oct 6, 2019

From @sisyphus

On Sat, 05 Oct 2019 07​:33​:27 -0700, leonerd@​leonerd.org.uk wrote​:

Is it now ready to merge?

Yes, it's now ready.

Cheers,
Rob

@sisyphus
Copy link
Contributor

Since my last post to this thread, we've moved on to
Dual-Life/Scalar-List-Utils#80
which is now, IMO, ready for merging.

Please take a look, and then we can work out how to proceed.

As it stands in perl-5.31.5 and earlier, I think uniqnum() is currently fit for purpose so long as all numbers are either IVs or UVs.
But it is is not fit for purpose when NVs (either integral or fractional values) that cannot be accurately represented in 15 or fewer decimal digits are involved.

For tonight's weird example:
$c = uniqnum(2 ** 50, 1 * (2 ** 50));
will set $c to 2 (unless $Config{ivsize} == 4, which is rare these days).
$c should, of course, be set to 1, as both values are identical.
The error arises partly because the first argument is an NV while the second is an IV, and partly because 2 ** 50 requires more than 15 decimal digits of precision for accurate representation.
Similarly for exponents in the range 51..63, and for a vast number of other integral values.

Cheers,
Rob

@jkeenan
Copy link
Contributor

jkeenan commented Oct 22, 2019 via email

@toddr
Copy link
Member

toddr commented Oct 22, 2019

@leonerd FYI

@sisyphus
Copy link
Contributor

sisyphus commented Nov 21, 2019 via email

@jkeenan jkeenan added affects-5.32 cpan-dual-life issues regarding dual-life cpan-first distributions and removed Severity Low labels Nov 21, 2019
@jkeenan
Copy link
Contributor

jkeenan commented Nov 21, 2019

@leonerd, Can you take a look at this?

Thank you very much.
Jim Keenan

@toddr toddr added this to the 5.32.0 milestone Nov 21, 2019
@jkeenan
Copy link
Contributor

jkeenan commented Jan 28, 2020

@leonerd, Can you take a look at this?

Thank you very much.
Jim Keenan

@leonerd, can you take a look at this problem with List::Util::uniqnum?

Thank you very much.
Jim Keenan

@leonerd
Copy link
Contributor

leonerd commented Jan 29, 2020

How does this relate to the Scalar-List-Utils issue Dual-Life/Scalar-List-Utils#84 ?

@sisyphus
Copy link
Contributor

sisyphus commented Jan 29, 2020 via email

@xsawyerx
Copy link
Member

xsawyerx commented Apr 1, 2020

I don't understand where we're standing on this. @leonerd can you provide your view of it?

@sisyphus
Copy link
Contributor

sisyphus commented Apr 1, 2020

@xsawyerx, I realize that your question was not directed to me, but I have information that I feel may be relevant to your question.
The previous post in this thread to which you've posted (ie #17174) referenced Dual-Life/Scalar-List-Utils#84 .
Things have moved on since then, and trying to make sense of everything from within the confines of this particular thread (#17174) is difficult and confusing.

The PR at Dual-Life/Scalar-List-Utils#99 has since been approved, and we're now up to considering my latest PR, which is:
Dual-Life/Scalar-List-Utils#100

The code proposed in Dual-Life/Scalar-List-Utils#100 has been testing fine in List-Uniqnum-0.11.
See:
https://www.cpantesters.org/distro/L/List-Uniqnum.html?oncpan=1&distmat=1&version=0.11&grade=2

There's a couple of UNKNOWN results due, pretty clearly, to something other than the code - ie a problem with the configuration of the particular smoker, and/or some quirk of the way that the List::Uniqnum source distro has been assembled.
I've personally tested List-Uniqnum-0.11 (and earlier) using the exact same Strawberry Perl builds that have thrown up these UNKNOWN reports and I cannot reproduce the problem.

With the committing of Dual-Life/Scalar-List-Utils#99, most of the issues that I know of regarding List::Util::uniqnum were taken care of.
However, that PR did not address an issue with perls built with "less recent" Microsoft Compilers, whereby on perls whose ivsize == nvsize ==8, uniqnum() deemed some equivalent values to be inequivalent.
I don't know the exact meaning of "less recent". I do know that VC++ 2010 and earlier are "less recent" - ie they suffer the problem that was not addressed until Dual-Life/Scalar-List-Utils#100 .
I know that VC++ 2017 and later are fine with Dual-Life/Scalar-List-Utils#99, but I don't know precisely the first version of VC++ that was not afflicted. (My guess is that it was VC++ 2015.)

Dual-Life/Scalar-List-Utils#100 addresses all issues that I know of - including an additional issue with DoubleDouble builds that I was unaware of when I proposed Dual-Life/Scalar-List-Utils#99.
It so happens that the fix for the "less recent" Microsoft Compilers contained in Dual-Life/Scalar-List-Utils#100, was simpler and more efficient than the existing code that dealt with other systems - so I extended Dual-Life/Scalar-List-Utils#100 to apply that fix "across the board" to all systems..

IMO, Dual-Life/Scalar-List-Utils#100 is bug free - though there may be one or more perl bugs, on some system, for some version of perl, that brings it undone.
If such bugs exist, then it's not on any of the perls that are being used by cpantesters.
And it's not on perl-5.6.2 or perls built with VC++2010, VC++2017, VC++2019, as I've personally tested them.
I've also personally tested mingw-built perls on Windows (including x86 and x64 builds) from 5.8.8 to 5.31.10 - both -Duselongdouble and not.
I've also personally tested perls on Ubuntu (including -Dusequadmath, -Duselongdouble) from 5.30.0 on.

I recognize that there's no guarantee that the test suite is not failing to detect some issue.
But I do feel confident that if there's some bug that is not addressed by Dual-Life/Scalar-List-Utils#100;, then it will be:
a) a bug in perl itself;
&&
b) a bug that's rarely encountered;
&&
c) a bug that's trivial to fix.

Oh ... one more thing ... there may be a more efficient fix for that DoubleDouble problem that I mentioned above.
If there is, it can certainly wait until after perl-5.32.0, as the fix in Dual-Life/Scalar-List-Utils#100 works just fine.

I've made some bold and confident assertions in this post.
Any examples that show that confidence to be misplaced are most welcome.
(Seriously, I would welcome that. It would be such an improvement upon the general disinterest with which my endeavours have so far been met.)

Cheers,
Rob

@xsawyerx
Copy link
Member

xsawyerx commented Apr 5, 2020

@sisyphus I appreciate the thorough rundown and the valuable, tireless work you've done on this. I would like to see these changes merged into Scalar-List-Util and have it merged within a development release.

@leonerd can you give an update on Dual-Life/Scalar-List-Utils#100?

@tonycoz
Copy link
Contributor

tonycoz commented Apr 15, 2020

For anyone following along, Scalar-List-Utils 1.55 includes the fix for this.

@xsawyerx
Copy link
Member

Thanks, @tonycoz. :)

@sisyphus
Copy link
Contributor

I should point out that, although these particular issues with uniqnum have been fixed in 1.55 the uniqint function, which was introduced out-of-the-blue in 1.55, is broken.

See Dual-Life/Scalar-List-Utils#105 which, I believe, fixes those remaining uniqint issues.

Cheers,
Rob

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cpan-dual-life issues regarding dual-life cpan-first distributions
Projects
None yet
Development

No branches or pull requests

7 participants