1. How to handle crashes?
- Posted by draegur at comcast.net May 28, 2003
- 443 views
Greetings, It's been a while since I visited this list. Here I am almost 4 years later still working on perfecting my mud. Because of the help of so many of you (so long ago) I've built myself a nice little home. Now the question. I've searched through as many of the posts and documentation as I could for the answer, but never found the right thing. In my game if there are errors the entire world crashes and I lose all data since the last save. (Usually only about 10-15 minutes, but players get so grumpy!) Has there been a way developed that if a certain action they try to perform calls a procedure that perhaps has a bug in it I had yet to find that I could indeed point euphoria to a routine I devise? It would be nice to point errors like that to a routine that simply says "Hey, don't do that again, it's broken" and resumes the main loop of the game. Any chance my 4 year old wish has finally come true?
2. Re: How to handle crashes?
- Posted by Sabal.Mike at notations.com May 28, 2003
- 428 views
Nope! How about for 2.5, Rob? >>> draegur at comcast.net 05/28/03 11:46AM >>> It would be nice to point errors like that to a routine that simply says "Hey, don't do that again, it's broken" and resumes the main loop of the game. Any chance my 4 year old wish has finally come true?
3. Re: How to handle crashes?
- Posted by gertie at visionsix.com May 28, 2003
- 408 views
On 28 May 2003, at 11:46, draegur at comcast.net wrote: > > > Greetings, > > It's been a while since I visited this list. Here I am almost 4 years > later still working on perfecting my mud. Because of the help of so many > of you (so long ago) I've built myself a nice little home. > > Now the question. I've searched through as many of the posts and > documentation as I could for the answer, but never found the right thing. > > In my game if there are errors the entire world crashes and I lose all > data since the last save. (Usually only about 10-15 minutes, but players > get so grumpy!) Has there been a way developed that if a certain action > they try to perform calls a procedure that perhaps has a bug in it I had > yet to find that I could indeed point euphoria to a routine I devise? > > It would be nice to point errors like that to a routine that simply says > "Hey, don't do that again, it's broken" and resumes the main loop of the > game. > > Any chance my 4 year old wish has finally come true? Didn't someone find a way to do that using types? Kat
4. Re: How to handle crashes?
- Posted by jbrown1050 at hotpop.com May 28, 2003
- 409 views
Its not builtin. I am working on a library that, when properly used, will trap nearly all run-time errors w/o causing the program to end. The catch is that using the lib with an existing program means considerable (and tedious) rewriting, tho I suppose it'd be possible to write a short program to convert all the code. The bigger issue, is that by using my lib, the program itself is likely to be slowed down considerably ... the library works by checking arguments in its replacement routines (you use the lib's routines instead of the normal operators or normal builtin routines) and making sure that they are correct .. if they aren't then it sets a flag and returns. In essence, the lib is a pre-written version of all the checking code that you'd normally have to write on your own. So, in short, your 4 year old wish has not come true, but I've helped bring it a little bit closer ... If you really want that sort of error checking tho, you might wanna check out OpenEuphoria (at OpenEU at topica.com). jbrown On Wed, May 28, 2003 at 11:46:59AM -0400, draegur at comcast.net wrote: > > > Greetings, > > It's been a while since I visited this list. Here I am almost 4 years > later still working on perfecting my mud. Because of the help of so many > of you (so long ago) I've built myself a nice little home. > > Now the question. I've searched through as many of the posts and > documentation as I could for the answer, but never found the right thing. > > In my game if there are errors the entire world crashes and I lose all > data since the last save. (Usually only about 10-15 minutes, but players > get so grumpy!) Has there been a way developed that if a certain action > they try to perform calls a procedure that perhaps has a bug in it I had > yet to find that I could indeed point euphoria to a routine I devise? > > It would be nice to point errors like that to a routine that simply says > "Hey, don't do that again, it's broken" and resumes the main loop of the > game. > > Any chance my 4 year old wish has finally come true? > > > > TOPICA - Start your own email discussion group. FREE! > > -- /"\ ASCII ribbon | http://www.geocities.com/jbrown1050/ \ / campain against | Linux User:190064 X HTML in e-mail and | Linux Machine:84163 /*\ news, and unneeded MIME |
5. Re: How to handle crashes?
- Posted by jbrown105 at speedymail.org May 30, 2003
- 402 views
On Fri, May 30, 2003 at 03:14:04PM +0700, aku saya wrote: > > > How about an option to make euphoria still run after a run-time error > happens? Like "On Error Resume Next" in VB. > > I suggest using "without error", with an option to call user > procedures. > And when a runtime error happens, just continue it and fill the > function result into a default value, such as: > > ? length(123) -- returns 0 > a = {1, 2, 3} > b = 5 > ? a[2..100] -- returns {2, 3} > ? 1/0 -- returns inf > ? b[1] -- returns 5 > if {1, 2, 3} = 2 then -- returns 0 > integer c > c = 1.25 -- make c = 1 > > etc. It can make user confused, but maybe useful for use in the > released programs, to prevent end-user confused by the fatal-error. > > so > - develop a program carefully without this option until finished > - add "without error" to the first line > - publish the program. > > Just a suggestion, <snip> It's an interesting suggestion. I'd think, that 1/0 should return nan, that invalid assignments to variables would simply be ignored, and that invalid slices of a sequence would return {} ... but those are just the details. The basic concept, looks ok to me, tho it seems to be not the best way. My lib will just flatly return -1 on error, and then you have to check the variable eu_errno to see what the error was (you'd have to check eu_errno every time if -1 is a valid return value btw). That way, at least the code actually _KNOWS_ that there was an error. jbrown -- /"\ ASCII ribbon | http://www.geocities.com/jbrown1050/ \ / campain against | Linux User:190064 X HTML in e-mail and | Linux Machine:84163 /*\ news, and unneeded MIME |
6. Re: How to handle crashes?
- Posted by Pete Lomax <petelomax at blueyonder.co.uk> May 30, 2003
- 403 views
On Fri, 30 May 2003 12:58:55 -0400, jbrown105 at speedymail.org wrote: >It's an interesting suggestion. I'd think, that 1/0 should return nan, If you want to use nan, define a constant and use that constant, whatever that may be, do *NOT* calculate it !! Lots of code that I have written (and lots inherited) use ?9/0 to force a fatal error. <slight rant> In some situations, (I'm talking MEditor here, where there may be several open documents containing lots of work the user might lose), it is up to me to do some sensible thing such as prompt the user, save all the files (others first, preferably in another [new] directory, before the one that seems to have an error (and, erm, write something which will cause the editor to re-explain the situation to the user when the editor is next re-started and offer a directory compare...) It does not do that at the moment but I've added that suggestion). But then I still need to force a crash. I might, scratch that, will need the ex.err file to track the bug down. Plus, of course, I don't code ?9/0 unless I really have to give up. If the error was just ignored, let's say it rewrites all open files with garbage. Would you prefer that to a crash? </slight rant> The way I would see this working, if at all, is: main.exw: global ... global ... global ... procedure intercept_fatal() ,,, end procedure set_fatal_routine(routine_id("intercept_fatal")) Notes: 1) No include statements, initialisation, or any other routines are allowed before set_fatal_routine(). Just global data. 2) A second call to set_fatal_routine() in the same program is an irrecoverable fatal error (see 7). 3) This feature is not available in compiled code, only when using the interpreter (which covers bound/shrouded/standalone stuff, just not C) 4)The call to set_fatal_routine() generates no code; instead it makes a checkpoint of the memory/symbol table currently in use.=20 5) When a fatal error occurs it reloads reference counts (eeek!) based on that and performs a full garbage collection, discards the rest of memory and the rest of the symbol table, and resumes interpretation at the first line of the procedure.[see postscript] 6) intercept_fatal() may not have any parameters or any local variables, the end procedure has no "clean up" requirement. 7) contrary to 2) set_fatal_routine() will be called again, but via 5) the interpreter will have managed to forget it was ever called. In a correct implementation, this will simply happen, no explicit check for this should be required. and last, but not least: 8) I don't subscribe to the theory that you can release crud code and the user can be blissfully unaware that it is crud code. Some apps it is a good idea and not very dangerous (eg games), some it might help if wisely used (eg editors), some it really is very very wrong (cgi). The problem with cgi-like programs, of course, is they are not interactive, so unless there is judicious use of rand(), recovering from a fatal error will just run splat into the self same problem, time and time again. Pete PS One perfectly acceptable method, in my eyes, would be to write a (massive) ex.err file and then re-invoke the interpreter to parse that file to initialise those global variables. I would not want or expect it to be fast. PPS Phew! I enjoyed that little rant
7. Re: How to handle crashes?
- Posted by jbrown105 at speedymail.org May 30, 2003
- 407 views
On Fri, May 30, 2003 at 10:03:48PM +0100, Pete Lomax wrote: > > > On Fri, 30 May 2003 12:58:55 -0400, jbrown105 at speedymail.org wrote: > > >It's an interesting suggestion. I'd think, that 1/0 should return nan, > > If you want to use nan, define a constant and use that constant, > whatever that may be, do *NOT* calculate it !! I meant I'd prefer it returning nan over inf. > > Lots of code that I have written (and lots inherited) use ?9/0 to > force a fatal error. > With my lib, you have to explicitly code (using op_divide(0,0) instead of 0/0 for example, or e_puts() instead of puts()) in order to avoid an error. If needed, you can always force an error. > <slight rant> > In some situations, (I'm talking MEditor here, where there may be > several open documents containing lots of work the user might lose), > it is up to me to do some sensible thing such as prompt the user, save > all the files (others first, preferably in another [new] directory, > before the one that seems to have an error (and, erm, write something > which will cause the editor to re-explain the situation to the user > when the editor is next re-started and offer a directory compare...) > It does not do that at the moment but I've added that suggestion). My lib lets you do that exactly, tho the MEditor code would need a major rewrite .. and use of the lib will slow it significantly. > > But then I still need to force a crash. I might, scratch that, will > need the ex.err file to track the bug down. You still code, with my lib. > > Plus, of course, I don't code ?9/0 unless I really have to give up. If > the error was just ignored, let's say it rewrites all open files with > garbage. Would you prefer that to a crash? > </slight rant> > > The way I would see this working, if at all, is: > > main.exw: > global ... > global ... > global ... > procedure intercept_fatal() > ,,, > end procedure > set_fatal_routine(routine_id("intercept_fatal")) > Basicly, the same as crash_routine() that was in peu and Matt Lewis's interpreter. > Notes: > 1) No include statements, initialisation, or any other routines are > allowed before set_fatal_routine(). Just global data. Why? > 2) A second call to set_fatal_routine() in the same program is an > irrecoverable fatal error (see 7). Why? Whats wrong with chains of error handlers? > 3) This feature is not available in compiled code, only when using the > interpreter (which covers bound/shrouded/standalone stuff, just not C) I agree with this one, since I don't see how it'd be possible to catch the C stuff. > 4)The call to set_fatal_routine() generates no code; instead it makes > a checkpoint of the memory/symbol table currently in use. > 5) When a fatal error occurs it reloads reference counts (eeek!) based > on that and performs a full garbage collection, discards the rest of > memory and the rest of the symbol table, and resumes interpretation at > the first line of the procedure.[see postscript] Why? That seems like overkill to me. > 6) intercept_fatal() may not have any parameters or any local > variables, the end procedure has no "clean up" requirement. Why? Might wanna pass error info thru the parameters, and local variables are very useful for the procedure. > 7) contrary to 2) set_fatal_routine() will be called again, but via 5) > the interpreter will have managed to forget it was ever called. In a > correct implementation, this will simply happen, no explicit check for > this should be required. I don't understand what you mean by this. > > and last, but not least: > > 8) I don't subscribe to the theory that you can release crud code and > the user can be blissfully unaware that it is crud code. Some apps it > is a good idea and not very dangerous (eg games), some it might help > if wisely used (eg editors), some it really is very very wrong (cgi). > I also agree. But no one is asking for the ability to release crud code, what is being asked for is the ability to save data, give the user a little message box explaining the error, and go down quietly. We don't want to ignore errors silently, we just want to look as professional as possible when an error does occur. > The problem with cgi-like programs, of course, is they are not > interactive, so unless there is judicious use of rand(), recovering > from a fatal error will just run splat into the self same problem, > time and time again. Agreed. > > Pete > > PS One perfectly acceptable method, in my eyes, would be to write a > (massive) ex.err file and then re-invoke the interpreter to parse that > file to initialise those global variables. I would not want or expect > it to be fast. I find it not acceptable or needed. This is definately overkill. > > PPS Phew! I enjoyed that little rant > jbrown > > > TOPICA - Start your own email discussion group. FREE! > > -- /"\ ASCII ribbon | http://www.geocities.com/jbrown1050/ \ / campain against | Linux User:190064 X HTML in e-mail and | Linux Machine:84163 /*\ news, and unneeded MIME |
8. Re: How to handle crashes?
- Posted by gertie at visionsix.com May 30, 2003
- 431 views
On 30 May 2003, at 17:45, jbrown105 at speedymail.org wrote: > > > On Fri, May 30, 2003 at 10:03:48PM +0100, Pete Lomax wrote: > > > > <snip> > > > > Pete > > > > PS One perfectly acceptable method, in my eyes, would be to write a > > (massive) ex.err file and then re-invoke the interpreter to parse that > > file to initialise those global variables. I would not want or expect > > it to be fast. > > I find it not acceptable or needed. This is definately overkill. It's rather acceptable, somewhat needed, and overkill for your purposes. What if you have a crash every other month, and you can't find the bug? Like this new bug in mirc 6.03: set -u0 %walkcolor1 $gettok(%colors1,$rand(1,$len(%colors1)),$asc(%comma)) Those functions return at different times, and occasionally %walkcolor1 will be $null. But a stepper ide like Eu won't catch it, even if mirc had one. But storing the vars did catch it, leading to code like this: :regetwalkcolor1 set -u0 %walkcolor1 $gettok(%colors1,$rand(1,$len(%colors1)),$asc(%comma)) if ( %walkcolor1 == $null ) { goto regetwalkcolor1 } If you have a cgi box that crashes once a month, you could rebuild to the moment before the crash, possibly stepping back in time thru the execution. Kat
9. Re: How to handle crashes?
- Posted by jbrown105 at speedymail.org May 31, 2003
- 402 views
No, restoring the variables and context is overkill. I see that saving the current variables (in full) and context (i.e. which statements were executed) into an error file, is a good idea. It would be a great aid to debugging. But I fail to see the need to RESTORE the variables. jbrown On Fri, May 30, 2003 at 06:52:57PM -0500, gertie at visionsix.com wrote: <snip> > It's rather acceptable, somewhat needed, and overkill for your purposes. > What if you have a crash every other month, and you can't find the bug? Like > this new bug in mirc 6.03: > > set -u0 %walkcolor1 > $gettok(%colors1,$rand(1,$len(%colors1)),$asc(%comma)) > > > Those functions return at different times, and occasionally %walkcolor1 will > be $null. But a stepper ide like Eu won't catch it, even if mirc had one. But > storing the vars did catch it, leading to code like this: > > :regetwalkcolor1 > set -u0 %walkcolor1 > $gettok(%colors1,$rand(1,$len(%colors1)),$asc(%comma)) > if ( %walkcolor1 == $null ) { goto regetwalkcolor1 } > > If you have a cgi box that crashes once a month, you could rebuild to the > moment before the crash, possibly stepping back in time thru the execution. > > Kat > > > > TOPICA - Start your own email discussion group. FREE! > > -- /"\ ASCII ribbon | http://www.geocities.com/jbrown1050/ \ / campain against | Linux User:190064 X HTML in e-mail and | Linux Machine:84163 /*\ news, and unneeded MIME |
10. Re: How to handle crashes?
- Posted by Pete Lomax <petelomax at blueyonder.co.uk> May 31, 2003
- 422 views
On Fri, 30 May 2003 17:45:13 -0400, jbrown105 at speedymail.org wrote: >> Notes: >> 1) No include statements, initialisation, or any other routines are >> allowed before set_fatal_routine(). Just global data. > >Why? My (naive) view of a workable system / I want to keep it simple. > >> 2) A second call to set_fatal_routine() in the same program is an >> irrecoverable fatal error (see 7). > >Why? Whats wrong with chains of error handlers? What exactly would you achieve by trapping bad code within bad code? This is not exception handling, this is buggy, crud code (see my comments below). This is not a programming methodology, this is a safety net for the end user. Code it and test it, but be embarrassed if it ever happens live. I think it is a totally different topic if you want a local try catch doobrie, or a safe_mul() or safe_div() routine. >> 5) When a fatal error occurs it reloads reference counts (eeek!) based >> on that and performs a full garbage collection, discards the rest of >> memory and the rest of the symbol table, and resumes interpretation at >> the first line of the procedure.[see postscript] > >Why? That seems like overkill to me. An absolutely unambiguous restart point. It also forces you to specify the absolutely unambiguous data set needed for recovery. How otherwise would you reference data which is not in scope at the point (which could be anywhere) that the fatal error occurs? > >> 6) intercept_fatal() may not have any parameters or any local >> variables, the end procedure has no "clean up" requirement. > >Why? Might wanna pass error info thru the parameters,=20 What would a top level routine ever know about low-level parameters and variables? Or are you suggesting the top level routine would have to be more intelligent and complicated than the code it is guarding? "Hello, this is routine number 73, I was passed a single integer which was 478, and my local variables are {4,7,"Simon",5}" Does it really help you to recover if I also pass you "appendThing", "Id", "i", "j", "text", "void"? >and local variables are very useful for the procedure. The important thing I felt about the "no clean up" is that on resumption the code could "fall through" the end procedure statement without causing any, even minor niggles. That means no parameters and no local variables to discard. > >> 7) contrary to 2) set_fatal_routine() will be called again, but via 5) >> the interpreter will have managed to forget it was ever called. In a >> correct implementation, this will simply happen, no explicit check for >> this should be required. > >I don't understand what you mean by this. Just dotting the i's > >>=20 >> and last, but not least: >>=20 >> 8) I don't subscribe to the theory that you can release crud code and >> the user can be blissfully unaware that it is crud code. Some apps it >> is a good idea and not very dangerous (eg games), some it might help >> if wisely used (eg editors), some it really is very very wrong (cgi). >>=20 > >I also agree. But no one is asking for the ability to release crud code, Well, actually we are asking for the ability to release crud code. Not deliberately, but just simply inevitably. Something like MEditor is some 15,000 lines of code (and win32lib what, 30,000?). It is highly unlikely there will ever be a release that really has zero (fatal) bugs, the best we can hope for is it will be several years between finding one for the average user. But as I say, this is no way to make bad code good, and that point needs to be said, loudly. >what is being asked for is the ability to save data, give the user a = little >message box explaining the error, and go down quietly. We don't want to = ignore >errors silently, we just want to look as professional as possible when = an >error does occur. Exactly. >> PS One perfectly acceptable method, in my eyes, would be to write a >> (massive) ex.err file and then re-invoke the interpreter to parse that >> file to initialise those global variables. I would not want or expect >> it to be fast. > >I find it not acceptable or needed. This is definately overkill. Sure, there may be a better, or more to the point, easier way. What I was trying to illustrate is that the overhead should be on programs recovering from a fatal error, and virtually no overhead on well-behaved programs. I'll add that if with profile or with profile_time is in force it should report the error with some message such as=20 "A (recoverable) fatal error occurred. You need to fix that before profiling the program." Likewise, if with trace is in force, the interpreter should probably assume you are in development mode and crash instead of recovering. Pete
11. Re: How to handle crashes?
- Posted by jbrown105 at speedymail.org May 31, 2003
- 410 views
On Sat, May 31, 2003 at 12:52:59AM +0100, Pete Lomax wrote: > > > On Fri, 30 May 2003 17:45:13 -0400, jbrown105 at speedymail.org wrote: > > >> Notes: > >> 1) No include statements, initialisation, or any other routines are > >> allowed before set_fatal_routine(). Just global data. > > > >Why? > My (naive) view of a workable system / I want to keep it simple. Ah I see. Shouldn't need to be that simple tho. > > > >> 2) A second call to set_fatal_routine() in the same program is an > >> irrecoverable fatal error (see 7). > > > >Why? Whats wrong with chains of error handlers? > What exactly would you achieve by trapping bad code within bad code? I mean more like, one handler looks at the error and does it stuff, then another handler can also do its stuff, and so on. > This is not exception handling, this is buggy, crud code (see my > comments below). This is not a programming methodology, this is a > safety net for the end user. > > Code it and test it, but be embarrassed if it ever happens live. > > I think it is a totally different topic if you want a local try catch > doobrie, or a safe_mul() or safe_div() routine. I don't. > > >> 5) When a fatal error occurs it reloads reference counts (eeek!) based > >> on that and performs a full garbage collection, discards the rest of > >> memory and the rest of the symbol table, and resumes interpretation at > >> the first line of the procedure.[see postscript] > > > >Why? That seems like overkill to me. > An absolutely unambiguous restart point. It also forces you to specify > the absolutely unambiguous data set needed for recovery. How otherwise > would you reference data which is not in scope at the point (which > could be anywhere) that the fatal error occurs? > My answer, in the openeu forum, was that the list of variables, and their scope, and the file they were in (as well as routine, if applicable, and also it should mark being a for loop var) and value, and etc. would be passed as a large sequence, to the crash routine. > > > >> 6) intercept_fatal() may not have any parameters or any local > >> variables, the end procedure has no "clean up" requirement. > > > >Why? Might wanna pass error info thru the parameters, > What would a top level routine ever know about low-level parameters > and variables? Or are you suggesting the top level routine would have > to be more intelligent and complicated than the code it is guarding? > "Hello, this is routine number 73, I was passed a single integer > which was 478, and my local variables are {4,7,"Simon",5}" > Does it really help you to recover if I also pass you "appendThing", > "Id", "i", "j", "text", "void"? No, but a more useful sequence (having all routine names, scopes, variables (names, scope, value, etc), file name and line number where error occured, error message as a string, etc) might be in order. > > >and local variables are very useful for the procedure. > The important thing I felt about the "no clean up" is that on > resumption the code could "fall through" the end procedure statement > without causing any, even minor niggles. That means no parameters and > no local variables to discard. Hmm. I can see your point there. But, if the program is going to abort as soon as the procedure ends, why does it matter? > > > >> 7) contrary to 2) set_fatal_routine() will be called again, but via 5) > >> the interpreter will have managed to forget it was ever called. In a > >> correct implementation, this will simply happen, no explicit check for > >> this should be required. > > > >I don't understand what you mean by this. > Just dotting the i's > > > >> > >> and last, but not least: > >> > >> 8) I don't subscribe to the theory that you can release crud code and > >> the user can be blissfully unaware that it is crud code. Some apps it > >> is a good idea and not very dangerous (eg games), some it might help > >> if wisely used (eg editors), some it really is very very wrong (cgi). > >> > > > >I also agree. But no one is asking for the ability to release crud code, > Well, actually we are asking for the ability to release crud code. Not > deliberately, but just simply inevitably. Something like MEditor is > some 15,000 lines of code (and win32lib what, 30,000?). It is highly > unlikely there will ever be a release that really has zero (fatal) > bugs, the best we can hope for is it will be several years between > finding one for the average user. But as I say, this is no way to make > bad code good, and that point needs to be said, loudly. Ah, very true. The idea is that the error handler doesn't try to fix things so the program can keep on going, but simply to do the stuff it needs to do (show a little "oppsies" msgbox, backup data, etc) and then abort gracefully. > > >what is being asked for is the ability to save data, give the user a little > >message box explaining the error, and go down quietly. We don't want to > >ignore > >errors silently, we just want to look as professional as possible when an > >error does occur. > Exactly. > > >> PS One perfectly acceptable method, in my eyes, would be to write a > >> (massive) ex.err file and then re-invoke the interpreter to parse that > >> file to initialise those global variables. I would not want or expect > >> it to be fast. > > > >I find it not acceptable or needed. This is definately overkill. > Sure, there may be a better, or more to the point, easier way. > What I was trying to illustrate is that the overhead should be on > programs recovering from a fatal error, and virtually no overhead on > well-behaved programs. Ah.. I agree, with the overhead part. > > I'll add that if with profile or with profile_time is in force it > should report the error with some message such as > "A (recoverable) fatal error occurred. You need to fix that before > profiling the program." Don't see why you can't have profile data up to the point of the error (tho beyond there, no data, obviously). > > Likewise, if with trace is in force, the interpreter should probably > assume you are in development mode and crash instead of recovering. Unless you are tracing the error handler itself. > > Pete > also, If an error handler has an error itself, it should crash. jbrown -- /"\ ASCII ribbon | http://www.geocities.com/jbrown1050/ \ / campain against | Linux User:190064 X HTML in e-mail and | Linux Machine:84163 /*\ news, and unneeded MIME |
12. Re: How to handle crashes?
- Posted by Derek Parnell <ddparnell at bigpond.com> May 31, 2003
- 422 views
----- Original Message ----- From: [lots of people] To: "EUforum" <EUforum at topica.com> Subject: Re: How to handle crashes? Why do we want a crash handler? In other words, what can't Euphoria do that you need to be able to do? For me, the primary answer to this question is to be able to handle things that Euphoria knows nothing about. For example, saving the current database transaction, or anything that would make the next restart easier for the program's user. I don't regard being able to automatically restart as being a priority issue. I would be quite contented if the crash handler could not return control to the program. I don't regard being able to know what caused the crash handler to be invoked as a high priority. It would be nice but not essential. -- Derek
13. Re: How to handle crashes?
- Posted by mistertrik at hotmail.com May 31, 2003
- 434 views
Yes, I agree. Two things that could be gained by handling crashes better. 1. A more professional look to your software. A dialog box telling the user a problem has occured, and what will happen is far more appealing than a screen dump of what sequence was where, and the error type that occured. That sort of information is invaluable to the programmer, but the user is not going to know what "invalid slice" is going to mean, or know what to do about it. A crash routine will not in this case reduce the number of errors that the user experiences, but it will be much more palatable than the current system. 2. More user 'safety' Nothing is worse than typing up a large document, and then losing it because the application crashed before you could save it. This sort of thing is more frustrating to a user than any other kind of error - where their effort and time was wasted. An application that experiences an error *should* close, because (like was said before) it is even worse for a rogue application to corrupt an entire document / system by continuing in such a fashion. What the user would like to do, after this error occured, is to salvage their work, and continue. As programmers, we can code defensively: for example store the users work in a temporary file every $period, and when the application starts up, check for that file, and give the option to restore from it. This is not always possible, for some types of application, doing this would mean too much overhead. A crash routine in this case will give the programmer the opportunity to backup the user's work into a file (example) and have the application start-up sequence give an option to restore. This would remove the overhead required to do that continuously, "just in case" there's an error. The ability to dodge fatal errors is not what should be advocated... there is no excuse for "crud" programming. During development, fatal errors are par for the course, and it is appropriate for the application to go haywire if there is a problem, because it tells the programmer what he needs to know (hopefully). However, once it has been released, a user doesn't care about whether there has been a math error, or a sequencing error, or a segmentation fault. What they care about is: a) The frequency of errors. The less the better, of course, and something telling them what has just happened. b) Where their work just went. Loss of data is painful, and if your application can (in the unlikely event of an error) bring that data back the next time it starts up, then that is good from a user's perspective. c) Whether the application behaves correctly. If an application occasionally dies with an error message, then it happens, and as long as it is not too often, then that's permissable. If an application behaves unpredictably (because your app dodged the fatal error and continued) then it can no longer be trusted. Imagine you were using an email client, and on sending a torrid letter to your loved one, found that instead your unpredictable program sent it to everyone in your addressbook, including boss, friends, and grandparents! Crashing is good, as long as it's a crash "you can walk away from", so to speak. That's my rant, anyway. ===================================================== .______<-------------------\__ / _____<--------------------__|=== ||_ <-------------------/ \__| Mr Trick >From: Derek Parnell <ddparnell at bigpond.com> >Reply-To: EUforum at topica.com >To: EUforum <EUforum at topica.com> >Subject: Re: How to handle crashes? >Date: Sat, 31 May 2003 13:23:51 +1000 > > >----- Original Message ----- >From: [lots of people] >To: "EUforum" <EUforum at topica.com> >Subject: Re: How to handle crashes? > >Why do we want a crash handler? In other words, what can't Euphoria do that >you need to be able to do? > > >For me, the primary answer to this question is to be able to handle things >that Euphoria knows nothing about. For example, saving the current database >transaction, or anything that would make the next restart easier for the >program's user. > >I don't regard being able to automatically restart as being a priority >issue. I would be quite contented if the crash handler could not return >control to the program. > >I don't regard being able to know what caused the crash handler to be >invoked as a high priority. It would be nice but not essential. > > >-- >Derek > > > >TOPICA - Start your own email discussion group. FREE! > >
14. Re: How to handle crashes?
- Posted by draegur at comcast.net May 31, 2003
- 433 views
I have seen many people here comment on my original question about crash handling/error trapping. Several of you have said there is no excuse for "crud" programming. Now, everyone is entitled to their opinion, but why should it matter to you how I program? The smallest file I have in my mud is 15,000 lines of code. There are many ways that new code I add interacts with old code that perhaps I wasn't expecting and *poof*, there goes anything they've done since the last backup of the database. Why is it so wrong for a language like euphoria to allow me flexibility in programming? Perhaps someones program to keep track of bank accounts might not benefit from being able to keep their programs running, but for someone doing a project like I am it's almost a nessessity. You've all had your chance to rant about how it should be handled like this so as not to encourage "crud" programming, or how it should not be done at all because it will encourage "sloppy" programming. My rant in response is, why do you care how I code? If using the print() command could lead to people being lazy, would you not include it because of that? So what if you don't need something to handle errors as I do? Unless, of course, the only reason why you do not write "sloppy" or "crud" code is because you cannot? There. I feel a little better now. (These comments were not directed at everyone, just those few on their personal little soap boxes)
15. Re: How to handle crashes?
- Posted by jbrown105 at speedymail.org May 31, 2003
- 412 views
On Sat, May 31, 2003 at 01:32:37PM -0400, draegur at comcast.net wrote: > > > I have seen many people here comment on my original question about crash > handling/error trapping. Several of you have said there is no excuse for > "crud" programming. Now, everyone is entitled to their opinion, but why > should it matter to you how I program? The smallest file I have in my > mud is 15,000 lines of code. There are many ways that new code I add > interacts with old code that perhaps I wasn't expecting and *poof*, > there goes anything they've done since the last backup of the database. > I hereby define crud programming as this: To continue execution of a program, after what should be a fatal error, at the risk of corrupting the data that the program works with. Under that definition, what you want to do is not crud programming. (Even if you want to back up the db and restart (or resume) the mud server, its still not crud programming since you aren't risking any corruption.) > Why is it so wrong for a language like euphoria to allow me flexibility > in programming? Perhaps someones program to keep track of bank accounts > might not benefit from being able to keep their programs running, but > for someone doing a project like I am it's almost a nessessity. Agreed. I believe that for games, especially multi-user ones, that sort of ability is a great advantage. (I also believe someone else who argued against crud programming said that ignoring errors in games is basicly OK.) > > You've all had your chance to rant about how it should be handled like > this so as not to encourage "crud" programming, or how it should not be > done at all because it will encourage "sloppy" programming. My rant in > response is, why do you care how I code? If using the print() command > could lead to people being lazy, would you not include it because of > that? So what if you don't need something to handle errors as I do? > Unless, of course, the only reason why you do not write "sloppy" or > "crud" code is because you cannot? That was one of the arguements against goto, you know. ;] try-catch for euphoria is a must, i feel.... > > There. I feel a little better now. Good for you. ;] > > (These comments were not directed at everyone, just those few on their > personal little soap boxes) HA! > > > > TOPICA - Start your own email discussion group. FREE! > j. brown > > -- /"\ ASCII ribbon | http://www.geocities.com/jbrown1050/ \ / campain against | Linux User:190064 X HTML in e-mail and | Linux Machine:84163 /*\ news, and unneeded MIME |
16. Re: How to handle crashes?
- Posted by Juergen Luethje <j.lue at gmx.de> May 31, 2003
- 417 views
Hi Jim, you wrote: <snip> > It's an interesting suggestion. I'd think, that 1/0 should return nan, that > invalid assignments to variables would simply be ignored, and that invalid > slices of a sequence would return {} ... but those are just the details. > > The basic concept, looks ok to me, tho it seems to be not the best way. My lib > will just flatly return -1 on error, and then you have to check the variable > eu_errno to see what the error was (you'd have to check eu_errno every time > if -1 is a valid return value btw). That's exactly the reason, why I'd prefer using a value as a flag for an invalid result, that never can be a valid number or sequence (such as NIL/NAN/UNKNOWN/UNDEFINED), rather than -1. This is especially important for writing generic routines. That's why I was happy when I discovered, that NAN can be returned from user defined functions. And that's why I was unhappy, when I recently read on this list, that this self-defined NAN can't be used reliable. > That way, at least the code actually _KNOWS_ that there was an error. I also regard this as important. > jbrown Best regards, Juergen -- /"\ ASCII ribbon campain | \ / against HTML in | Money is the root of all evil. X e-mail and news, | Send 20 Dollars for more info. / \ and unneeded MIME |
17. Re: How to handle crashes?
- Posted by jbrown105 at speedymail.org May 31, 2003
- 412 views
On Sat, May 31, 2003 at 08:25:41PM +0200, Juergen Luethje wrote: > > > Hi Jim, you wrote: > > <snip> > > > It's an interesting suggestion. I'd think, that 1/0 should return nan, that > > invalid assignments to variables would simply be ignored, and that invalid > > slices of a sequence would return {} ... but those are just the details. > > > > The basic concept, looks ok to me, tho it seems to be not the best way. My > > lib > > will just flatly return -1 on error, and then you have to check the variable > > eu_errno to see what the error was (you'd have to check eu_errno every time > > if -1 is a valid return value btw). > > That's exactly the reason, why I'd prefer using a value as a flag for an > invalid result, that never can be a valid number or sequence (such as > NIL/NAN/UNKNOWN/UNDEFINED), rather than -1. This is especially important > for writing generic routines. Yes, but its very hard to find one like that. I used to like to do what DC did in Py: global constant UNDEFINED = {-102354, -102354} He called it PyUndef and used different numbers tho, but the general concept (use an ugly looking sequence that is unlikely to every be a valid result) still works. > That's why I was happy when I discovered, that NAN can be returned from > user defined functions. Shouldn't have, since NAN can be a perfectly valid return value. > And that's why I was unhappy, when I recently > read on this list, that this self-defined NAN can't be used reliable. The reason behind that, is that there is more than one NAN. You can get a NAN from tan(), power(), -inf/inf, ... And, each way of calculating NAN gives a different NAN. What should be done, is to do this. global constant divNAN = -inf/inf, powNAN = power(2, inf), tanNAN = --however you get a NAN from tan() ...etc for every possible way of calculating NAN. So, that, divNAN is reliable when using NANs from division, but not with comparisons to tanNANs, for example. Then, you can choose one NAN, to use as the return value ... as long as its always the same NAN there is no problem. (Except of course, that NAN could be a valid return value ... but so could {-102354, -102354}, so theres no good way of getting around that.) > > > That way, at least the code actually _KNOWS_ that there was an error. > > I also regard this as important. I based my errhandle.e lib, on how C stdlib functions use a global errno to return errors. jbrown > > > jbrown > > Best regards, > Juergen > > -- > /"\ ASCII ribbon campain | > \ / against HTML in | Money is the root of all evil. > X e-mail and news, | Send 20 Dollars for more info. > / \ and unneeded MIME | > > > > TOPICA - Start your own email discussion group. FREE! > > -- /"\ ASCII ribbon | http://www.geocities.com/jbrown1050/ \ / campain against | Linux User:190064 X HTML in e-mail and | Linux Machine:84163 /*\ news, and unneeded MIME |
18. Re: How to handle crashes?
- Posted by Juergen Luethje <j.lue at gmx.de> Jun 07, 2003
- 433 views
Hi Jim, you wrote: > On Sat, May 31, 2003 at 08:25:41PM +0200, Juergen Luethje wrote: >> >> >> Hi Jim, you wrote: >> >> <snip> >> >>> It's an interesting suggestion. I'd think, that 1/0 should return nan, that >>> invalid assignments to variables would simply be ignored, and that invalid >>> slices of a sequence would return {} ... but those are just the details. >>> >>> The basic concept, looks ok to me, tho it seems to be not the best way. My >>> lib >>> will just flatly return -1 on error, and then you have to check the variable >>> eu_errno to see what the error was (you'd have to check eu_errno every time >>> if -1 is a valid return value btw). >> >> That's exactly the reason, why I'd prefer using a value as a flag for an >> invalid result, that never can be a valid number or sequence (such as >> NIL/NAN/UNKNOWN/UNDEFINED), rather than -1. This is especially important >> for writing generic routines. > > Yes, but its very hard to find one like that. > > I used to like to do what DC did in Py: > > global constant UNDEFINED = {-102354, -102354} > > He called it PyUndef and used different numbers tho, but the general concept > (use an ugly looking sequence that is unlikely to every be a valid result) > still works. Yes. Some time ago, I had the idea of using global constant UNKNOWN = {"UnkNOWn"} >> That's why I was happy when I discovered, that NAN can be returned from >> user defined functions. > > Shouldn't have, since NAN can be a perfectly valid return value. > >> And that's why I was unhappy, when I recently >> read on this list, that this self-defined NAN can't be used reliable. > > The reason behind that, is that there is more than one NAN. > > You can get a NAN from tan(), power(), -inf/inf, ... > > And, each way of calculating NAN gives a different NAN. Interesting, thank you! Now I know, that I didn't know too much about NAN. > What should be done, is to do this. > > global constant > divNAN = -inf/inf, > powNAN = power(2, inf), > tanNAN = --however you get a NAN from tan() Because of tan(x) = sin(x)/cos(x), tan(x) is undefined, if cos(x) = 0 (i.e. for x = .., -PI/2, PI/2, 3*PI/2, ..). BTW: With Euphoria, 'cos(PI/2)' does *not* return 0. > ...etc for every possible way of calculating NAN. I also found the following addNAN = inf + (-inf) mulNAN = 0 * inf remNAN = remainder(inf, 1) > So, that, divNAN is reliable when using NANs from division, but not with > comparisons > to tanNANs, for example. > > Then, you can choose one NAN, to use as the return value ... as long as its > always the same NAN there is no problem. (Except of course, that NAN could be > a valid return value ... but so could {-102354, -102354}, so theres no good > way of getting around that.) In "What Every Computer Scientist Should Know About Floating-Point Arithmetic" <http://docs.sun.com/source/806-3568/ncg_goldberg.html>, David Goldberg writes, that the IEEE recommends a function Isnan(). In my imagination, this function would return TRUE for *any* NAN, and so help with this issue, right? Best regards, Juergen -- /"\ ASCII ribbon campain | \ / against HTML in | This message has been ROT-13 encrypted X e-mail and news, | twice for higher security. / \ and unneeded MIME |
19. Re: How to handle crashes?
- Posted by jbrown105 at speedymail.org Jun 07, 2003
- 427 views
On Sat, Jun 07, 2003 at 07:33:52PM +0200, Juergen Luethje wrote: > > > Hi Jim, you wrote: > > > On Sat, May 31, 2003 at 08:25:41PM +0200, Juergen Luethje wrote: > >> > >> > >> Hi Jim, you wrote: > >> > >> <snip> > >> > >>> It's an interesting suggestion. I'd think, that 1/0 should return nan, > >>> that > >>> invalid assignments to variables would simply be ignored, and that invalid > >>> slices of a sequence would return {} ... but those are just the details. > >>> > >>> The basic concept, looks ok to me, tho it seems to be not the best way. My > >>> lib > >>> will just flatly return -1 on error, and then you have to check the > >>> variable > >>> eu_errno to see what the error was (you'd have to check eu_errno every > >>> time > >>> if -1 is a valid return value btw). > >> > >> That's exactly the reason, why I'd prefer using a value as a flag for an > >> invalid result, that never can be a valid number or sequence (such as > >> NIL/NAN/UNKNOWN/UNDEFINED), rather than -1. This is especially important > >> for writing generic routines. > > > > Yes, but its very hard to find one like that. > > > > I used to like to do what DC did in Py: > > > > global constant UNDEFINED = {-102354, -102354} > > > > He called it PyUndef and used different numbers tho, but the general concept > > (use an ugly looking sequence that is unlikely to every be a valid result) > > still works. > > Yes. Some time ago, I had the idea of using > global constant UNKNOWN = {"UnkNOWn"} > That'd work too (tho I think it might be slightly more likely to be a program's valid data). > >> That's why I was happy when I discovered, that NAN can be returned from > >> user defined functions. > > > > Shouldn't have, since NAN can be a perfectly valid return value. > > > >> And that's why I was unhappy, when I recently > >> read on this list, that this self-defined NAN can't be used reliable. > > > > The reason behind that, is that there is more than one NAN. > > > > You can get a NAN from tan(), power(), -inf/inf, ... > > > > And, each way of calculating NAN gives a different NAN. > > Interesting, thank you! > Now I know, that I didn't know too much about NAN. LOL! > > > What should be done, is to do this. > > > > global constant > > divNAN = -inf/inf, > > powNAN = power(2, inf), > > tanNAN = --however you get a NAN from tan() > > Because of tan(x) = sin(x)/cos(x), > tan(x) is undefined, if cos(x) = 0 (i.e. for x = .., -PI/2, PI/2, 3*PI/2, ..). > BTW: With Euphoria, 'cos(PI/2)' does *not* return 0. Perhaps its cuz the PI constant isnt accurate enough? > > > ...etc for every possible way of calculating NAN. > > I also found the following > > addNAN = inf + (-inf) Why isnt this zero? x + (-x) == 0, and if x == inf, that should still hold true, or am I overlooking something? (Like, how 2 sets can be of inf size (i.e. are infinite sets) but still have one set larger than the other?) > mulNAN = 0 * inf You'd think that'd be 0 too ... (or maybe it has to do with the 1/inf == 0 and 1/0 != inf sort of thing?) /me faintly remembers reading somewhere that 0*inf == 1 > remNAN = remainder(inf, 1) This one I can understand (barely). > > > So, that, divNAN is reliable when using NANs from division, but not with > > comparisons > > to tanNANs, for example. > > > > Then, you can choose one NAN, to use as the return value ... as long as its > > always the same NAN there is no problem. (Except of course, that NAN could > > be > > a valid return value ... but so could {-102354, -102354}, so theres no good > > way of getting around that.) > > In "What Every Computer Scientist Should Know About Floating-Point Arithmetic" > <http://docs.sun.com/source/806-3568/ncg_goldberg.html>, David Goldberg > writes, that the IEEE recommends a function Isnan(). In my imagination, > this function would return TRUE for *any* NAN, and so help with this > issue, right? > Yes. But we'd have to write our own (unless Rob wants to make such a beast builtin, or some wise human decides to wrap a C version via define_c_func). > Best regards, > Juergen > Of course, if we used nan, then the error lib would NOT be as usable for, say, a program which did complex floating point math (in which cases NAN might be a valid return value). In that case, that program would still have to do the checks anyways. IOW, since no user-defined value will always be an invalid result or value, some programs will still have to do costly checks to be sure that no error occurred. At least my way (using -1), it becomes more of a habit. Besides, you'd still have to check for procedures (which return no value). jbrown > -- > /"\ ASCII ribbon campain | > \ / against HTML in | This message has been ROT-13 encrypted > X e-mail and news, | twice for higher security. > / \ and unneeded MIME | > -- /"\ ASCII ribbon | http://www.geocities.com/jbrown1050/ \ / campain against | Linux User:190064 X HTML in e-mail and | Linux Machine:84163 /*\ news, and unneeded MIME |
20. Re: How to handle crashes?
- Posted by Juergen Luethje <j.lue at gmx.de> Jun 09, 2003
- 406 views
Hi Jim, you wrote: > On Sat, Jun 07, 2003 at 07:33:52PM +0200, Juergen Luethje wrote: >> >> >> Hi Jim, you wrote: <snip> >>> What should be done, is to do this. >>> >>> global constant >>> divNAN = -inf/inf, >>> powNAN = power(2, inf), >>> tanNAN = --however you get a NAN from tan() >> >> Because of tan(x) = sin(x)/cos(x), >> tan(x) is undefined, if cos(x) = 0 (i.e. for x = .., -PI/2, PI/2, 3*PI/2, >> ..). >> BTW: With Euphoria, 'cos(PI/2)' does *not* return 0. > > Perhaps its cuz the PI constant isnt accurate enough? And also an IEEE double precision floating point number (8 bytes) isn't accurate enough. Even in another language, which provides IEEE *extended* precision floating point numbers (10 bytes), and using a PI constant with 30 digits after the decimal point, I got for cos(PI/2) the result 4.22838847269347E-18, but not 0. I just mentioned that in order to say, that I don't see any possibility for actually generating a 'tanNAN' with Eu. Well, I think we can live with this fact ... >>> ...etc for every possible way of calculating NAN. >> >> I also found the following >> >> addNAN = inf + (-inf) > > Why isnt this zero? > > x + (-x) == 0, and if x == inf, that should still hold true, or am I > overlooking > something? In arithmetic, there is no "number" inf, which can be used like x for normal calculations. Calculating with such a "number" would lead to strange results, e.g.: Say inf + (-inf) = 0. Also 2*inf = inf + inf. But 2*inf = inf, so: inf = inf + inf. Now subtract inf from each side: inf - inf = inf + inf - inf. Or: inf + (-inf) = inf. But didn't we say "inf + (-inf) = 0" ? > (Like, how 2 sets can be of inf size (i.e. are infinite sets) but > still have one set larger than the other?) Matt answered that better than I could have done. >> mulNAN = 0 * inf > > You'd think that'd be 0 too ... (or maybe it has to do with the 1/inf == 0 and > 1/0 != inf sort of thing?) /me faintly remembers reading somewhere that 0*inf > == 1 I found these addNAN, mulNAN, and remNAN in Goldberg's article cited below, and tested them with Eu. But I think I'd better not claim that I've fully understood that tricky concept of infinity. >> remNAN = remainder(inf, 1) > > This one I can understand (barely). I had tested this with the (2.4 beta) interpreter, and in the meantime I realized, that using the (2.4 beta) translator and the Borland compiler, remainder(inf, 1) is not NAN, but 0 ... >>> So, that, divNAN is reliable when using NANs from division, but not with >>> comparisons >>> to tanNANs, for example. >>> >>> Then, you can choose one NAN, to use as the return value ... as long as its >>> always the same NAN there is no problem. (Except of course, that NAN could >>> be >>> a valid return value ... but so could {-102354, -102354}, so theres no good >>> way of getting around that.) >> >> In "What Every Computer Scientist Should Know About Floating-Point >> Arithmetic" >> <http://docs.sun.com/source/806-3568/ncg_goldberg.html>, David Goldberg >> writes, that the IEEE recommends a function Isnan(). In my imagination, >> this function would return TRUE for *any* NAN, and so help with this >> issue, right? >> > > Yes. But we'd have to write our own (unless Rob wants to make such a beast > builtin, or some wise human decides to wrap a C version via define_c_func). I've done so. Any improvements and corrections, if necessary, are of course appreciated. -----------------------------[ Begin Code ]----------------------------- include machine.e constant zero52 = repeat(0, 52) global function isnan (object x) -- return TRUE, if and only if x is an IEEE 754 NaN value; -- tested with: o Eu 2.4 beta interpreter for Windows -- o Eu 2.4 beta translator and the Borland compiler sequence s, bits, mantissa integer exponent if sequence(x) then return 0 end if -- get the bit representation of an IEEE -- double precision floating point number s = atom_to_float64(x) bits = {} for i = 1 to 8 do bits &= int_to_bits(s[i], 8) end for -- check exponent and mantissa exponent = bits_to_int(bits[53..63]) - 1023 if exponent = 1024 then mantissa = bits[1..52] if not equal(mantissa, zero52) then return 1 end if end if return 0 end function -- Demo global constant POS_INF = 1.8e+307 * 10, NEG_INF = -POS_INF, addNAN = -(POS_INF+NEG_INF), mulNAN = -(0*POS_INF), divNAN = -(POS_INF/POS_INF) print(1, isnan("Hi!")) print(1, isnan(0)) print(1, isnan(-3)) print(1, isnan(167.25)) print(1, isnan(POS_INF)) ? isnan(NEG_INF) print(1, isnan(addNAN)) print(1, isnan(mulNAN)) print(1, isnan(divNAN)) print(1, isnan(5/addNAN)) print(1, isnan(7+mulNAN)) ? isnan(3*divNAN) if getc(0) then end if ------------------------------[ End Code ]------------------------------ >> Best regards, >> Juergen >> > > Of course, if we used nan, then the error lib would NOT be as usable for, say, > a program which did complex floating point math (in which cases NAN might be a > valid return value). In that case, that program would still have to do the > checks anyways. I can't imagine, in which situation NAN might be a valid return value. Could you give me an example? > IOW, since no user-defined value will always be an invalid result or > value, some programs will still have to do costly checks to be sure that > no error occurred. BTW: My isnan() function is not without cost, too. > At least my way (using -1), it becomes more of a habit. I normally also use -1, if possible. > Besides, you'd still have to check for procedures (which return no > value). > > jbrown Best regards, Juergen -- /"\ ASCII ribbon campain | |\ _,,,---,,_ \ / against HTML in | /,`.-'`' -. ;-;;,_ X e-mail and news, | |,4- ) )-,_..;\ ( `'-' / \ and unneeded MIME | '---''(_/--' `-'\_)
21. Re: How to handle crashes?
- Posted by jbrown105 at speedymail.org Jun 10, 2003
- 417 views
On Mon, Jun 09, 2003 at 03:53:38PM +0200, Juergen Luethje wrote: > > > Hi Jim, you wrote: > > > On Sat, Jun 07, 2003 at 07:33:52PM +0200, Juergen Luethje wrote: > >> > >> > >> Hi Jim, you wrote: > > <snip> > > >>> What should be done, is to do this. > >>> > >>> global constant > >>> divNAN = -inf/inf, > >>> powNAN = power(2, inf), > >>> tanNAN = --however you get a NAN from tan() > >> > >> Because of tan(x) = sin(x)/cos(x), > >> tan(x) is undefined, if cos(x) = 0 (i.e. for x = .., -PI/2, PI/2, 3*PI/2, > >> ..). > >> BTW: With Euphoria, 'cos(PI/2)' does *not* return 0. > > > > Perhaps its cuz the PI constant isnt accurate enough? > > And also an IEEE double precision floating point number (8 bytes) isn't > accurate enough. Even in another language, which provides IEEE > *extended* precision floating point numbers (10 bytes), and using a PI > constant with 30 digits after the decimal point, I got for cos(PI/2) the > result 4.22838847269347E-18, but not 0. In my fraction lib, I considers implementing "special" values, which would be interpreted as common "irrational" constants (such as PI, tho apparently PI isn't irrational iirc). Perhaps the IEEE specs should be updated for this idea as well? Then again, maybe not. > I just mentioned that in order to say, that I don't see any possibility > for actually generating a 'tanNAN' with Eu. Well, I think we can live > with this fact ... lol > > >>> ...etc for every possible way of calculating NAN. > >> > >> I also found the following > >> > >> addNAN = inf + (-inf) > > > > Why isnt this zero? > > > > x + (-x) == 0, and if x == inf, that should still hold true, or am I > > overlooking > > something? > > In arithmetic, there is no "number" inf, which can be used like x > for normal calculations. Calculating with such a "number" would lead to > strange results, e.g.: > > Say inf + (-inf) = 0. > > Also 2*inf = inf + inf. But 2*inf = inf, so: > inf = inf + inf. Now subtract inf from each side: > inf - inf = inf + inf - inf. Or: > inf + (-inf) = inf. > > But didn't we say "inf + (-inf) = 0" ? Oh. > > > (Like, how 2 sets can be of inf size (i.e. are infinite sets) but > > still have one set larger than the other?) > > Matt answered that better than I could have done. > > >> mulNAN = 0 * inf > > > > You'd think that'd be 0 too ... (or maybe it has to do with the 1/inf == 0 > > and > > 1/0 != inf sort of thing?) /me faintly remembers reading somewhere that > > 0*inf > > == 1 > > I found these addNAN, mulNAN, and remNAN in Goldberg's article cited > below, and tested them with Eu. But I think I'd better not claim that > I've fully understood that tricky concept of infinity. > Oh. > >> remNAN = remainder(inf, 1) > > > > This one I can understand (barely). > > I had tested this with the (2.4 beta) interpreter, and in the meantime I > realized, that using the (2.4 beta) translator and the Borland compiler, > remainder(inf, 1) is not NAN, but 0 ... Oh. Weird. > > >>> So, that, divNAN is reliable when using NANs from division, but not with > >>> comparisons > >>> to tanNANs, for example. > >>> > >>> Then, you can choose one NAN, to use as the return value ... as long as > >>> its > >>> always the same NAN there is no problem. (Except of course, that NAN could > >>> be > >>> a valid return value ... but so could {-102354, -102354}, so theres no > >>> good > >>> way of getting around that.) > >> > >> In "What Every Computer Scientist Should Know About Floating-Point > >> Arithmetic" > >> <http://docs.sun.com/source/806-3568/ncg_goldberg.html>, David Goldberg > >> writes, that the IEEE recommends a function Isnan(). In my imagination, > >> this function would return TRUE for *any* NAN, and so help with this > >> issue, right? > >> > > > > Yes. But we'd have to write our own (unless Rob wants to make such a beast > > builtin, or some wise human decides to wrap a C version via define_c_func). > > I've done so. Any improvements and corrections, if necessary, are of > course appreciated. > <snip code> Interesting. I'll test it out. > > >> Best regards, > >> Juergen > >> > > > > Of course, if we used nan, then the error lib would NOT be as usable for, > > say, > > a program which did complex floating point math (in which cases NAN might be > > a > > valid return value). In that case, that program would still have to do the > > checks anyways. > > I can't imagine, in which situation NAN might be a valid return value. > Could you give me an example? Experimental math programs, when doing complex math calculations (the meaning of which is likely beyond my head ): may encounter NAN as a result, and not necessarily as an invalid one. For the average program tho, NAN (and perhaps INF as well) are likely to be invalid return values... (one plus of using -1, is with the way Eu works, -1 takes up 4 bytes while NAN/INF take up 8 bytes ... but thats mostly a non issue these days). > > > IOW, since no user-defined value will always be an invalid result or > > value, some programs will still have to do costly checks to be sure that > > no error occurred. > > BTW: My isnan() function is not without cost, too. No method of checking really is. (Although some do indeed cost less, all have some cost.) > > > At least my way (using -1), it becomes more of a habit. > > I normally also use -1, if possible. As do the libc functions. Like (I think) I said, I borrowed this practice from C programming in Linux. jbrown > > > Besides, you'd still have to check for procedures (which return no > > value). > > > > jbrown > > Best regards, > Juergen > > -- > /"\ ASCII ribbon campain | |\ _,,,---,,_ > \ / against HTML in | /,`.-'`' -. ;-;;,_ > X e-mail and news, | |,4- ) )-,_..;\ ( `'-' > / \ and unneeded MIME | '---''(_/--' `-'\_) > > > > TOPICA - Start your own email discussion group. FREE! > > -- /"\ ASCII ribbon | http://www.geocities.com/jbrown1050/ \ / campain against | Linux User:190064 X HTML in e-mail and | Linux Machine:84163 /*\ news, and unneeded MIME |
22. Re: How to handle crashes?
- Posted by Juergen Luethje <j.lue at gmx.de> Jun 10, 2003
- 435 views
Hi Jim, you wrote: > On Mon, Jun 09, 2003 at 03:53:38PM +0200, Juergen Luethje wrote: >> >> >> Hi Jim, you wrote: >> >>> On Sat, Jun 07, 2003 at 07:33:52PM +0200, Juergen Luethje wrote: >>>> >>>> >>>> Hi Jim, you wrote: >> >> <snip> >> >>>>> What should be done, is to do this. >>>>> >>>>> global constant >>>>> divNAN = -inf/inf, >>>>> powNAN = power(2, inf), >>>>> tanNAN = --however you get a NAN from tan() >>>> >>>> Because of tan(x) = sin(x)/cos(x), >>>> tan(x) is undefined, if cos(x) = 0 (i.e. for x = .., -PI/2, PI/2, 3*PI/2, >>>> ..). >>>> BTW: With Euphoria, 'cos(PI/2)' does *not* return 0. >>> >>> Perhaps its cuz the PI constant isnt accurate enough? >> >> And also an IEEE double precision floating point number (8 bytes) isn't >> accurate enough. Even in another language, which provides IEEE >> *extended* precision floating point numbers (10 bytes), and using a PI >> constant with 30 digits after the decimal point, I got for cos(PI/2) the >> result 4.22838847269347E-18, but not 0. Small correction for the record: Although that language generally provides IEEE *extended* precision floating point numbers, in the meantime I realized, that it's cos() function only returns *double* precision floating point numbers. > In my fraction lib, I considers implementing "special" values, which would be > interpreted as common "irrational" constants Does this mean, that your lib can handle symbols? I mean, for instance, can your lib cancel an expression such as "PI*7/PI" to get the exact result "7" directly? That would be cool. > (such as PI, tho apparently PI isn't irrational iirc). PI *is* irrational, that means it cannot be expressed as a fraction p/q for any integers p and q. However, there are rational approximations for PI, of course. My favourite is the following, which also is easy to memorize: 355/113 = 3.14159292... Althogh this "formula" is very simple, it gives a correct value for PI to 6 decimal places! <snip> [Eu function isnan()] > Interesting. I'll test it out. Very nice, thank you! <snip> >>> At least my way (using -1), it becomes more of a habit. >> >> I normally also use -1, if possible. > > As do the libc functions. Like (I think) I said, I borrowed this practice > from C programming in Linux. AFAIR I borrowed it from Euphoria and/or from you. Unfortunately, Euphoria is somewhat inconsistent in this regard. The following text is from the Euphoria 2.3 docs: * "i1 = define_c_func(a, s1, s2, i2) -1 will be returned if the function can't be found." * "i1 = define_c_proc(a, s1, s2) -1 will be returned if the function can't be found." * "x = dir(st) If there is no file or directory with the name st then -1 is returned." * "i = get_key() Return -1 if no key was pressed." * "x1 = get_mouse() Return -1 if there has not been a mouse event since the last time get_mouse() was called." * "i = getc(fn) -1 is returned at end of file." * "x = getenv(s) If the variable is undefined return -1." * "x = gets(fn) -1 is returned on end of file." * "fn = open(st1, st2) -1 is returned if the open fails." * "i = routine_id(st) -1 is returned if the named routine can't be found." * "i1 = system_exec(st, i2) If it is not possible to run the program, system_exec() will return -1." ---=-------------=--- * "a = allocate(i) Return 0 if the memory can't be allocated." * "i2 = allocate_low(i1) Return 0 if the memory can't be allocated." * "a = allocate_string(s) If there is not enough memory available, 0 will be returned." * "a = open_dll(st) 0 will be returned if the .dll (or .so) can't be found." IMHO it would be more elegant, if allocate() allocate_low() allocate_string() open_dll() also would return -1, rather than 0. Best regards, Juergen -- /"\ ASCII ribbon campain | while not asleep do \ / against HTML in | sheep += 1 X e-mail and news, | end while / \ and unneeded MIME |