## NAN revisited, a crossover from old to new.

### NAN revisited, a crossover from old to new.

I posted the following on the old forun last night. Now I have figuring out case sensitivity problem I was haveing with loging in here. I will repeat myself here in the New forum.

Here we go on an adventure in NAN :)

Fresh Start:

newLISP v6.5.23-win32 Copyright (c) 1993-2002 Lutz Mueller. All rights reserved

> (set '+NAN (sqrt -1))

sqrt: DOMAIN error

+NAN

> (NaN? +NAN)

true

> (set 'X +NAN)

+NAN

> (NaN? X)

true

> (save "loadtest.lsp")

true

LoadTest contains:

(set '+NAN +NAN)

(set 'X +NAN)

Fresh Start:

newLISP v6.5.23-win32 Copyright (c) 1993-2002 Lutz Mueller. All rights reserved.

> (load "test")

true

> (symbols)

(! != % & * + +NAN - / < << <= = > >= >> ? MAIN NaN? X ^ abs ...... | ~)

> +NAN

nil

> (NaN? +NAN)

Value expected in function NaN?

> X

nil

> (NaN? X)

Value expected in function NaN?

>

Edit LoadTest file:

;(set '+NAN +NAN) Don't mess with +NAN !

(set 'X +NAN)

Fresh Start:

newLISP v6.5.23-win32 Copyright (c) 1993-2002 Lutz Mueller. All rights reserved

> (set '+NAN (sqrt -1))

sqrt: DOMAIN error

+NAN

> (NaN? +NAN)

true

> (load "loadtest.lsp")

true

> (NaN? X)

true

>

If +NAN was a constant, then its inference

could be carried between states using (save)(load)

without having to force an seemingly untrapable error to generating one.

> (catch (set '+NAN (sqrt -1)) 'result)

sqrt: DOMAIN error

true

>

How can I generate a +NaN that I can test for with NAN?

without fireing off the error handler ?

Why you ask?

I am using the +NAN as a place holding excluder.

The Current Doc states:

syntax: (NaN? number )

Tests if the result of floating point math operation is a NaN.

Certain floating point operations return a special IEE 754 number

format called a NaN for 'Not a Number'.

example:

(set 'x (sqrt -1) => NaN

(add x 123) => NaN

(> x 0) => nil

(<= x 0) => nil

(= x x) => nil

(NaN? x) => true

Note that all floating point arithmetik operations with a NaN will

yield a NaN. All comparisons with NaN will return nil,

even if comparing NaN to itself.

While we are on the subject of the fact that "Certain floating point operations

return a special IEE 754 number format"

How about Pi ? Having access to the constant for Pi would be great !!!

A test (Pi? number ) would be very nice also. Problem is people trying

(Pi? 3.1416)

Final Note: a (div 1 0) should return a +NAN and not return to the OS !

Thanks, now I feel better :)

Keep up the good work.

Thanks

(bob)

bob@bradlee.org

Here we go on an adventure in NAN :)

Fresh Start:

newLISP v6.5.23-win32 Copyright (c) 1993-2002 Lutz Mueller. All rights reserved

> (set '+NAN (sqrt -1))

sqrt: DOMAIN error

+NAN

> (NaN? +NAN)

true

> (set 'X +NAN)

+NAN

> (NaN? X)

true

> (save "loadtest.lsp")

true

LoadTest contains:

(set '+NAN +NAN)

(set 'X +NAN)

Fresh Start:

newLISP v6.5.23-win32 Copyright (c) 1993-2002 Lutz Mueller. All rights reserved.

> (load "test")

true

> (symbols)

(! != % & * + +NAN - / < << <= = > >= >> ? MAIN NaN? X ^ abs ...... | ~)

> +NAN

nil

> (NaN? +NAN)

Value expected in function NaN?

> X

nil

> (NaN? X)

Value expected in function NaN?

>

Edit LoadTest file:

;(set '+NAN +NAN) Don't mess with +NAN !

(set 'X +NAN)

Fresh Start:

newLISP v6.5.23-win32 Copyright (c) 1993-2002 Lutz Mueller. All rights reserved

> (set '+NAN (sqrt -1))

sqrt: DOMAIN error

+NAN

> (NaN? +NAN)

true

> (load "loadtest.lsp")

true

> (NaN? X)

true

>

If +NAN was a constant, then its inference

could be carried between states using (save)(load)

without having to force an seemingly untrapable error to generating one.

> (catch (set '+NAN (sqrt -1)) 'result)

sqrt: DOMAIN error

true

>

How can I generate a +NaN that I can test for with NAN?

without fireing off the error handler ?

Why you ask?

I am using the +NAN as a place holding excluder.

The Current Doc states:

syntax: (NaN? number )

Tests if the result of floating point math operation is a NaN.

Certain floating point operations return a special IEE 754 number

format called a NaN for 'Not a Number'.

example:

(set 'x (sqrt -1) => NaN

(add x 123) => NaN

(> x 0) => nil

(<= x 0) => nil

(= x x) => nil

(NaN? x) => true

Note that all floating point arithmetik operations with a NaN will

yield a NaN. All comparisons with NaN will return nil,

even if comparing NaN to itself.

While we are on the subject of the fact that "Certain floating point operations

return a special IEE 754 number format"

How about Pi ? Having access to the constant for Pi would be great !!!

A test (Pi? number ) would be very nice also. Problem is people trying

(Pi? 3.1416)

Final Note: a (div 1 0) should return a +NAN and not return to the OS !

Thanks, now I feel better :)

Keep up the good work.

Thanks

(bob)

bob@bradlee.org

Bob the Caveguy aka Lord High Fixer.

NaN is not a specific value of something, but rather a concept flagging a result as no computable.

+NaN is just a new symbol you created and has the value nil. The parser takes the '+' and ' -' minus characters only as number prefixes when followed by a number, else a space must be present. NaN is "Not a Number".

Lutz

### My Last Justification for +NaN

In my example +NAN is in fact just a symbol like any other symbol, only it has been (set) to a NaN, the return value generated by the sqrt: DOMAIN error.

I use '+NAN as a reference symbol to the actual NaN in memory.

I can just as easily refer to it as 'X.

In fact +NAN does in have a value. It is not a string, handle, structure, integer ... it is a non-numeric value whose binary pattern represent the results of an invalid operation some where in the floating point specification.

By ignoring NaNs a stack based numeric processor like the 8087 could ignore intermediate calculations that resulted from previous errors.

I understand that it can only be tested for by using

(NaN?) that is to be expected. The fact that I can

bind a symbol to an NaN once it existence proves the

argument for assignability.

> (set '+NAN (sqrt -1))

sqrt: DOMAIN error ;<---- this is my nemeses

+NAN ; give be a way to catch this error

> (NaN? +NAN) ; and I will go away for a while :)

true

> (set 'X +NAN)

+NAN

> (NaN? X)

true

>

We all use nil as a third state -1 0 1 True False Nil(unknown).

We use (list?) and Nil to represent knowledge or lack of it.

NaNs can be thought of as a mathematical nil.

The reason we have NaNs is to avoid floating point errors when dealing

with unknown values that resulted from previous operations.

We can use +NaN to replace all occurrence of 0.0 in a list to avoid a dreaded divide by zero error.

-0.999 +NAN +0.999 works very nicely in situations where a floating point error or (div x 0.0) will take the system down.

The use of NaN as a data type dates back to the first MASM and PL/M code that accessed the 8087 when Intel introduced it. At the time some said that existence of the NaN would eliminate all divide by zero exceptions in the future, it was the 80's and we had it all figured out, back then :)

Somewhere along the line the NaN became a secret weapon. Most software that exploited NaNs were/are locked deep in NDAs hiding both National and Industrial secrets and the NaN fell from grace. NaN logic is a 900 series topic that is seldom taught because for the most part it's use has been limited to stack based numerical recursion.

Base constants: true false nil NaN and mabe Pi.

Pi is righ next to NaN in the math co-processor and

is at the root of all polar mapping.

Back to my Rat Killen...

I use '+NAN as a reference symbol to the actual NaN in memory.

I can just as easily refer to it as 'X.

In fact +NAN does in have a value. It is not a string, handle, structure, integer ... it is a non-numeric value whose binary pattern represent the results of an invalid operation some where in the floating point specification.

By ignoring NaNs a stack based numeric processor like the 8087 could ignore intermediate calculations that resulted from previous errors.

I understand that it can only be tested for by using

(NaN?) that is to be expected. The fact that I can

bind a symbol to an NaN once it existence proves the

argument for assignability.

> (set '+NAN (sqrt -1))

sqrt: DOMAIN error ;<---- this is my nemeses

+NAN ; give be a way to catch this error

> (NaN? +NAN) ; and I will go away for a while :)

true

> (set 'X +NAN)

+NAN

> (NaN? X)

true

>

We all use nil as a third state -1 0 1 True False Nil(unknown).

We use (list?) and Nil to represent knowledge or lack of it.

NaNs can be thought of as a mathematical nil.

The reason we have NaNs is to avoid floating point errors when dealing

with unknown values that resulted from previous operations.

We can use +NaN to replace all occurrence of 0.0 in a list to avoid a dreaded divide by zero error.

-0.999 +NAN +0.999 works very nicely in situations where a floating point error or (div x 0.0) will take the system down.

The use of NaN as a data type dates back to the first MASM and PL/M code that accessed the 8087 when Intel introduced it. At the time some said that existence of the NaN would eliminate all divide by zero exceptions in the future, it was the 80's and we had it all figured out, back then :)

Somewhere along the line the NaN became a secret weapon. Most software that exploited NaNs were/are locked deep in NDAs hiding both National and Industrial secrets and the NaN fell from grace. NaN logic is a 900 series topic that is seldom taught because for the most part it's use has been limited to stack based numerical recursion.

Base constants: true false nil NaN and mabe Pi.

Pi is righ next to NaN in the math co-processor and

is at the root of all polar mapping.

Back to my Rat Killen...

Bob the Caveguy aka Lord High Fixer.

(div 1 0) => Inf ;; hangs the Win32 version

is broken on the Win32 version. When compiled with GCC under Cygwin or Linux is gives you: 'Inf'

This 'Inf' behaves a little bit different than NaN, more like a number :) so:

(set 'x (div 1 0)) => Inf

(set 'y (div 1 0)) => Inf

(= x y) => true

but ?!?:

(+ x 1 ) => 1

But Inf is a total different animal, and at this moment I am just returning to the user, whatever the GCC libraries give me back. And as mentioned, it is broken on the Win32 version and I am not sure at this moment what we can or should do about it. Also just like with NaN 'Inf' is not a newLISP symbol, but unlike NaN, which you have to test using the NaN? newLISP function, you can test for 'Inf' using the equality operator.

But back to NaN. As you describe in your posting all arithmetik operations on NaN result in NaN and all comparisonas in 'nil' (which is also newLISP's false). I modeled this after Java's behavior, which is supposed to be pretty IEEE conformant when comes to floating point crazyness.

The message "sqrt: DOMAIN error", your are observing comes from the BORLAND C++ libraries, and is not present when compiled with GCC under Cygwin or Linux. This is why 'catch' will not work for you, because newLISP didn't observe any error.

There is surfacing all kinds of stuff over time since we have a native Win32 version of newLISP again. I.e. the 'date' function crashes with small values and sockets don't work with functions taking file handles. If you can, compile newLISP under Cygwin when on Windows and you will have more consistent behaviour to newLISP compiled inder UNIXes (UNICES).

About Pi. I just use:

(set 'Pi (mul (acos 0) 2)) => 3.41592564

at the beginning of a program, where I use Pi a lot. Interesting detail, you are mentioning, that Pi is burried in the math coprocessor, I didn't know that and guess it makes a lot of sence to build it into it.

Anyway, very welcome to our group of newLISP fans ...

Lutz

### +NAN

Pi is stored as an 80 bit float in the co-processor as a

constant. Your solution returns a 64 bit float If we stay in this solar system then polar error is not too bad :) Just Kidding.

I only need a symbol that has been set to +NAN to still

be a NAN after a save and load.

(save) saves it out as (set 'x +NaN)

(load) (sets 'x nil)

Makeing +NaN a static symbol pointing to a static NaN

would allow it to be restored.

Till later ...

Bob

constant. Your solution returns a 64 bit float If we stay in this solar system then polar error is not too bad :) Just Kidding.

I only need a symbol that has been set to +NAN to still

be a NAN after a save and load.

(save) saves it out as (set 'x +NaN)

(load) (sets 'x nil)

Makeing +NaN a static symbol pointing to a static NaN

would allow it to be restored.

Till later ...

Bob

Bob the Caveguy aka Lord High Fixer.

http://newlisp.org/download/development/

and the CHANGES file in the distribution

Lutz

### +NAN as a constant

newLISP v6.5.26-win32 Copyright (c) 1993-2002 Lutz Mueller. All rights reserved.

> (symbols) => no observed +NAN on the heap

> +NAN => nil

> (NaN? +NAN) => Value expected in function NaN?

; Now I force one into exsistance

> (set '+NAN (sqrt -1)) => sqrt: DOMAIN error returns: +NAN

(symbols) => wa-la we got +NAN on the heap

; now there will be joy in mudville

> +NAN => +NAN

> (set 'q +NAN) => +NAN

> (NaN? q) => true

>

Like nil there should be only one value for +NAN

and all symbols point to it. If you save a +NAN a maie it constant, then the error does not have to occure to generate the first +NAN value to link to.

Close, real close, once "created" the new +NAN responds nicely.

Other than that, It looks great, thanks for the div by zero fix for winblows. Having forceing a +NaN as 0

in integer operations works for me nicely. I may start using it for Integer Values to be Ignored in a sequence :)

Till later ...

> (symbols) => no observed +NAN on the heap

> +NAN => nil

> (NaN? +NAN) => Value expected in function NaN?

; Now I force one into exsistance

> (set '+NAN (sqrt -1)) => sqrt: DOMAIN error returns: +NAN

(symbols) => wa-la we got +NAN on the heap

; now there will be joy in mudville

> +NAN => +NAN

> (set 'q +NAN) => +NAN

> (NaN? q) => true

>

Like nil there should be only one value for +NAN

and all symbols point to it. If you save a +NAN a maie it constant, then the error does not have to occure to generate the first +NAN value to link to.

Close, real close, once "created" the new +NAN responds nicely.

Other than that, It looks great, thanks for the div by zero fix for winblows. Having forceing a +NaN as 0

in integer operations works for me nicely. I may start using it for Integer Values to be Ignored in a sequence :)

Till later ...

Bob the Caveguy aka Lord High Fixer.

Perhaps we will have some protection mechanism in the future or we could simply have a 'constant' primitive:

(constant '+NaN (sqrt -1))

(constant 'Pi (mul 2 (acos 0)))

etc.

Lutz

### How about

How about a new subber (+NaN) that performs a (sqrt -1) function internally and returns +NAN without the error.

The error is the only real problem, now.

I have not tried it as a CGI yet but I am sure it will go boom when I do ... I will give it a test late tonight.

I dont care about Pi it is easily worked around. But the

error is un-trapable.

Got to run...

The error is the only real problem, now.

I have not tried it as a CGI yet but I am sure it will go boom when I do ... I will give it a test late tonight.

I dont care about Pi it is easily worked around. But the

error is un-trapable.

Got to run...

Bob the Caveguy aka Lord High Fixer.

(define (+NaN) (sqrt -1)) ;; make new function retruning a NaN

In your initialization file (init.lsp) , or just put:

(set '+NaN (sqrt -1))

in your initialization file.

Then after startup of newLISP +NaN will return +NaN.

Lutz

ps: just finished a new function 'constant' for protecting symbols to define constants, this will go into a new development version by the end of this week.

### CGI examples of the problem.

Been there done that.....

I have set up a CGI test so you can see my problem. "LSP" files are evaluated by your latest greatest, and "LISP" files are processed by the last known stable version before we started messing with it.

<center>

<A ref="http://autocode.com/run/nan-1.lsp">"

http://autocode.com/run/nan-1.lsp"</a>

and

<A ref="http://autocode.com/run/nan-1.lisp">"

http://autocode.com/run/nan-1.lisp"</a>

If you want/need FTP access for testing for your own, please contact me off-list.

Here are links to my first test using both.

<A ref="http://autocode.com/run/nan-test.lsp">"

http://autocode.com/run/nan-test.lsp"</a>

and

<A ref="http://autocode.com/run/nan-test.lisp">"

http://autocode.com/run/nan-test.lisp"</a>

Please believe me, when this works, I will provide you

examples.

Back to my Rat Killen....

I have set up a CGI test so you can see my problem. "LSP" files are evaluated by your latest greatest, and "LISP" files are processed by the last known stable version before we started messing with it.

<center>

<A ref="http://autocode.com/run/nan-1.lsp">"

http://autocode.com/run/nan-1.lsp"</a>

and

<A ref="http://autocode.com/run/nan-1.lisp">"

http://autocode.com/run/nan-1.lisp"</a>

If you want/need FTP access for testing for your own, please contact me off-list.

Here are links to my first test using both.

<A ref="http://autocode.com/run/nan-test.lsp">"

http://autocode.com/run/nan-test.lsp"</a>

and

<A ref="http://autocode.com/run/nan-test.lisp">"

http://autocode.com/run/nan-test.lisp"</a>

Please believe me, when this works, I will provide you

examples.

Back to my Rat Killen....

Bob the Caveguy aka Lord High Fixer.

(1) we can now create a symbol containing the NaN value:

(set '+NaN (sqrt -1))

when doing this, the error message "sqrt: DOMAIN error" will occur only on the native Win32 version, and I have no way to suppress it (some body knows?). I guess this is a problem for you when doing CGI, where all STDOUT goes back to the client browser. Other than suggesting to use the Cygwin version on Windows, I don't have a solution at the moment. There must be a way to surpress this message. Anybody out there with Borland C++ documentation???

on Cygwin and UNIXs there is no such message.

(2) all integer operations: + 0 / * take NaN as a zero

this seems to work on all versions.

(3) Divisions by zero cause a newLISP "Math exception" on all versions using integer operators and floating operators. This seems to work on all versions.

(4) all floating point ops: div mul add sub produce NaN when one of the arguments is NaN.

*This works on Cygwin and UNIX's but produces a Math exception error with 'div' on the native Win32 version.*

(5) when doing

NaN? => NaN? <407E08>

NaN? is a builtin primitive in newLISP, evaluating a primitive by itself will ebaluate to itself and print its's name and hexadecimal run address. This is intended behaviour for all builtin primitives.

To sum it up: my understanding is, that the only two things to be fixed is the (div 3.14 +NaN) bug in point (4) and surpression of the "DOMAIN error" message in Win32 in point (1), everything else is fine.

I think (4) I can do pretty quickly, for (1) I wouldn't know, how to do it, at the moment.

Lutz

PS: no rats or any other animals will be killed sqashing this bug.

### Yet One more thought :)

Simple Answer: Yes and Yes :)

Please Understand the last "C" project I personaly coded was many years ago. What version of Borland

are you using I WILL locate a copy. One workaround

that comes to mind is to force the error early.

In NewLISP internal init code. redirtect stdio to null,

do a (sqrt -1), store the return value, and put stdio

back. Now by the time it gets to me at the application level, the NAN value has already been forced and the

output suppressed :)

I have a "C" programmer in Chicago I work with, If you do not mind I will have him take a hack at the problem.

Till later

Bob

Please Understand the last "C" project I personaly coded was many years ago. What version of Borland

are you using I WILL locate a copy. One workaround

that comes to mind is to force the error early.

In NewLISP internal init code. redirtect stdio to null,

do a (sqrt -1), store the return value, and put stdio

back. Now by the time it gets to me at the application level, the NAN value has already been forced and the

output suppressed :)

I have a "C" programmer in Chicago I work with, If you do not mind I will have him take a hack at the problem.

Till later

Bob

Bob the Caveguy aka Lord High Fixer.

Lutz

http://nuevatec.com/download/development/

Lutz

### There is Joy in Mudville Tonight

Thanks !!! I updated online test and it passed with flying colors :) ATABoy ......

Bob the Caveguy aka Lord High Fixer.

### Spoke a bit too soon :(

One more little problem with NaN :(

> (set 'X nil)

nil

> (NaN? 'X)

Value expected in function NaN?

>

I would have expected a return of nil, I will add it to the

previous online test.

> (set 'X nil)

nil

> (NaN? 'X)

Value expected in function NaN?

>

I would have expected a return of nil, I will add it to the

previous online test.

Bob the Caveguy aka Lord High Fixer.

So I feel reluctant to change this.

Lutz

### +NAN the noun Vs. NaN? the Verb

Promoting +NAN to the state of being a noun in NewLISP

was truely a big leep in logic :)

Fixing the verb NaN? to be consistent with the other XXX?

functions completes the puzzle.

NaN? should return True or False based exclusively on NaNness and nothing else.

All the other (xxxx? tests operate this way.

The fact that NaNness is the numeric anti-nil. IT no longer

wishes to be confused with it and it's evil twin the all logical nil.

The fact that the birth of a new AI is in your hands,

should not affect your decision in any way :)

And if you are asking. WHY ME ?

You started it with NaN? I have wanted a numeric nil for years.

I appreciate the numerous leeps of logic involved in evolution of newLISP as a language. LISP, Scheme, and TK.

I know nothing about TK, which will make codeing the user interface, a real adventure. and the start of a new thread and a new example or three :)

Thanks again, it has been fun ...

Bob

was truely a big leep in logic :)

Fixing the verb NaN? to be consistent with the other XXX?

functions completes the puzzle.

NaN? should return True or False based exclusively on NaNness and nothing else.

All the other (xxxx? tests operate this way.

The fact that NaNness is the numeric anti-nil. IT no longer

wishes to be confused with it and it's evil twin the all logical nil.

The fact that the birth of a new AI is in your hands,

should not affect your decision in any way :)

And if you are asking. WHY ME ?

You started it with NaN? I have wanted a numeric nil for years.

I appreciate the numerous leeps of logic involved in evolution of newLISP as a language. LISP, Scheme, and TK.

I know nothing about TK, which will make codeing the user interface, a real adventure. and the start of a new thread and a new example or three :)

Thanks again, it has been fun ...

Bob

Bob the Caveguy aka Lord High Fixer.

(define (+NaN? x) (if (float? x) (NaN? x) nil)) ;;-)

but seriously, I wonder what everybody else thinks about this topic?

Anybody out there with an opinion about NaN? !?!

About TK, I am not an expert here, just supplied a workable interface to use a very popular and platformindependent way to do GUI's.

What is missing here would be a layer in newLISP providing a more LISPier way of doing GUI stuff. Personally I am more into Web GUIs and haven't thought of providing it myself.

Lutz

The rules for using inf are in every college calculus book.

About GUIs.

I had to write a database front-end for NSLDS (financial aid stuff). I gave up on newlisp-tk, java, and wxPython and just used the newlisp httpd server and wrote a cgi in newlisp to enter data. The cgi verifys data entry and exports it to fixed record format for the Government and took half of the work required to do a full blown GUI.

Eddie

I think the NaN situation is pretty much hashed out with CaveGuy's help, but on Inf I just rely on the smartness of the underlying 'C' libraries until further notice.

That application you are describing pretty much sums up what I think about todays GUI app. writing: 99% of GUIs can be written for a Web Browser. When hosting locally just use the newLISP httpd as a very slim webserver.

I think GUIs fabricated outside of Browsers only have a very special niche today, like mouse intense graphics stuff and certain realtime stuff. The nice thing about doing Browser/CGI GUIs is, that

(1) at the same time you make an application which can be distributed/run over the Internet.

(2) parts of your application can be replaced, redesigned, because of open standards, i.e. throw in a different webserver, or interface with other web/CGI system, which may/or not be written in newLISP.

(3) If well designed, big parts of the system can be maintained without or very little newLISP knowledge.

I think the time will come where we will see new intents to bring real-time stuff and interactive graphics to the browser. Java was pretty good at that but didn't caught on, other solutions out there are propietary.

Lutz