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

Re: snmpconf PM: Integer NaN?



At 12:40 PM 3/14/2001 -0800, Steve Waldbusser wrote:
>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:

Who said anything about silent termination? A run-time exception (which is 
what I advocated) leaves an error trail, no?


>       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.

My point was that a) this should be rare, since most integers are encoded 
as integers, not strings and b) Tainting values doesn't help unless you 
check for tainted values (presumably by comparing to "NaN"). If you have 
reason to expect bad values, then test for them in advance and take 
"recovery" action as needed. If not, then your code will cause bad things 
to happen on bad values unless we terminate the program for you.

The IsInteger() function I propose would allow you to do error recovery (or 
prevention) without exposing a quick-and-dirty script to the possibility of 
spinning its wheels and destroying your configuration in the process. My 
expectation is that a lot of these scripts will be in the quick-and-dirty 
category. Personally, I'd rather not check for errors unless I believe they 
are likely. I'd rather the script abort by itself and tell me that I goofed.


>     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.

I think we should remove it.  By the way, I don't think an error indication 
of this sort is necessarily a bad idea for all languages. I just think it 
doesn't belong in our small Policy scripting language.


>     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.

I agree. Both solutions are better than silently converting to zero.


>     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").

I've already stated that I believe NaN is a bad name, even if we keep the 
general concept.



>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.

I said nothing about enforcement. The sscanf() function is an explicit 
conversion function. This is much less dangerous than the implicit 
conversions that occur in the Policy language. I thought about a way of 
modifying the Integer() function such that it could optionally return an 
error status rather than abort on error, but decided that an 
IsValidInteger() function would be simpler and less confusing.


> > 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

Perl is far from a prefect scripting language. Its rules for boolean 
expressions are also badly flawed and can cause scripts to misbehave. 
(Unfortunately, it would be hard to fix the boolean rules in Perl because 
of its typelessness.)

>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.

We need to make the decision for the most common cases. Any run-time 
exception has the same potential flaw.  Do we want to add an 
exception-catching mechanism?


>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".

Fact: The above are opinions. I disagree with both (especially the latter).


>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.

Agreed.

>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.

Agreed. You made some valid points, but my analysis still firmly points 
away from NaN.  I await your analysis and the analysis of others on this list.



>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


- Pablo
---------------------------------------------------------------------
Pablo Halpern                                    phalpern@newview.org
http://www.halpernwightsoftware.com