Discussion:
Pre-RFC; "!isa" : negate sense of isa operator
(too old to reply)
Diab Jerius
2024-08-05 21:09:55 UTC
Permalink
There is no “isnta” operator, so to determine if an object isn't in a
class, one might write

    ! $obj isa Class

But, this is wrong. The precedence of the ‘!’ operator binds more
closely to $obj, and this is effectively

    (!$obj) isa Class

which isn’t at all correct.  One must write

     ! ($obj isa Class)

This has bit me in the nether regions enough times that it has become
annoying.  For the uninitiated, this results
in subtly broken code. For the initiated it adds parentheses which for
the lisp-less makes things more difficult to parse.

This contrast with other binary “equality” operators such as ⩵, eq,
which have negated versions, e.g. != , ne, so instead of writing

    !( $x ⩵ 3)

one writes

    $x != 3

In that vein, I suggest the bike sheddable “!isa”,

    $obj !isa Class

Diab
Joel Roth
2024-08-05 21:49:34 UTC
Permalink
There is no “isnta” operator, so to determine if an object isn't in a class,
one might write
    ! $obj isa Class
For this purpose, perl has a low-precedence negation
operator 'not'.

not $obj isa Class
But, this is wrong. The precedence of the ‘!’ operator binds more closely to
$obj, and this is effectively
    (!$obj) isa Class
which isn’t at all correct.  One must write
     ! ($obj isa Class)
This has bit me in the nether regions enough times that it has become
annoying.  For the uninitiated, this results
in subtly broken code. For the initiated it adds parentheses which for the
lisp-less makes things more difficult to parse.
This contrast with other binary “equality” operators such as ⩵, eq, which
have negated versions, e.g. != , ne, so instead of writing
    !( $x ⩵ 3)
one writes
    $x != 3
In that vein, I suggest the bike sheddable “!isa”,
    $obj !isa Class
Diab
--
Joel Roth
Darren Duncan
2024-08-05 22:00:40 UTC
Permalink
I agree that just using "not" is the best thing to do here rather than adding an
operator.

But if we were to add an operator then I feel single operators should never mix
symbolic and alphanumeric components, they should be one or the other only.

So "!" only combines with symbols, and something alpha has to be used for the
"isa" counterpart.

I am perfectly okay with an alpha operator being several words separated by
underscores, for example "not_isa".

Or it could be "nota".

-- Darren Duncan
Post by Joel Roth
There is no “isnta” operator, so to determine if an object isn't in a class,
one might write
    ! $obj isa Class
For this purpose, perl has a low-precedence negation
operator 'not'.
not $obj isa Class
But, this is wrong. The precedence of the ‘!’ operator binds more closely to
$obj, and this is effectively
    (!$obj) isa Class
which isn’t at all correct.  One must write
     ! ($obj isa Class)
This has bit me in the nether regions enough times that it has become
annoying.  For the uninitiated, this results
in subtly broken code. For the initiated it adds parentheses which for the
lisp-less makes things more difficult to parse.
This contrast with other binary “equality” operators such as ⩵, eq, which
have negated versions, e.g. != , ne, so instead of writing
    !( $x ⩵ 3)
one writes
    $x != 3
In that vein, I suggest the bike sheddable “!isa”,
    $obj !isa Class
Diab
Felipe Gasper via perl5-porters
2024-08-05 22:32:38 UTC
Permalink
isnta :)

-FG
I agree that just using "not" is the best thing to do here rather than adding an operator.
But if we were to add an operator then I feel single operators should never mix symbolic and alphanumeric components, they should be one or the other only.
So "!" only combines with symbols, and something alpha has to be used for the "isa" counterpart.
I am perfectly okay with an alpha operator being several words separated by underscores, for example "not_isa".
Or it could be "nota".
-- Darren Duncan
Post by Joel Roth
There is no “isnta” operator, so to determine if an object isn't in a class,
one might write
! $obj isa Class
For this purpose, perl has a low-precedence negation
operator 'not'.
not $obj isa Class
But, this is wrong. The precedence of the ‘!’ operator binds more closely to
$obj, and this is effectively
(!$obj) isa Class
which isn’t at all correct. One must write
! ($obj isa Class)
This has bit me in the nether regions enough times that it has become
annoying. For the uninitiated, this results
in subtly broken code. For the initiated it adds parentheses which for the
lisp-less makes things more difficult to parse.
This contrast with other binary “equality” operators such as ⩵, eq, which
have negated versions, e.g. != , ne, so instead of writing
!( $x ⩵ 3)
one writes
$x != 3
In that vein, I suggest the bike sheddable “!isa”,
$obj !isa Class
Diab
Nicolas Mendoza via perl5-porters
2024-08-06 00:48:34 UTC
Permalink
Post by Diab Jerius
There is no “isnta” operator, so to determine if an object isn't in a
class, one might write
    ! $obj isa Class
But, this is wrong. The precedence of the ‘!’ operator binds more
closely to $obj, and this is effectively
    (!$obj) isa Class
which isn’t at all correct.  One must write
     ! ($obj isa Class)
This has bit me in the nether regions enough times that it has become
annoying.  For the uninitiated, this results
in subtly broken code. For the initiated it adds parentheses which for
the lisp-less makes things more difficult to parse.
This contrast with other binary “equality” operators such as ⩵, eq,
which have negated versions, e.g. != , ne, so instead of writing
    !( $x ⩵ 3)
one writes
    $x != 3
In that vein, I suggest the bike sheddable “!isa”,
    $obj !isa Class
Or we could allow calling an `isa` method on undef also, and you could
write !$obj->isa('Class'); (same goes for 'ref'  guess)

perl -wlE 'use experimental qw/class/; class A { }; my @a = (A->new,
"string", 7, undef); print "$_:" . (!$_->isa("A") ? "false" : "true")
for @a'

A=OBJECT(0x5aae33a84700):true
string:false
7:false
Use of uninitialized value $_ in concatenation (.) or string at -e line 1.
Can't call method "isa" on an undefined value at -e line 1.
--
Nicolas Mendoza
Paul "LeoNerd" Evans
2024-08-06 10:20:53 UTC
Permalink
On Tue, 6 Aug 2024 05:56:21 +0200
Post by Diab Jerius
There is no “isnta” operator, so to determine if an object isn't in
a class, one might write
    ! $obj isa Class
But, this is wrong. The precedence of the ‘!’ operator binds more
closely to $obj, and this is effectively
    (!$obj) isa Class
which isn’t at all correct.  One must write
     ! ($obj isa Class)
This has bit me in the nether regions enough times that it has
become annoying.  For the uninitiated, this results
in subtly broken code. For the initiated it adds parentheses which
for the lisp-less makes things more difficult to parse.
None of the proposed solutions in this thread tackle what seems to me
the main problem: We already have two reasonable and correct ways to
write this code, but adding more correct ways does not prevent people
from writing the incorrect `! $obj isa Class`.
Until now.
Starting from today, perl will emit a warning if it sees the
mauke++ # actually solving the real problem
--
Paul "LeoNerd" Evans

***@leonerd.org.uk
http://www.leonerd.org.uk/ | https://metacpan.org/author/PEVANS
Diab Jerius
2024-08-06 16:03:52 UTC
Permalink
Post by Diab Jerius
There is no “isnta” operator, so to determine if an object isn't in a
class, one might write
     ! $obj isa Class
But, this is wrong. The precedence of the ‘!’ operator binds more
closely to $obj, and this is effectively
     (!$obj) isa Class
which isn’t at all correct.  One must write
      ! ($obj isa Class)
This has bit me in the nether regions enough times that it has become
annoying.  For the uninitiated, this results
in subtly broken code. For the initiated it adds parentheses which
for the lisp-less makes things more difficult to parse.
None of the proposed solutions in this thread tackle what seems to me
the main problem: We already have two reasonable and correct ways to
write this code, but adding more correct ways does not prevent people
from writing the incorrect `! $obj isa Class`.
Until now.
Starting from today, perl will emit a warning if it sees the incorrect
    $ ./perl -Ilib -wE 'my $obj; ! $obj isa Class'
    Possible precedence problem on isa operator at -e line 1.
    $ ./perl -Ilib -wE 'my $obj; ! $obj isa Class' |& splain
    Possible precedence problem on isa operator at -e line 1 (#1)
        (W precedence) You wrote something like
            !$obj isa Some::Class
        but because ! has higher precedence than isa, this is
interpreted as
        (!$obj) isa Some::Class, which checks whether a boolean is an
instance of
        Some::Class. If you want to negate the result of isa instead,
            !($obj isa Some::Class)   # explicit parentheses
            not $obj isa Some::Class  # low-precedence 'not' operator
That does seem the appropriate solution.

Many thanks!

Diab

Loading...