automatic number <-> string conversions

Discussion in 'Perl Misc' started by Rainer Weikusat, Sep 18, 2013.

  1. Coming to think of this, I'd agree that automatically converting a
    non-numerical string to a number with value zero is rarely useful and
    likely to lead to unpleasnt surprises, eg

    [rw@sable]/tmp#perl -e 'print "David" == "Nick", "\n"'
    1

    (although this could be referred to 'deeper insight')

    That's consistent with how atoi/ strtol would behave,

    -----------
    #include <stdlib.h>
    #include <stdio.h>

    int main(void)
    {
    printf("%d\n", atoi("Salad") == atoi("Steak"));
    return 0;
    }
    ----------

    but that's more likely to be an 1970s implemenetation shortcut than a
    conscious semantic choice and in any case, someone who knows Perl won't
    necessarily/ shouldn't need to know C as well.

    OTOH, I think the so-called 'undefined value', at least insofar it is
    used as default value of an uninitialized variable, should be an
    exception here: A variable with 'no value' should behave as if it had
    some 'neutral value' for the context it is used in: Explicit
    initialization should only be necessary when something other like than
    this 'neutral value' is needed. Forcing people to write

    my $a;
    $a = 0;
    print($a + 1);

    instead of

    my $a
    print($a + 1);

    just clutters the code with a lot of 'self-evident' statements.
     
    Rainer Weikusat, Sep 18, 2013
    #1
    1. Advertising

  2. Rainer Weikusat <> writes:

    [...]

    > [rw@sable]/tmp#perl -e 'print "David" == "Nick", "\n"'
    > 1
    >
    > (although this could be referred to 'deeper insight')


    Silly joke I can resist ATM: This works even nicer in German because
    "beides Nullen" (both zeroes) is colloquial for "guys who can't get
    anything done because it is beyond them" :->
     
    Rainer Weikusat, Sep 18, 2013
    #2
    1. Advertising

  3. On 9/18/2013 2:51 AM, Rainer Weikusat wrote:
    > Rainer Weikusat <> writes:
    >
    > [...]
    >
    >> [rw@sable]/tmp#perl -e 'print "David" == "Nick", "\n"'
    >> 1
    >>
    >> (although this could be referred to 'deeper insight')

    >
    > Silly joke I can resist ATM: This works even nicer in German because
    > "beides Nullen" (both zeroes) is colloquial for "guys who can't get
    > anything done because it is beyond them" :->
    >


    At least perl warns when "beides Nullen" is "beyond the pale":

    perl -wE 'print "David" == "Nick"'
    Argument "Nick" isn't numeric in numeric eq (==) at -e line 1.
    ....


    --
    Charles DeRykus
     
    Charles DeRykus, Sep 18, 2013
    #3
  4. On 9/18/2013 9:55 AM, Ben Morrow wrote:
    >
    > Quoth Rainer Weikusat <>:
    > ...
    >>
    >> but that's more likely to be an 1970s implemenetation shortcut than a
    >> conscious semantic choice and in any case, someone who knows Perl won't
    >> necessarily/ shouldn't need to know C as well.

    >
    > atoi has no choice: it has to return some int or other to signal
    > 'invalid input', and it's obviously going to return the same one for
    > different invalid inputs. Since int doesn't have a NaN value, the return
    > values are going to be equal.
    >
    >> OTOH, I think the so-called 'undefined value', at least insofar it is
    >> used as default value of an uninitialized variable, should be an
    >> exception here: A variable with 'no value' should behave as if it had
    >> some 'neutral value' for the context it is used in: Explicit
    >> initialization should only be necessary when something other like than
    >> this 'neutral value' is needed.

    >
    > I agree. Uninit value warnings were much more useful in the pre-strict
    > days when an unexpected undef often meant you had autocreated a variable
    > without meaning to. These days "uninitiailisized" is the warning
    > category I turn off most often (the next is probably "exiting").
    >


    But, IIUC, I'm not sure how Perl could thread the twisty-turny maze to
    warn sanely but not annoyingly.

    Sensibly in lvalue settings, it doesn't: 'my $x; say ++$x;'
    or: 'my $x; $x .= "foo";

    But, most of the time, it seems to me there's more likely a need for a
    warning than not, eg,

    'my $x; my $y = "Alice hates $x...and the Red Queen;"

    If there were no warning because "nothing other than its neutral value
    is needed for the context it is used in", it'd fail to alert the author
    to expressions that had changed in havoc-wreaking ways computationally
    (or semantically).

    --
    Charles DeRykus
     
    Charles DeRykus, Sep 18, 2013
    #4
  5. Charles DeRykus <> writes:
    > On 9/18/2013 9:55 AM, Ben Morrow wrote:
    >> Quoth Rainer Weikusat <>:


    [...]

    >>> OTOH, I think the so-called 'undefined value', at least insofar it is
    >>> used as default value of an uninitialized variable, should be an
    >>> exception here: A variable with 'no value' should behave as if it had
    >>> some 'neutral value' for the context it is used in: Explicit
    >>> initialization should only be necessary when something other like than
    >>> this 'neutral value' is needed.

    >>
    >> I agree. Uninit value warnings were much more useful in the pre-strict
    >> days when an unexpected undef often meant you had autocreated a variable
    >> without meaning to. These days "uninitiailisized" is the warning
    >> category I turn off most often (the next is probably "exiting").
    >>

    >
    > But, IIUC, I'm not sure how Perl could thread the twisty-turny maze to
    > warn sanely but not annoyingly.
    >
    > Sensibly in lvalue settings, it doesn't: 'my $x; say ++$x;'
    > or: 'my $x; $x .= "foo";
    >
    > But, most of the time, it seems to me there's more likely a need for a
    > warning than not, eg,
    >
    > 'my $x; my $y = "Alice hates $x...and the Red Queen;"
    >
    > If there were no warning because "nothing other than its neutral value
    > is needed for the context it is used in", it'd fail to alert the
    > author to expressions that had changed in havoc-wreaking ways
    > computationally (or semantically).


    Simple. Warn if a string without leading digits is implicitly converted
    to a 0. Don't warn if 'an undefined value' is used as if somebody
    thought he wasn't accessing some a C 'stack-allocated object' which was
    left unitialized for performance reason because that's totally
    ridicolous for perl, anyway, and not true. Not everything which has
    always worked in this way since 1973 for reasons we've long stopped to
    care about has to continue to work in this way. That's going to be a
    good idea in certain cases and a bad idea in certain other cases and
    *for me*, the benefits outweigh the drawbacks.
     
    Rainer Weikusat, Sep 19, 2013
    #5
  6. On 9/18/2013 6:00 PM, Ben Morrow wrote:
    >
    > Quoth Charles DeRykus <>:
    >> On 9/18/2013 9:55 AM, Ben Morrow wrote:

    ....

    >
    > IMHO with properly scoped variables an undef is no more likely to be a
    > mistake than any other value. IME undef warnings cause more problems (in
    > terms of unnecessary code to work around them) than they solve. A simple
    > example would be something like this:
    >
    > my $verb = $conf{verbose} + $ENV{FOO_VERBOSE} + $opt{v};
    >
    > where silently treating a nonexistent setting as 0 is the right thing to
    > do. With undef warnings turned on that line of code has to become a good
    > bit more complex, to no real advantage.


    Maybe it's a personal bias bordering on an OCD affliction, but I'd
    rather see that as: my $verb = ... + ($ENV{FOO_VERBOSE} // 0) + ...

    IMO not appallingly tedious and documenting clearly what's going on.

    >
    >> Sensibly in lvalue settings, it doesn't: 'my $x; say ++$x;'
    >> or: 'my $x; $x .= "foo";
    >>
    >> But, most of the time, it seems to me there's more likely a need for a
    >> warning than not, eg,
    >>
    >> 'my $x; my $y = "Alice hates $x...and the Red Queen;"
    >>
    >> If there were no warning because "nothing other than its neutral value
    >> is needed for the context it is used in", it'd fail to alert the author
    >> to expressions that had changed in havoc-wreaking ways computationally
    >> (or semantically).

    >
    > In that particular case an empty string makes no more sense than an
    > undef, but an empty string won't warn. In the general case, there are a
    > great many possible wrong values in any given situation, and undef is no
    > more likely to be one of them than anything else.
    >


    Right. But, IMO, particularly in early development, you're more likely
    to forget to initialize and -w can really help. Then you graduate to
    more refined types of mayhem and no one can help you.

    --
    Charles DeRykus
     
    Charles DeRykus, Sep 19, 2013
    #6
  7. On 2013-09-19 01:00, Ben Morrow <> wrote:
    >
    > Quoth Charles DeRykus <>:
    >> On 9/18/2013 9:55 AM, Ben Morrow wrote:
    >> >
    >> > I agree. Uninit value warnings were much more useful in the pre-strict
    >> > days when an unexpected undef often meant you had autocreated a variable
    >> > without meaning to. These days "uninitiailisized" is the warning
    >> > category I turn off most often (the next is probably "exiting").

    >>
    >> But, IIUC, I'm not sure how Perl could thread the twisty-turny maze to
    >> warn sanely but not annoyingly.

    >
    > IMHO with properly scoped variables an undef is no more likely to be a
    > mistake than any other value.


    I disagree with that estimation. Undef is much more likely to be a
    mistake than any other value because it *means* "no value". So when I
    expect a numerical value, 23 may or may not be a mistake, but undef is
    certain to be one - because I expect a numerical value and undef isn't
    that.

    Of course that depends on your coding style. If you treat undef like 0
    or an empty string, the warning is just annoying and not helpful at all.
    But the way I code, an undef in a place where I didn't expect it almost
    always means that there is an error in my logic.

    That said, uninitialized is also the warning category I turn off most
    often (and I probably mistype it just as often as you ;-)), although
    usually in a very tight scope and often around debug output.

    Especially for debug output a way to replace it with something else than
    "" would be handy, for example something like this:


    my $foo = "bla";
    my $bar;
    {
    local $^@ = "(undef)";
    say "foo=$foo bar=$bar"
    }

    could print

    foo=bla bar=(undef)



    > IME undef warnings cause more problems (in
    > terms of unnecessary code to work around them) than they solve. A simple
    > example would be something like this:
    >
    > my $verb = $conf{verbose} + $ENV{FOO_VERBOSE} + $opt{v};


    I think I would write that as

    my $verb = $conf{verbose} // $ENV{FOO_VERBOSE} // $opt{v};

    (or probably the other way around).

    hp


    --
    _ | Peter J. Holzer | Fluch der elektronischen Textverarbeitung:
    |_|_) | | Man feilt solange an seinen Text um, bis
    | | | | die Satzbestandteile des Satzes nicht mehr
    __/ | http://www.hjp.at/ | zusammenpaƟt. -- Ralph Babel
     
    Peter J. Holzer, Sep 19, 2013
    #7
  8. "Peter J. Holzer" <> writes:
    > On 2013-09-19 01:00, Ben Morrow <> wrote:
    >>
    >> Quoth Charles DeRykus <>:
    >>> On 9/18/2013 9:55 AM, Ben Morrow wrote:
    >>> >
    >>> > I agree. Uninit value warnings were much more useful in the pre-strict
    >>> > days when an unexpected undef often meant you had autocreated a variable
    >>> > without meaning to. These days "uninitiailisized" is the warning
    >>> > category I turn off most often (the next is probably "exiting").
    >>>
    >>> But, IIUC, I'm not sure how Perl could thread the twisty-turny maze to
    >>> warn sanely but not annoyingly.

    >>
    >> IMHO with properly scoped variables an undef is no more likely to be a
    >> mistake than any other value.

    >
    > I disagree with that estimation. Undef is much more likely to be a
    > mistake than any other value because it *means* "no value".


    [...]

    > Of course that depends on your coding style. If you treat undef like 0
    > or an empty string, the warning is just annoying and not helpful at
    > all.


    If someone treats Perl like C (or C++ or Java, FWIW) with respect to not
    otherwise initialized my variables, that is, assigning values to them
    even although automatic conversion of 'undef' to a suitable type would
    result in the same value, then, 'undef' being used instead of some
    'defined value' should rarely[*] ever happen. But Perl isn't C and it
    doesn't suffer from the 'bad habit' of making storage locations
    available to code while leaking whatever value the most recent user of
    this storage location happened to leave there: Variables created with my
    are not uninitialized and I consider the fact that they will 'behave
    themselves' according to the ways they're used in a feature (and a very
    convenient one at that).

    [*] There's still the issue that some builtin functions return undef as
    'false value' and that using 0 and 1 in order to mean 'true' and 'false'
    can be convenient because it is possible to do ordinary arithmetic with
    'boolean values', eg (contrived example)

    my $results;

    $result = call_a();
    $result |= call_b();
    $result |= call_c();
    print("Something worked!\n") if $result;
     
    Rainer Weikusat, Sep 19, 2013
    #8
  9. Charles DeRykus <> writes:
    > On 9/18/2013 6:00 PM, Ben Morrow wrote:
    >>
    >> Quoth Charles DeRykus <>:
    >>> On 9/18/2013 9:55 AM, Ben Morrow wrote:

    > ...
    >
    >>
    >> IMHO with properly scoped variables an undef is no more likely to be a
    >> mistake than any other value. IME undef warnings cause more problems (in
    >> terms of unnecessary code to work around them) than they solve. A simple
    >> example would be something like this:
    >>
    >> my $verb = $conf{verbose} + $ENV{FOO_VERBOSE} + $opt{v};
    >>
    >> where silently treating a nonexistent setting as 0 is the right thing to
    >> do. With undef warnings turned on that line of code has to become a good
    >> bit more complex, to no real advantage.

    >
    > Maybe it's a personal bias bordering on an OCD affliction, but I'd
    > rather see that as: my $verb = ... + ($ENV{FOO_VERBOSE} // 0) + ...
    >
    > IMO not appallingly tedious and documenting clearly what's going on.


    This would in itself warrant some 'clear documentation' a la

    # silence 'undefined value' warnings

    because on its own, it's just apparently useless code.
     
    Rainer Weikusat, Sep 19, 2013
    #9
  10. On 9/19/2013 9:55 AM, Rainer Weikusat wrote:
    > ...
    >>
    >> Maybe it's a personal bias bordering on an OCD affliction, but I'd
    >> rather see that as: my $verb = ... + ($ENV{FOO_VERBOSE} // 0) + ...
    >>
    >> IMO not appallingly tedious and documenting clearly what's going on.

    >
    > This would in itself warrant some 'clear documentation' a la
    >
    > # silence 'undefined value' warnings
    >
    > because on its own, it's just apparently useless code.
    >


    If someone knows it's "useless code", I will wager he/she knows well
    the dark kingdom of "uninitialized value". (if not, then some lessons
    need to be experienced and having been so, you will not want to comment
    on such things ever again :)

    --
    Charles DeRykus
     
    Charles DeRykus, Sep 19, 2013
    #10
  11. Ben Morrow <> writes:
    > Quoth Rainer Weikusat <>:
    >>

    > [undef warnings]


    [...]

    >> Don't warn if 'an undefined value' is used as if somebody
    >> thought he wasn't accessing some a C 'stack-allocated object' which was
    >> left unitialized for performance reason because that's totally
    >> ridicolous for perl, anyway, and not true.

    >
    > I'm pretty certain that wasn't the reason. The warning was added in perl
    > 2 (and goodness me, perl was a lot simpler in those days!); the only
    > comments about it still preserved in the perl repo are this paragraph in
    > the manpage:
    >
    > .B \-w
    > prints warnings about identifiers that are mentioned only once, and
    > scalar variables that are used before being set.
    > Also warns about redefined subroutines, and references to undefined
    > subroutines and filehandles.
    >
    > and this comment from the git commit message for perl-2.0, which I
    > believe was taken from a release announcement of some sort:
    >
    > * Warnings are now available (with -w) on use of uninitialized
    > variables and on identifiers that are mentioned only once, and on
    > reference to various undefined things.
    >
    > Both of these (and the fact that the message is about an 'uninitialized'
    > rather than an 'undefined' value) lead me to believe that the intention
    > was to catch variables created by mistake (through typos and such)
    > rather than because of any illusions about Perl behaving like C.


    'Variables created by mistake' should be caught by the '... used only
    once: possible typo at line ...' check and 'strict vars' is IMHO a
    better way to guard against that because 'systematic' typos (repeated
    identical misspellings) are not uncommon. It is conceivable that the
    undef check was meant to be a supplement to the other. OTOH, I consider
    it completely probable that this was just another someone with a
    automatic "****! That's a PROBLEM!" reaction, especially considering
    that 'uninitialized variables' can cause really nasty runtime problems
    in C, eg, write accesses through pointer which aren't really dangling
    because they point to something completely different than what a naive
    observer would assume.
     
    Rainer Weikusat, Sep 20, 2013
    #11
  12. Charles DeRykus <> writes:
    > On 9/19/2013 9:55 AM, Rainer Weikusat wrote:
    >> ...
    >>>
    >>> Maybe it's a personal bias bordering on an OCD affliction, but I'd
    >>> rather see that as: my $verb = ... + ($ENV{FOO_VERBOSE} // 0) + ...
    >>>
    >>> IMO not appallingly tedious and documenting clearly what's going on.

    >>
    >> This would in itself warrant some 'clear documentation' a la
    >>
    >> # silence 'undefined value' warnings
    >>
    >> because on its own, it's just apparently useless code.
    >>

    >
    > If someone knows it's "useless code", I will wager he/she knows well
    > the dark kingdom of "uninitialized value". (if not, then some
    > lessons need to be experienced and having been so, you will not want
    > to comment on such things ever again :)


    Which "dark kingdom"? Assuming the following toy program for testing the
    perl PRNG,

    ------------
    use warnings;
    use constant WANT => 5;

    my ($got, $needed);

    do {
    ++$needed;
    ++$got if int(rand(100)) >= 89;
    } while ($got < WANT);

    print("needed $needed\n");
    ------------

    there's a (pseudo-)random chance that this will print a (pseudo-)random
    number of warnings in addition to the actual output. What's that
    supposed to be so good for that it would excuse any of the possible
    contortions which could be used to hack around that?

    What's the precise logic behind something like this:

    [rw@sable]/tmp#perl -we '$c = $c + 1; ++$d;'
    Name "main::d" used only once: possible typo at -e line 1.
    Use of uninitialized value $c in addition (+) at -e line 1.

    "It is fine to use $c because 'the more, the merrier' but not as operand
    in an addition whose value is assigned back to $c, however, while using
    a single $d sure seems fishy, performing the exact same operation using
    a traditional, syntactical shortcut on that is perfectly ok"?
     
    Rainer Weikusat, Sep 20, 2013
    #12
  13. On 9/20/2013 7:09 AM, Rainer Weikusat wrote:
    > Charles DeRykus <> writes:
    >> On 9/19/2013 9:55 AM, Rainer Weikusat wrote:
    >>> ...
    >>>>
    >>>> Maybe it's a personal bias bordering on an OCD affliction, but I'd
    >>>> rather see that as: my $verb = ... + ($ENV{FOO_VERBOSE} // 0) + ...
    >>>>
    >>>> IMO not appallingly tedious and documenting clearly what's going on.
    >>>
    >>> This would in itself warrant some 'clear documentation' a la
    >>>
    >>> # silence 'undefined value' warnings
    >>>
    >>> because on its own, it's just apparently useless code.
    >>>

    >>
    >> If someone knows it's "useless code", I will wager he/she knows well
    >> the dark kingdom of "uninitialized value". (if not, then some
    >> lessons need to be experienced and having been so, you will not want
    >> to comment on such things ever again :)

    >
    > Which "dark kingdom"? Assuming the following toy program for testing the
    > perl PRNG,
    >
    > ...

    ]

    > What's the precise logic behind something like this:
    >
    > [rw@sable]/tmp#perl -we '$c = $c + 1; ++$d;'
    > Name "main::d" used only once: possible typo at -e line 1.
    > Use of uninitialized value $c in addition (+) at -e line 1.
    >
    > "It is fine to use $c because 'the more, the merrier' but not as operand
    > in an addition whose value is assigned back to $c, however, while using
    > a single $d sure seems fishy, performing the exact same operation using
    > a traditional, syntactical shortcut on that is perfectly ok"?
    >


    Yes, it sorta makes "sense". The ++$d draws an lvalue exemption from
    "uninitialized value" but then perl agrees a single mention is fishy.
    However $c=$c+1 is too complex to equate to a simple preinc so it draws
    the "uninitialized" warning would be my guess.

    --
    Charles DeRykus
     
    Charles DeRykus, Sep 21, 2013
    #13
  14. Charles DeRykus <> writes:
    > On 9/20/2013 7:09 AM, Rainer Weikusat wrote:


    [...]

    >> What's the precise logic behind something like this:
    >>
    >> [rw@sable]/tmp#perl -we '$c = $c + 1; ++$d;'
    >> Name "main::d" used only once: possible typo at -e line 1.
    >> Use of uninitialized value $c in addition (+) at -e line 1.
    >>
    >> "It is fine to use $c because 'the more, the merrier' but not as operand
    >> in an addition whose value is assigned back to $c, however, while using
    >> a single $d sure seems fishy, performing the exact same operation using
    >> a traditional, syntactical shortcut on that is perfectly ok"?
    >>

    >
    > Yes, it sorta makes "sense". The ++$d draws an lvalue exemption from
    > "uninitialized value" but then perl agrees a single mention is
    > fishy. However $c=$c+1 is too complex to equate to a simple preinc so
    > it draws the "uninitialized" warning would be my guess.


    "Code does $something" doesn't imply "$something is sensible". Wrt to
    'uninitialized values' in expressions, there are basically three
    choices:

    - compile-time error
    - runtime error
    - define a meaning for that

    'Define a meaning for that but then emit an optional runtime warning
    except in case of the following expressions ..., ..., ...' [perfectly
    arbitrary collection of stuff which ocurred in code written by the
    person who designed/ implemented the warning] is IMHO just a bizarre
    inconsistency, sort-of "do a little bit of everything", that is,
    don't really do anything, but muddy the waters enough to hide that.
     
    Rainer Weikusat, Sep 22, 2013
    #14
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Guest
    Replies:
    1
    Views:
    770
    Guest
    Jun 29, 2004
  2. Replies:
    10
    Views:
    708
    Jasen Betts
    Aug 5, 2005
  3. Bill Wayne

    fstream and number conversions

    Bill Wayne, Apr 5, 2006, in forum: C++
    Replies:
    2
    Views:
    316
    Daniel T.
    Apr 6, 2006
  4. vdicarlo
    Replies:
    7
    Views:
    288
    Terry Reedy
    Jun 9, 2007
  5. Aaron

    Automatic type conversions

    Aaron, Apr 1, 2004, in forum: Javascript
    Replies:
    1
    Views:
    93
    Michael Winter
    Apr 1, 2004
Loading...

Share This Page