in reply to Re^5: Using exists to check element in array
in thread Using exists to check element in array

Secondly

> ( grep { !exists( $a[$_] ) } keys @a ) ? "can" : "didn\x27t" );

Looks like keys @array was added to Perl in 5.12

And it's obviously inconsistent to delete and exists .

> The very existence of this inconsistency is reason enough for a warning.

But it's even worse!!!

keys is inconsistent to the behavior in hashes, even without using delete and exists and ever seeing any warnings !!!

my (@y,%y); $y[3]=$y{3}=1; say "keys \%y: ", join ",",keys %y; say "keys \@y: ", join ",",keys @y;

-->

keys %y: 3 keys @y: 0,1,2,3

A consistent implementation of keys ARRAY should check with exists first before returning an index.

Cheers Rolf
(addicted to the Perl Programming Language :)
see Wikisyntax for the Monastery

Replies are listed 'Best First'.
Re^7: Using exists to check element in array
by ikegami (Patriarch) on Feb 01, 2024 at 17:32 UTC

    And it's obviously inconsistent to delete and exists

    That's what I've been saying. exists isn't consistent. That's why there's a warning. And you're right, delete isn't either. We've proved this so many times already!

    keys is inconsistent to the behavior in hashes

    Next you'll say that scalar(@a) and scalar(%h) are inconsistent!

    Perl doesn't have sparse arrays. If $y[3] is in the array, so is $y[2].

    keys returns the elements found the structure for both arrays and hashes. keys is consistent for both arrays and hashes.

    Only exists and delete are inconsistent, as repeatedly demonstrated.

      VAR / VARELEM@a / $a[$i]%h / $h{$k}
      VARELEM = 1May add multiple elements to the array.Adds at most one element to the hash.
      VAR in list contextThe value of each element.The key and value of each element.
      VAR in scalar contextThe number of elements.
      keys(VAR) in list contextThe key of each element.
      keys(VAR) in scalar contextThe number of elements.
      values(VAR)The value of each element.
      each(VAR)All elements.
      exists(VARELEM)False if the element isn't in array.
      False if it's in the array and the underlying pointer is NULL.
      True if it's in the array and the underlying pointer isn't NULL.
      False if the element isn't in hash.
      True if it is in the hash.
      delete(VARELEM)Sets the element to undef by setting the underlying pointer to NULL.
      Removes the element from the array if it's the last one.
      Removes the element from the hash.
      > exists isn't consistent.

      No exists is/was consistent, keys ARRAY came later and is inconsistent.

      It doesn't make any sense that a $x[9]=1 on an empty array will make keys return 10 indices. And right after delete $x[9] keys will return none.

      DB<6> x @x empty array DB<7> $x[9]=1 DB<8> p keys @x 0123456789 DB<9> delete $x[9] DB<10> p keys @x DB<11>

      > Next you'll say that scalar(@a) and scalar(%h) are inconsistent!

      No not next, I already said that scalar @array is inconsistent.

      I keep saying that all of this depends on the definition of exists and that orthogonality to hashes was respected.

      You keep insisting that your definition of exists is the only possible one.

      And you still haven't shown any code were delete and exists alone produce different results on arrays than on hashes.

      Even more your example with the reference is consistent for both.

      And keys ARRAY is obviously troubled.

      Actually what's happening here is that two inconsistent concepts were interwoven.

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      see Wikisyntax for the Monastery

        You keep insisting that your definition of exists is the only possible one.

        Don't lie about what I've done. I've been purposefully avoiding the word "exists" since my first post to avoid this very issue. I've only been saying exists is inconsistent, and I showed that it does something different for hashes and arrays using both code and illustrations.

        Actually what's happening here is that two inconsistent concepts were interwoven.

        Or at least people could conflate two concepts. And that's why there's a warning.