http://qs321.pair.com?node_id=646923

stu42j has asked for the wisdom of the Perl Monks concerning the following question:

Is it just me or does it seem wrong that undef == 0 evaluates to true?

Update: In retrospect, I feel kind of stupid for having asked this question and wish I had just thought about it a little more (or at least asked in a less permanent way :). At the very least, though, it has reconfirmed for me the importance of use warnings and maybe next time I won't grumble at the "Use of uninitialized value in numeric eq".

Replies are listed 'Best First'.
Re: undef == 0?
by Fletch (Bishop) on Oct 24, 2007 at 16:25 UTC

    Since the undefined value in a numeric context is treated as 0 why should it?

    Granted it may be surprising coming from different context (say Ruby where nil is not equal to anything but itself), but by the way undef is defined in Perl that's just the way it is. But if you're using warnings you will get whinged at for doing so.

      Well, that's really my question. "Why is an undefined value treated as zero in numeric context?" That still doesn't really make sense to me.

      I forgot about the warning though which means I need to add a defined in there. Then the problem goes away.

        As everyone else has asked, what number would you propose it be treated as?

        Perl doesn't have a single equality operator, it has two which operate on specific types of values:

        • == / != for numeric values
        • eq / ne for string values

        A numeric value gets promoted to its string representation when used as a string. A string value gets converted to a numeric value (if possible; 0 if it's not a valid numeric representation) when used as a number.

        So when you consider what could be done with the "wrong" kind of value in a given context there's two possibilities:

        • treat it as a domain error (you're not allowed to compare these two types of values; see my Ruby example)
        • convert it to a value in the correct domain (which is what Perl does)

        Given that the second choice was made, again what other value would you expect? I might could see an argument being made for NaN, but the choice of 0 makes lots of things "just work" nicely (especially for things like quick 1-liners or 5 minute throw-away scripts where you really aren't that concerned with data validation).

Re: undef == 0?
by ikegami (Patriarch) on Oct 24, 2007 at 16:25 UTC

    That's why it issues a warning. That's more than you'd get in C (truly undefined) or VB (silent conversion to 0).

    Which number would you have undef become in numerical context?

Re: undef == 0?
by Old_Gray_Bear (Bishop) on Oct 24, 2007 at 16:28 UTC
    Hum. If I remember the BNF rightly,
    1. undef *= FALSE
    2. 0 *= FALSE
    3. FALSE: FALSE *= TRUE (Since we have the same thing on both sides of the comparison operator.)

    Sounds logical to me.

    ----
    I Go Back to Sleep, Now.

    OGB

Re: undef == 0?
by samtregar (Abbot) on Oct 24, 2007 at 16:52 UTC
    I suppose you prefer something like SQL's tri-state logic. Frankly, I find (NULL = NULL) being NULL much more confusing than (undef == 0) being true!

    -sam

      Yeah, I was thinking somewhere along the lines of how SQL treats NULLs. Although I suppose that instinctively, I would expect undef == 0 to be false but undef == undef to be true. Not that it would be right in any way.

      Tristate... you said the magic word!

      my $test = return_from_function(); if (not defined $test) { # do this if evaluates to undefined } elsif (!$test) { # do this if evaluates to zero equivalent } elsif ($test) { # do this if evaluates to non-zero equivalent }

      If you really wanted, you could throw in a $test eq '' in there too, but I've found that to be gratuitous code abuse.

Re: undef == 0?
by Argel (Prior) on Oct 24, 2007 at 22:16 UTC
    I have to agree that sometimes the warnings do not make a lot of sense to me. I think my "favorite" is "Use of uninitialized value in concatenation (.) or string" given how often I have seen it in places I didn't even think I was concatenating anything. Still, I always try and eliminate all of the warnings since it means I am either doing something I did not intend to do or perl is doing something I didn't expect. And in the latter case I get to learn more about the intricacies of the language and/or the interpreter. I am sad to see you got some negative votes on your post though because on the surface it does look puzzling.
Re: undef == 0?
by swampyankee (Parson) on Oct 25, 2007 at 00:13 UTC

    It actually makes perfect sense to me, in that undef and 0 both evaluate to "false" and "false" equals "false." I've programmed Fortran for many years (my first editor was an IBM-029 card punch 8=)); Fortran actually has a dedicated logical operators, .EQV. and .NEQV. to compare Boolean values. Part of the reason for this that some older Fortrans would do something like "x == y" (actually, X .EQ. Y) without any kind of cast: the compiler would just generate the instructions to compare the actual bit sequences. And Fortran's concept of "true" vs "false" can be a trifle confusing. Of course, one could now digress into why -0 != 0, but one shouldn't.


    emc

    Information about American English usage here and here.

    Any Northeastern US area jobs? I'm currently unemployed.

      1 and 2 are both true in boolean context so does that mean that 1 == 2?
        == forces scalar context. Both 1 and 2 are treated as decimal integers. Obviously they are not the same.

        print+qq(\L@{[ref\&@]}@{['@'x7^'!#2/"!4']});
        No, what it means is that is_true(1) == is_true(2), where is_true is something like sub { $_[0] ? 1 : 0 }

        It does mean that 1 && 2 evaluates to true. And, were Perl to have Fortran-style logical comparison operators (.EQV. and .NEQV.; this gives me an idea for an Acme module...), 1 eqv 2 would evaluate to true.

        Every language has its little corners which may not be that well thought out; undef& == 0 evaluating to true may be one of them (00 evaluating to 1 is probably another). It is consistent, and arguably reasonable, behavior, although it's just as sensible, and arguably more reasonable, to have undef behave like NaN and not be comparable to anything, even itself (NaN == NaN and NaN != NaN are both false in most languages).


        emc

        Information about American English usage here and here.

        Any Northeastern US area jobs? I'm currently unemployed.

Re: undef == 0?
by gamache (Friar) on Oct 24, 2007 at 16:26 UTC
    Perl's a dynamic-typed language. Magic lurks at every nook and cranny. This stuff comes with the territory.

    Is there a number you'd rather that undef be equal to?

      Perl's a weakly-typed language (almost untyped, really). Magic lurks at every nook and cranny. This stuff comes with the territory.

      Quite the opposite. This "issue" is a symptom of the the very strict requirements operators place on the type of their operands. == requires numbers, so Perl converted the undefined value to a number.

      Update: Added original content of parent node.

        Is it wrong that I wait wistfully for your corrections? The word I was looking for was "dynamic", not "weak"