1. strong typing and error handling
- Posted by Peter Willems <peter at integratedmoves.com> Jun 27, 2003
- 408 views
Maybe I'm shooting myself in the foot here, but.... One of the things in Eu that I really like is the rule-like variable typing that let us set boundaries for a variable. But it seems to me that the absense of an error-handler makes this close to useless because when I try to load a value into a variable that is outside it's boundaries, it exits the app with an error message. Thus I need to have my app check anyway when putting values into vars to prevent my app from exiting, so when I have to check var boundaries myself, what does the option to set boundaries when defining a var does for me ? Or do I mis something and IS it possible to capture boundary overflow (or underflow) in a simple way so I can write a simpe error-handler ? Hans Peter Willems
2. Re: strong typing and error handling
- Posted by gertie at visionsix.com Jun 27, 2003
- 365 views
On 27 Jun 2003, at 7:55, Peter Willems wrote: > > > Maybe I'm shooting myself in the foot here, but.... > > One of the things in Eu that I really like is the rule-like > variable typing that let us set boundaries for a variable. > But it seems to me that the absense of an error-handler makes > this close to useless because when I try to load a value into > a variable that is outside it's boundaries, it exits the app > with an error message. Thus I need to have my app check anyway > when putting values into vars to prevent my app from exiting, > so when I have to check var boundaries myself, what does the > option to set boundaries when defining a var does for me ? > > Or do I mis something and IS it possible to capture boundary > overflow (or underflow) in a simple way so I can write a simpe > error-handler ? You set your own type, which Eu will execute whenever you assign something to the var. Inside the typecast code, you check it's bounds. There is info on user-defined typecasting in Eu's help docs, but i don't know how to tell you where they are. Scroll down to this line in String.e for an example: global type string_type(object x) Kat
3. Re: strong typing and error handling
- Posted by Derek Parnell <ddparnell at bigpond.com> Jun 27, 2003
- 377 views
On Fri, 27 Jun 2003 07:55:08 +0000 (06/27/03 17:55:08) , Peter Willems <peter at integratedmoves.com> wrote: > > > Maybe I'm shooting myself in the foot here, but.... > > One of the things in Eu that I really like is the rule-like > variable typing that let us set boundaries for a variable. > But it seems to me that the absense of an error-handler makes > this close to useless because when I try to load a value into > a variable that is outside it's boundaries, it exits the app > with an error message. Thus I need to have my app check anyway > when putting values into vars to prevent my app from exiting, > so when I have to check var boundaries myself, what does the > option to set boundaries when defining a var does for me ? > > Or do I mis something and IS it possible to capture boundary > overflow (or underflow) in a simple way so I can write a simpe > error-handler ? > You can almost do this, so long as you don't mind not having access to any meta-data. procedure logerr(sequence msg, object data) printf(2, "Type Failure: %s\n", {msg}) pretty_print(2, data, {3}) end procedure global type Customer(object x) if not sequence(x) then logerr("Customer Type must be a sequence.", x) return 1 -- Return to app end if if length(x) != 5 then logerr("Customer Type must have 5 fields.", x) return 1 -- Return to app end if ...etc... return 1 end type So long as you always return non-zero from a type definition, your application won't crash with a 'type' error. If you don't mind it crashing when an assignment is made you do this... sequence vTypeDefCrash vTypeDefCrash = {0} procedure SetTypeDefCrash( object NewVal) if sequence(NewVal) then if length(vTypeDefCrash) > 1 then vTypeDefCrash = vTypeDefCrash[2..length(vTypeDefCrash)] return end if else vTypeDefCrash = NewVal & vTypeDefCrash end if end procedure global type Customer(object x) if not sequence(x) then logerr("Customer Type must be a sequence.", x) return vTypeDefCrash[1] end if if length(x) != 5 then logerr("Customer Type must have 5 fields.", x) return vTypeDefCrash[1] end if ...etc... return 1 end type So that by default it would crash except when you don't want it to crash during a certain part of you code... SetTypeDefCrash(1) -- Turn on crash avoidance . . . -- critical code SetTypeDefCrash("") -- Restore it to whatever it was. Unfortunately, you can't tell the user what line of code this was on, or the name of the variable, or even what source file it was in. -- cheers, Derek Parnell
4. Re: strong typing and error handling
- Posted by eugtk at yahoo.com Jun 27, 2003
- 400 views
--- Peter Willems <peter at integratedmoves.com> wrote: > > > Maybe I'm shooting myself in the foot here, but.... > > One of the things in Eu that I really like is the > rule-like > variable typing that let us set boundaries for a > variable. > But it seems to me that the absense of an > error-handler makes > this close to useless because when I try to load a > value into > a variable that is outside it's boundaries, it exits > the app > with an error message. Thus I need to have my app > check anyway > when putting values into vars to prevent my app from > exiting, > so when I have to check var boundaries myself, what > does the > option to set boundaries when defining a var does > for me ? > > Or do I mis something and IS it possible to capture > boundary > overflow (or underflow) in a simple way so I can > write a simpe > error-handler ? You can use type() to trap invalid assignments, but unfortunately there's no reasonable way to _fix_ the invalid data and continue on. When encountering bad data, your choices are: 1. end the program - at least you have the option to log the error and perhaps clean up files, etc before ending. 2. ignore the bad data, and let the program forge ahead until the bad data fails to pass some built-in type checking, or causes data corruption - whichever comes first. Since type() can only return TRUE or FALSE, and cannot modify the data being checked, it's usefulness is about 10% of what it would be if it had been designed correctly. Because type() is nothing more than a function called automatically _on assignment_, we should be able to use it to FIX most errors and return a correct data value. We might even call, from within the type() function, a routine to notify the user about the bad data, and have them re-input the correct data. Sadly, we don't have those options, so you may just as well go ahead and write do the type checking yourself. And if we can have a function which is automatically called on assignment, why can we not also have a function which is automatically called on reference? Regards
5. Re: strong typing and error handling
- Posted by Mike Nelson <MichaelANelson at WORLDNET.ATT.NET> Jun 27, 2003
- 384 views
Until such time as Euphoria has pass-by-reference, there is a nasty workaround for types that will only be used for a few variables--its impractical for programs with hundereds of variables. Let's assume we want to have variables that will reject a sequence, but modify any atom to coerce its value to an integer between 1 and 10. -- this code needs to be written only once function coerce(object x) if atom(x) then x=floor(x) if x<min then x=1 end if if x>max then x=10 end if end if return x end function -- the code from here on is repeated for EACH variable integer SET_A type a_object(object x) object y y=coerce(x) if not equal(x,y) then call_proc(set_a,{y}) end if return integer(x) end type a_object a procedure set_a(object x) a=x end procedure SET_A=routine_id("set_a") This is a huge amount of overhead to simulate pass by reference, but it does work. I wish Rob would relent on pass by refernece for types at least --preferably for all routines. Wouldn't we all prefer to code the above as: type int1to10(by_ref object x) if sequence(x) then return 0 end if x=floor(x) if x<1 then x=10 end if if x>10 then x=10 end if return 1 end type int1to10 a,b,c,d,e For the OpenEU team, I would suggest two keywords that would be allowable only before a type specifier in a parameter list: by_ref and by_val (by_val for documentation: pass by value would and should be the default -- VB defaulting to ByRef is really, really bad). -- Mike Nelson
6. Re: strong typing and error handling
- Posted by Pete Lomax <petelomax at blueyonder.co.uk> Jun 27, 2003
- 364 views
On Fri, 27 Jun 2003 18:56:33 +1000, Derek Parnell <ddparnell at bigpond.com> wrote: WOW, Derek you blew my fuse... > > >On Fri, 27 Jun 2003 07:55:08 +0000 (06/27/03 17:55:08) >, Peter Willems <peter at integratedmoves.com> wrote: > >> >> Maybe I'm shooting myself in the foot here, but.... >> >> One of the things in Eu that I really like is the rule-like >> variable typing that let us set boundaries for a variable. >> But it seems to me that the absense of an error-handler makes >> this close to useless because when I try to load a value into >> a variable that is outside it's boundaries, it exits the app >> with an error message. Thus I need to have my app check anyway >> when putting values into vars to prevent my app from exiting, >> so when I have to check var boundaries myself, what does the >> option to set boundaries when defining a var does for me ? >> >> Or do I mis something and IS it possible to capture boundary >> overflow (or underflow) in a simple way so I can write a simpe >> error-handler ? >> > >You can almost do this, so long as you don't mind not having access to = any=20 >meta-data. > > procedure logerr(sequence msg, object data) > printf(2, "Type Failure: %s\n", {msg}) > pretty_print(2, data, {3}) > end procedure > > global type Customer(object x) > > if not sequence(x) then > logerr("Customer Type must be a sequence.", x) > return 1 -- Return to app > end if > > if length(x) !=3D 5 then > logerr("Customer Type must have 5 fields.", x) > return 1 -- Return to app > end if > > ...etc... > > return 1 > end type > > >So long as you always return non-zero from a type definition, your=20 >application won't crash with a 'type' error. Yes, Got that. > >If you don't mind it crashing when an assignment is made you do this... > > sequence vTypeDefCrash > vTypeDefCrash =3D {0} > > procedure SetTypeDefCrash( object NewVal) > if sequence(NewVal) then > if length(vTypeDefCrash) > 1 then > vTypeDefCrash =3D vTypeDefCrash[2..length(vTypeDefCrash)] Help! > return > end if else > vTypeDefCrash =3D NewVal & vTypeDefCrash Ditto! > end if > end procedure > I want to understand here, but I don't > global type Customer(object x) > > if not sequence(x) then > logerr("Customer Type must be a sequence.", x) > return vTypeDefCrash[1] > end if > > if length(x) !=3D 5 then > logerr("Customer Type must have 5 fields.", x) > return vTypeDefCrash[1] > end if > > ...etc... > > return 1 > end type > So that by default it would crash except when you don't want it to = crash=20 >during a certain part of you code... > > SetTypeDefCrash(1) -- Turn on crash avoidance > . . . -- critical code > SetTypeDefCrash("") -- Restore it to whatever it was. > Are you trying to push() and pop() error handling status? >Unfortunately, you can't tell the user what line of code this was on, or= =20 >the name of the variable, or even what source file it was in. -- > >cheers, >Derek Parnell Pete
7. Re: strong typing and error handling
- Posted by Derek Parnell <ddparnell at bigpond.com> Jun 27, 2003
- 379 views
----- Original Message ----- From: "Pete Lomax" <petelomax at blueyonder.co.uk> To: "EUforum" <EUforum at topica.com> Subject: Re: strong typing and error handling > > > On Fri, 27 Jun 2003 18:56:33 +1000, Derek Parnell > <ddparnell at bigpond.com> wrote: > > WOW, Derek you blew my fuse... Sorry about that. Here is a working example of the sort of thing one can do... ------------ include misc.e sequence vTypeDefCrash vTypeDefCrash = {0} sequence vTypeDefMsg vTypeDefMsg = {""} integer vTypeDefErrs vTypeDefErrs = 0 global procedure ShowTypeDefErr(sequence msg, object data) printf(2, "Type Failure: %s\n", {msg}) if length(vTypeDefMsg[1]) > 0 then printf(2, "%s\n", {vTypeDefMsg[1]}) end if pretty_print(2, data, {3}) puts(2,'\n') vTypeDefErrs += 1 end procedure global procedure SetDebugMsg(sequence Msg) vTypeDefMsg[1] = Msg end procedure global procedure SetTypeDefCrash( object NewVal) vTypeDefErrs = 0 if sequence(NewVal) then if length(vTypeDefCrash) > 1 then vTypeDefCrash = vTypeDefCrash[2..length(vTypeDefCrash)] vTypeDefMsg = vTypeDefMsg[2..length(vTypeDefMsg)] return end if else vTypeDefCrash = NewVal & vTypeDefCrash vTypeDefMsg = {""} & vTypeDefMsg end if end procedure global function TypeDefErr() return vTypeDefErrs end function global type Customer(object x) if not sequence(x) then ShowTypeDefErr("Customer Type must be a sequence.", x) return vTypeDefCrash[1] end if if length(x) != 5 then ShowTypeDefErr("Customer Type must have 5 fields.", x) return vTypeDefCrash[1] end if return 1 end type Customer x SetTypeDefCrash(1) -- Turn on crash avoidance SetDebugMsg("Test #1") -- This should not crash. x = 0 SetDebugMsg("Test #2") -- This should not crash. x = {1,1,1,1} -- See if there were any errors found if TypeDefErr() > 0 then printf(1, "Number of Errors = %d\n", TypeDefErr()) end if SetTypeDefCrash("") -- Restore it to whatever it was. -- Program should crash this time. x = {1,1,1,1} ------------ Derek
8. Re: strong typing and error handling
- Posted by jbrown105 at speedymail.org Jun 28, 2003
- 369 views
On Fri, Jun 27, 2003 at 09:03:04AM -0700, Mike Nelson wrote: > <snip> > > For the OpenEU team, I would suggest two keywords that would be allowable > only before a type specifier in a parameter list: by_ref and by_val (by_val > for documentation: pass by value would and should be the default -- VB > defaulting to ByRef is really, really bad). > > -- Mike Nelson > I'm not sure where things stand on the pass-by-reference front ... iirc there was talk about it but i don't know what the result is. As for types specificly, you will be able to create sequences (and arrays) of a specific type (a sequence of integers, a 30 length array of user_type) and use "bag" to get a mix of types. These will internally be checked per element instead of the entire thing (as you'd have to do currently in RDSEu). Its not hard to imagine this being extended to user-defined types, I suppose. 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 | http://verify.stanford.edu/evote.html