1. Crash or return forbidden value?

CChris posed the question. I always have a tough time with this one. I can give
a few examples:

1. Open a file that does not exist. Well, the user may wish to try a different
file. Error code.

2. Connect to a database server fails. Error code, as you may have given
incorrect login credentials by user input and want to prompt the user for the
username/password again.

3. Requesting an out of bounds index for a given sequence. Crash. This tends to
be a programmers fault, not a users fault. The methods find_from, rfind_from,
etc... do this.

Now, translate that into a set of rules? Hm. Any thoughts? There seems to be
some theme going on of "testing the waters" vs. "do this just as I say", but I'm
not sure.

This is a good topic, thanks Chris for posing the question.

--
Jeremy Cowgar
http://jeremy.cowgar.com

new topic     » topic index » view message » categorize

2. Re: Crash or return forbidden value?

Jeremy Cowgar wrote:
> 
> CChris posed the question. I always have a tough time with this one. I can
> give
> a few examples:
> 
> 1. Open a file that does not exist. Well, the user may wish to try a different
> file. Error code.

Ask user if they want to create the file.

> 
> 2. Connect to a database server fails. Error code, as you may have given
> incorrect
> login credentials by user input and want to prompt the user for the
> username/password
> again.
> 

Connecting to a database should start out asking the user to login,

therefore the user would know their login failed.

> 3. Requesting an out of bounds index for a given sequence. Crash. This tends
> to be a programmers fault, not a users fault. The methods find_from,
> rfind_from,
> etc... do this.

The programmer should be doing any necessary bounds checking ?

> 
> Now, translate that into a set of rules? Hm. Any thoughts? There seems to be
> some theme going on of "testing the waters" vs. "do this just as I say", but
> I'm not sure.
> 
> This is a good topic, thanks Chris for posing the question.
> 
> --


Bernie

My files in archive:
WMOTOR, XMOTOR, W32ENGIN, MIXEDLIB, EU_ENGIN, WIN32ERU, WIN32API 

Can be downloaded here:
http://www.rapideuphoria.com/cgi-bin/asearch.exu?dos=on&win=on&lnx=on&gen=on&keywords=bernie+ryan

new topic     » goto parent     » topic index » view message » categorize

3. Re: Crash or return forbidden value?

Jeremy Cowgar wrote:
> 
> CChris posed the question. I always have a tough time with this one. I can
> give
> a few examples:
> 
> 1. Open a file that does not exist. Well, the user may wish to try a different
> file. Error code.

That depends on whether the file is opened for writing or for reading. The
tradition is that if the file is opened for writing and it doesn't exist, then it
is created; and if it is opened for reading and it doesn't exist, then a -1 or
something is returned. Perhaps I misunderstand the question.

new topic     » goto parent     » topic index » view message » categorize

4. Re: Crash or return forbidden value?

Bernie Ryan wrote:
> 
> Jeremy Cowgar wrote:
> > 
> > CChris posed the question. I always have a tough time with this one. I can
> > give
> > a few examples:
> > 
> > 1. Open a file that does not exist. Well, the user may wish to try a
> > different
> > file. Error code.
> 
> Ask user if they want to create the file.
> 
> > 
> > 2. Connect to a database server fails. Error code, as you may have given
> > incorrect
> > login credentials by user input and want to prompt the user for the
> > username/password
> > again.
> > 
> 
> Connecting to a database should start out asking the user to login,
> 
> therefore the user would know their login failed.
> 
> > 3. Requesting an out of bounds index for a given sequence. Crash. This tends
> > to be a programmers fault, not a users fault. The methods find_from,
> > rfind_from,
> > etc... do this.
> 
> The programmer should be doing any necessary bounds checking ?
> 

Why do it twice, since the backend always cjecks? There should be some sort of
runtime warning, because it may be a program bug. But if the only point is to
exit a loop when there is nothing left to process, let's use the logic built into
the interpreter, rather than duplicationg it.

CChris

> > 
> > Now, translate that into a set of rules? Hm. Any thoughts? There seems to be
> > some theme going on of "testing the waters" vs. "do this just as I say", but
> > I'm not sure.
> > 
> > This is a good topic, thanks Chris for posing the question.
> > 
> > --
> 
> 
> Bernie
> 
> My files in archive:
> WMOTOR, XMOTOR, W32ENGIN, MIXEDLIB, EU_ENGIN, WIN32ERU, WIN32API 
> 
> Can be downloaded here:
> <a
> href="http://www.rapideuphoria.com/cgi-bin/asearch.exu?dos=on&win=on&lnx=on&gen=on&keywords=bernie+ryan">http://www.rapideuphoria.com/cgi-bin/asearch.exu?dos=on&win=on&lnx=on&gen=on&keywords=bernie+ryan</a>

new topic     » goto parent     » topic index » view message » categorize

5. Re: Crash or return forbidden value?

CChris wrote:
> 
> 
> Why do it twice, since the backend always cjecks? There should be some sort
> of runtime warning, because it may be a program bug. But if the only point is
> to exit a loop when there is nothing left to process, let's use the logic
> built
> into the interpreter, rather than duplicationg it.
> 

CChris:

   Checking a sequence ony reports that a sequence is out of bounds; It

   is worthless it only gives a message that a sequence of a length 999

   using an index of 1000 failed.

   NO mention of which sequence caused the error. 

   IF you look at the ex.err to see what sequence failed,

   it prints out all long sequences chopped off with ...

   How is this usefull. 

 
Bernie

My files in archive:
WMOTOR, XMOTOR, W32ENGIN, MIXEDLIB, EU_ENGIN, WIN32ERU, WIN32API 

Can be downloaded here:
http://www.rapideuphoria.com/cgi-bin/asearch.exu?dos=on&win=on&lnx=on&gen=on&keywords=bernie+ryan

new topic     » goto parent     » topic index » view message » categorize

6. Re: Crash or return forbidden value?

Bernie Ryan wrote:
> 
> Jeremy Cowgar wrote:
> > 
> > CChris posed the question. I always have a tough time with this one. I can
> > give
> > a few examples:
> > 
> > 1. Open a file that does not exist. Well, the user may wish to try a
> > different
> > file. Error code.
> 
> Ask user if they want to create the file.

Correct, no crash, open() returns an error code and the app deals with it.

> > 
> > 2. Connect to a database server fails. Error code, as you may have given
> > incorrect
> > login credentials by user input and want to prompt the user for the
> > username/password
> > again.
> > 
> 
> Connecting to a database should start out asking the user to login,
> 
> therefore the user would know their login failed.
> 
> > 3. Requesting an out of bounds index for a given sequence. Crash. This tends
> > to be a programmers fault, not a users fault. The methods find_from,
> > rfind_from,
> > etc... do this.
> 
> The programmer should be doing any necessary bounds checking ?

I am always testing for 
if sequence()  
if length()
if length() > index
if index > 0 
etc etc. when in my opinion, Eu could be more tolerant and return logical
results:

s = "qwerty"
a = 12
return s[11] -- returns ""
return s[1..45] -- returns s
return s[-1] -- returns ""
if s then -- this works
if a = s then -- cannot possibly be true, but don't crash!

etc.

Kat

new topic     » goto parent     » topic index » view message » categorize

7. Re: Crash or return forbidden value?

CChris wrote:
> 
> Bernie Ryan wrote:
> > 
> > > 3. Requesting an out of bounds index for a given sequence. Crash. This
> > > tends
> > > to be a programmers fault, not a users fault. The methods find_from,
> > > rfind_from,
> > > etc... do this.
> > 
> > The programmer should be doing any necessary bounds checking ?
> > 
> 
> Why do it twice, since the backend always cjecks? There should be some sort
> of runtime warning, because it may be a program bug. But if the only point
> is to exit a loop when there is nothing left to process, let's use the 
> logic built into the interpreter, rather than duplicationg it.

Maybe we're thinking about widely different things, but I can't figure out
what you mean here.  But maybe you want to check, because it tells you some
data is bad.  That doesn't mean that you have to crash, just that you should
stop processing, or whatever.  Can you explain what you mean here?

Matt

new topic     » goto parent     » topic index » view message » categorize

8. Re: Crash or return forbidden value?

Matt Lewis wrote:
> 
> CChris wrote:
> > 
> > Bernie Ryan wrote:
> > > 
> > > > 3. Requesting an out of bounds index for a given sequence. Crash. This
> > > > tends
> > > > to be a programmers fault, not a users fault. The methods find_from,
> > > > rfind_from,
> > > > etc... do this.
> > > 
> > > The programmer should be doing any necessary bounds checking ?
> > > 
> > 
> > Why do it twice, since the backend always cjecks? There should be some sort
> > of runtime warning, because it may be a program bug. But if the only point
> > is to exit a loop when there is nothing left to process, let's use the 
> > logic built into the interpreter, rather than duplicationg it.
> 
> Maybe we're thinking about widely different things, but I can't figure out
> what you mean here.  But maybe you want to check, because it tells you some
> data is bad.  That doesn't mean that you have to crash, just that you should
> stop processing, or whatever.  Can you explain what you mean here?
> 
> Matt

Various algorithms end simply when there is nothing left to do. This usually
corresponds to either an empty slice - this is not a problem and needs be tested
for anyway -, an invalid slice or an out of bounds sequence index (typically 0 or
length(s)+1).

In such cases, the invalid condition simply marks the end of the validity span
of some computation. The processed data may or may not be bad.

Currently, the interpreter always checks the validity of any index or slice, and
errors out whenever a test fails.

My point is: there is no need to duplicate the testing made by the interpreter,
and it should do the testing. Just allow RTFatal() to do something smarter, like
skipping the call or branching to some place. This would make the user code more
efficient (no duplicate tests) and cleaner, as part of the error handling will
simply be in the backand, where it is already.

CChris

new topic     » goto parent     » topic index » view message » categorize

9. Re: Crash or return forbidden value?

CChris wrote:
> 
> Currently, the interpreter always checks the validity of any index or slice,
> and errors out whenever a test fails.
> 
> My point is: there is no need to duplicate the testing made by the
> interpreter,
> and it should do the testing. Just allow RTFatal() to do something smarter,
> like skipping the call or branching to some place. This would make the user
> code more efficient (no duplicate tests) and cleaner, as part of the error
> handling
> will simply be in the backand, where it is already. 
> 
> CChris

What you are talking about here is building an Exception system into the
interpreter.  It would be analogous to try/throw/catch and Exceptions like
in Java or C++.  Perhaps exceptions could be less invasive than adding C++ 
syntax if say some new builtin routines such as a register_exception_routine
were added.  Routines that are passed to that function would get called
in case of exceptions.  There would have to be a special return mechanism
for these functions.  They could return to the offending routine's caller.

You can put in some kind of side effect like syntax keyword:
onexception (s[6] = 4) {
 ..
}


On the other hand, perhaps compiled code could remove the second check
after an if statement.

s[6] = 5 -- check is done to make sure s is a sequence and 6 is a valid index

if sequence(s) and length(s) > 7 then
      s[6] = 5 -- no check is made to make sure s is a sequence for the
                -- the user did it.  Additionally 7 and 6 are constants
                -- so index checking could be eliminated at compile time
                -- too.
end if

Shawn Pringle

new topic     » goto parent     » topic index » view message » categorize

10. Re: Crash or return forbidden value?

Shawn Pringle wrote:
> 
> What you are talking about here is building an Exception system into the
> interpreter.  It would be analogous to try/throw/catch and Exceptions like
> in Java or C++.  Perhaps exceptions could be less invasive than adding C++ 
> syntax if say some new builtin routines such as a register_exception_routine
> were added.  

The problem with this is the exception routine knows nothing about what function
function caused the problem. You could pass a function name, error, etc... but
that still does not help. Nor does it give the ability to recover from anything.

For instance:

function exception_handler(sequence name, sequence msg, integer error)
   ...
end function
regisert_handler(...)

fname = "abc.txt"
f = open(fname, "r") -- abc.txt does not exist, lets say


Now, what is exception_handler suppose to do? It does not know if the app can
recover or how it should recover. However, take this example:

try
    f = open(fname, "r")
catch ex
    if ex[CODE] = ERR_FILE_NOT_EXIST then
        f = open(fname, "w")
        puts(f, "# File created today\n")
    else
        crash("Could not handle exception: %i %s", {ex[CODE], ex[MSG]})
    end if
end try


So... that takes more coding, but it's useful and can do something about the
exception. Sure, the example was not that good as we can handle that now, but
that's the idea.

Ok, an exception system will take a lot of planning and a lot of work. What we
are trying to solve right now what error condition should return an error code
and what error condition should cause a crash?

Many times in Euphoria code, I see ? 1/0 which the programmer feels is an error
that cannot be recovered from, therefore causes a crash to terminate Euphoria
with a ex.err file.

We now have a better way of doing that in 4.0. You can:

crash("Fatal error I cannot recover from. Error in hard drive: %s",
    {hard_drive_name})


So, this keeps a true stack trace, the user is given a realistic error message
(not a divide by zero message), etc... But, the question is, when to use crash()
vs. return an error code. For instance, when opening a file if it does not exist
an error code is returned vs. s="Hello" ? s[500] ... an index out of bounds
causes a crash.

--
Jeremy Cowgar
http://jeremy.cowgar.com

new topic     » goto parent     » topic index » view message » categorize

11. Re: Crash or return forbidden value?

Shawn Pringle wrote:
> 
> CChris wrote:
> > 
> > Currently, the interpreter always checks the validity of any index or slice,
> > and errors out whenever a test fails.
> > 
> > My point is: there is no need to duplicate the testing made by the
> > interpreter,
> > and it should do the testing. Just allow RTFatal() to do something smarter,
> > like skipping the call or branching to some place. This would make the user
> > code more efficient (no duplicate tests) and cleaner, as part of the error
> > handling
> > will simply be in the backand, where it is already. 
> > 
> > CChris
> 
> What you are talking about here is building an Exception system into the
> interpreter. 

Exactly. In an earlier post, I was showing how Eiffel does it - simpler, but
less flexible.

 It would be analogous to try/throw/catch and Exceptions like
> in Java or C++.  Perhaps exceptions could be less invasive than adding C++ 
> syntax if say some new builtin routines such as a register_exception_routine
> were added.  Routines that are passed to that function would get called
> in case of exceptions.  There would have to be a special return mechanism
> for these functions.  They could return to the offending routine's caller.

Either the calling statement (retry) or the next one. Both have separate uses.

> 
> You can put in some kind of side effect like syntax keyword:
> onexception (s[6] = 4) {
>  ..
> }
> 
> 
> On the other hand, perhaps compiled code could remove the second check
> after an if statement.
> 
> s[6] = 5 -- check is done to make sure s is a sequence and 6 is a valid index
> 
> if sequence(s) and length(s) > 7 then
>       s[6] = 5 -- no check is made to make sure s is a sequence for the
>                 -- the user did it.  Additionally 7 and 6 are constants
>                 -- so index checking could be eliminated at compile time
>                 -- too.
> end if
> 
> Shawn Pringle

CChris

new topic     » goto parent     » topic index » view message » categorize

12. Re: Crash or return forbidden value?

We shouldn't assume anything about the system outside of EUPHORIA.  Files and 
DLLs may or may not exist.  They return dummy data (that is the 
term I learned for 'forbidden values' ).  However, when the programmer 
user tries to index data that isn't assigned(variable has no value error) or 
doesn't exist(index error) then this shows a big problem in the code 
and what happens next if we allow this is the code will crash later
continuing to do unsensible things or worse: corrupt a user's data file.

For example, we do assume that if the programmer EUPHORIA code writes 
d[D_NAME] he knows this works and under no circumstances does he want
dummy data.  Even if d is not a valid dir() entry.  Suppose you code:
d = dir("\foo") and then try to use d[D_NAME].  If you have a small number
of files you will get an error.  The programmer has not coded what he
has intended.  If there are at least D_NAME files in \foo then as soon
the programmer passes d[D_NAME] into open() the program will die.  

I know this is rather subjective, but I think the implementation of
open is a sensible balance between dummy values vs. crashing.  If
the expression is not sensible, crash.  If it is sensible but
not valid in the system outside (the OS, the Internet) return dummy.

For example: open_dll returns dummy -1.


Here is a sample program I would write demonstrating how I set things
up:

include joy.e as joy
print(1, joy:min( {5,3} ) ) -- prints 5
print(1, joy:min( 5 ) ) -- error min takes a sequence
print(1, joy:min({}) ) -- runtime error since min({}) 
-- has no mathematical meaning in real numbers.  (Don't tell me about infinity)

Some people would have a min such that min({}) returns -1000000000 but to
me min({}) shouldn't be a defined value.

Shawn Pringle

new topic     » goto parent     » topic index » view message » categorize

13. Re: Crash or return forbidden value?

My take on this is that it is entirely context-dependent, since Euphoria does
not have an exception system and is unlikely to get one any time soon.

Some cases, such as has been mentioned with open() either create a new file or
return with -1 which is known to be an invalid file handle. Other
functions/procedures should return error values if it makes sense to do so and if
it is possible (that is, there is an error value that is recognized as such and
not as a valid return value).

For functions and procedures that will definitely crash given erroneous input,
it is the responsibility of the programmer to validate the input before calling
the function/procedure.

Basically, status quo ante. Unless and until some form of exception system has
been designed.

--
A complex system that works is invariably found to have evolved from a simple
system that works.
--John Gall's 15th law of Systemantics.

"Premature optimization is the root of all evil in programming."
--C.A.R. Hoare

j.

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu