[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: snmpconf PM: Integer NaN?



I think the following is the real issue:

    Is it better for the script to silently terminate if ToInteger()
    fails or should the script be given an error indication and
    allowed to continue? The only reason the NaN error indication
    exists is because the following code must not continue to run
    without some error indication:

      var x, y = "foo";

      x = 5 * y; // equivalent to x = 5 * ToInteger("foo")

    clearly there is no defined integer value appropriate for x
    because ToInteger("foo") is undefined.

    The only 2 choices are to terminate the script or to flag x and
    any offspring of x with an error indication. Both do the job,
    while the latter provides some flexibility in error
    recovery. Since data that comes from the network can have
    unexpected values, this flexibility may be valuable. For example,
    if we retrieve objects that are expected to contain
    decimal-encoded strings yet it unexpectantly contains a
    non-decimal value, we may want to do some error-recovery.

    On the other hand, the var data type would be simpler without the
    NaN error indication. If it isn't going to be valuable, we
    should remove it.

    BTW, for what it's worth, Perl silently converts non-decimal
    strings to zero, raising no error indication. We are trying to
    avoid this behavior by choosing one of these two solutions.

    If we decide we like the flexibility offered by continuing while
    raising a flag, the next question is should we call the extra
    value "NaN" or give it some other name? (e.g., "Error").


Pablo Halpern wrote:
> 
> All three of these constitute error conditions and should simply result in
> a run-time exception. Unlike floating point numbers, zero's don't happen
> "accidentally" in integer arithmetic as a result of lost precision. Thus,
> you should *never* have a divide-by-zero situation. Similarly, you should
> *never* attempt to convert a string to an integer unless you are sure it
> contains a syntactically valid integer. In both cases, the script writer is
> making an assumption about the inputs to an operation. If those assumptions
> (that the divisor is non-zero or that the string represents an integer)
> turn out to be wrong, the script should abort.

I think you have it wrong about why divide-by-zero terminates a C
program. The int data type contains no value that represents
infinity/NaN. Therefore, short of setting errno, the only option is to
abort the program. I don't think the analysis of "accidental" zero's
had any bearing on C's decision. Similarly, I don't think there is
any such rule that one should "*never* attempt to convert a string to
an integer ...". sscanf() certainly doesn't enforce such a rule.

> Scripting languages, unlike application languages should abort on a
> hair-trigger.

I'm not ready yet to accept this "hair-trigger doctrine".

> It can be very damaging for a script to continue running
> after something has gone wrong...

This would be true in Perl where you silently convert to zero. But
with an error indication, you can continue running with no correctness
issues. And if there were resources to clean up or state to restore,
it could be very damaging to *not* continue running. Of course, we
could use an IsValidInteger() function to bracket arithmetic code and
to call cleanup code. The question is "Which is best for the
programmer?" I don't yet know the right answer but it isn't as cut and
dried as you make it out to be.

Finally, the original message makes some claims that are false. After
considerable thought, I can assert the following
facts:

  Fact: This is the most straightforward translation of the ECMAScript
  var data type and its type conversion rules and there is no
  relevant inconsistency with C.
  Fact: This error value for integers won't interfere with future
  floating point whether we abstractly name it "NaN" or "Error" or
  "Foobar".

If we decide we want to keep using NaN, I'll go through the effort
to show why they are false (I'm deferring it now because it's tedious
and potentially avoidable if we decide that script termination is
better). These issues should not be considerations in deciding whether
termination or error indication is better for the programmer.

To sum up, I have no vested interest (or strong opinion) in the
outcome of the termination vs. error indication decision except to
make sure we analyze it thoroughly (I haven't yet) and give it a fair
hearing. Whatever conclusion we come to I want to come to it for the
right reason.


Steve


Pablo Halpern wrote:
> 
> One thing that troubles me greatly about the current draft of the Policy
> MIB is that the policy language introduces the notion of an integer NaN
> (not-a-number). In no other language have I seen NaN represent an integer
> value. Every place I have seen it NaN has been a floating-point value. The
> purpose for introducing NaN is very dubious to me and seems have come about
> through an uncritical cut-and-past of ECMAScript Number semantics.
> (ECMAScript Numbers are floats.)  In the future, it seems certain that
> floating point numbers will be added to the set of SNMP data types. At that
> time, the Policy language will probably be extended to including floating
> point types as well. Introducing NaN for integers now will confuse matters
> when true floating-point NaN is needed later.  Let me, then break the issue
> into two parts:
> 
> 1. Should we have NaN for integers?
> 2. If so, should it be called "NaN" or something else?
> 
> My opinion is that we should *not* have NaN for integers. One of our goals
> was to stick to existing language concepts was much as possible. The policy
> language is mostly C++ with a bit of ECMAScript (JavaScript) thrown in to
> make it better for scripting.  An integer NaN is not part of either C++ or
> ECMAScript.
> 
> In the draft as it currently is written, NaN is the result of one of the
> following:
> 
> 1. Divide by zero
> 2. Converting a string to an Integer when that string does not contain a
> syntactically valid integer.
> 3. Using the result of either of the above in a computation.
> 
> All three of these constitute error conditions and should simply result in
> a run-time exception. Unlike floating point numbers, zero's don't happen
> "accidentally" in integer arithmetic as a result of lost precision. Thus,
> you should *never* have a divide-by-zero situation. Similarly, you should
> *never* attempt to convert a string to an integer unless you are sure it
> contains a syntactically valid integer. In both cases, the script writer is
> making an assumption about the inputs to an operation. If those assumptions
> (that the divisor is non-zero or that the string represents an integer)
> turn out to be wrong, the script should abort.
> 
> Scripting languages, unlike application languages should abort on a
> hair-trigger. It can be very damaging for a script to continue running
> after something has gone wrong.  It could result in shutting down a bunch
> of interfaces or changing some other configuration parameter. The current
> definition uses integer NaN values to make scripts continue running after
> an error. I don't think that's a good idea.
> 
> One might argue that a poorly-formed string might come from MIB objects and
> that it is too harsh to terminate the script in those situations. I don't
> agree. If you use a string in an integer context, it is because you are
> certain that the string will always represent an integer. If you're
> mistaken, an exception is the most humane way of alerting you. Propagating
> an NaN through calculations just puts the system into a strange state and
> does not help get the script's job done. At best, the script will silently
> do nothing. At worse, it could damage your configuration. Besides, how
> often will you retrieve an integer from a string-valued MIB object?
> 
> My proposal:
> 
> - Eliminate NaN from the current PM.
> - Divide-by-zero causes a run-time exception and terminates the script.
> - If ToString fails, it causes a run-time exception and terminates the script.
> - Add an IsInteger() function that returns 1 if its argument is an integer
> or can be converted to an integer else returns 0.
> 
> P.S. If we decide to keep NaN, then let's at least rename it to "Error" or
> "IError" or something like that.  That way, it won't be confused with
> floating-point NaN.
> 
> - Pablo
> ---------------------------------------------------------------------
> Pablo Halpern                                    phalpern@newview.org
> http://www.halpernwightsoftware.com