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

snmpconf PM: Integer NaN?



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