1. RE: pass by reference
- Posted by Bernie Ryan <xotron at localnet.com> Feb 12, 2002
- 536 views
Irv Mullins wrote: > er...no, that's pass-by-value. > If I call foo(integer x) as follows: > > x = 3 > foo(x) > ? x => 3 > > No matter what happens inside the mysterious foo, x is still what it was > > before calling the function. > Even if foo sets x to 99, it's only 99 while inside the foo routine. > So foo is working with a copy of x, not the real x. > > Pass-by_reference passes the actual variable, not a copy, so that atom addr_of_x addr_of_x = allocate(4) > foo(var integer x) > x = 99 > end procedure foo(atom addr_of_x) poke4(addr_of_x,99) end procedure > foo(x) > ? x => 99 foo(addr_of_x) ? peek4u(addr_of_x) => 99 > > The variable IS changed within the routine, and remains changed > afterward. yes Regards, Bernie
2. RE: pass by reference
- Posted by bensler at mail.com Feb 19, 2002
- 491 views
I was one of the people who suggested pass by referencing. Here's my thoughts. Why on EARTH do I want to type check my variables only to make my program crash 'elegantly', albeit better than the current alternative(no type checks). With reference passing, I could type check my variable, and when it's out of bounds, I could modify it, or set it to a default value. IMHO, if I'm going to sacrifice some speed to use typechecking in my program, it should be to safeguard my program, not just give a little bit more useful error info. You COULD do it with pointers(shudder), but that is a lot of places where you might have to add allocations, deallocations, peeks and pokes. It also means you would have to do double typechecking. First using a generic typecast, and then a secondary typecheck within the routine. Bernie Ryan wrote: > > I keep reading that you can't use pass by reference > in Euphoria. That is not true. You can use pass by > reference on any variable or atom or any fixed > length structure. The only thing you can't pass by > reference is a sequence because it is dynamic and > there is no way to control the errors that would > be caused by a user. The way you pass by reference > is to use allocates, peeks and pokes. > > Bernie > >
3. RE: pass by reference
- Posted by Kat <gertie at PELL.NET> Feb 19, 2002
- 507 views
Wouldn't the PassByReference camp be satisfied with a table of the vars? And maybe a table of the functions, like routine_id()s for everything? I have a feeling this already exists in Eu, but we don't have access to it. Then, with exception handling, you could check whatever vars you wanted, and do whatever you need to do with them. Kat On 20 Feb 2002, at 2:23, bensler at mail.com wrote: > > I was one of the people who suggested pass by referencing. > > Here's my thoughts. > Why on EARTH do I want to type check my variables only to make my > program crash 'elegantly', albeit better than the current alternative(no > type checks). > With reference passing, I could type check my variable, and when it's > out of bounds, I could modify it, or set it to a default value. > IMHO, if I'm going to sacrifice some speed to use typechecking in my > program, it should be to safeguard my program, not just give a little > bit more useful error info. > > You COULD do it with pointers(shudder), but that is a lot of places > where you might have to add allocations, deallocations, peeks and pokes. > It also means you would have to do double typechecking. First using a > generic typecast, and then a secondary typecheck within the routine. > > Bernie Ryan wrote: > > > > I keep reading that you can't use pass by reference > > in Euphoria. That is not true. You can use pass by > > reference on any variable or atom or any fixed > > length structure. The only thing you can't pass by > > reference is a sequence because it is dynamic and > > there is no way to control the errors that would > > be caused by a user. The way you pass by reference > > is to use allocates, peeks and pokes. > > > > Bernie > > > > > > >
4. Re: RE: pass by reference
- Posted by Derek Parnell <ddparnell at bigpond.com> Feb 19, 2002
- 488 views
20/02/2002 1:23:04 PM, bensler at mail.com wrote: > >I was one of the people who suggested pass by referencing. > >Here's my thoughts. >Why on EARTH do I want to type check my variables only to make my >program crash 'elegantly', albeit better than the current alternative(no >type checks). >With reference passing, I could type check my variable, and when it's >out of bounds, I could modify it, or set it to a default value. >IMHO, if I'm going to sacrifice some speed to use typechecking in my >program, it should be to safeguard my program, not just give a little >bit more useful error info. > >You COULD do it with pointers(shudder), but that is a lot of places >where you might have to add allocations, deallocations, peeks and pokes. >It also means you would have to do double typechecking. First using a >generic typecast, and then a secondary typecheck within the routine. > Chris, from this description is sounds like the problems you are trying to solve are: (1) Sometimes, variables are used without being initialized. (2) Sometimes, variables are used that contain out-of-bounds data. (3) Sometimes, variables are used that are of the wrong data type. (4) Sometimes, sequence are used that have the wrong number, or type, of elements. and you speculate that the type checking mechanism might be a convenient way to resolve these, so long as we can modify the variable being typechecked, inside the typecheck routine itself. Have I understood you correctly? If so, I have also want this type of functionality. It shouldn't add too much overhead to the interpreter as it would only be used where user-defined type checking is being used. And as is would be restricted to only the variable being type checked, which is when the variable is being assigned to anyway, it wouldn't add any unexpected side-effects. The other thing you might want to add is the ability to detect at run time, whether or not a variable has been initialized. I can imagine something like: ------------- type TextLine(object x) if not initialized(x) then x = {} elsif atom(x) then if x = -1 then -- Mark EOF with an empty sequence. x = {} else crash_message("TextLine must be a string or -1") return 0 end if else for i = 1 to length(x) do if sequence(x[i]) then crash_message("TextLine must not have substrings") return 0 elsif not integer(x[i]) then crash_message("TextLine must only contain integers") return 0 elsif x[i] < 0 or x[i] > 255 then crash_message("TextLine must only contain bytes") return 0 end if end for end if return 1 end type TextLine inputdata inputdata = gets(f) while length(inputdata) > 0 do . . . inputdata = gets(f) end while ---------- cheers, Derek. --------- Cheers, Derek Parnell
5. Re: RE: pass by reference
- Posted by Derek Parnell <ddparnell at bigpond.com> Feb 19, 2002
- 493 views
20/02/2002 2:21:46 PM, Kat <gertie at PELL.NET> wrote: > >Wouldn't the PassByReference camp be satisfied with a table of the vars? >And maybe a table of the functions, like routine_id()s for everything? I have a > >feeling this already exists in Eu, but we don't have access to it. Then, with >exception handling, you could check whatever vars you wanted, and do >whatever you need to do with them. > I can see where you are going here. Something like variable_id() that would return a reference to the variable. This idea seems nice but it also creates other side-effects. For example, what exactly would it return? Currently routine_id() returns an integer. If variable_id() returned an integer, how would we distinguish between an integer and a data reference in the routine it was passed to. procedure ProcA( integer x) . . . end procedure -- This might cause bugs. ProcA(1) -- This might not be right either? ProcA( variable_id(x) ) One solution is to create a new datatype, say a 'reference'. Then we could do: procedure ProcA( reference x) . . . end procedure -- This would fail due to datatype mismatch. ProcA(1) -- This would be fine. ProcA( variable_id(x) ) But a new datatype would create new overheads in the interpreter. Everywhere it currently validates datatypes, it would have to add another check. We would probably also need a reference() function similar to sequence() etc... However, a reference datatype would still enable Eu automatic garbage collection and memory allocation to work. It would still not allow direct access to a variable's RAM, but that could be argued as a good thing. We could do things like: sequence A, B integer C reference x,y C = 1 x = variable_id(C) x = 0 -- Change C to zero. A = "foo" B = "bar" x = variable_id(A) y = variable_id(B) B = x -- Copy A to B x = "moo" -- Change A to "moo" x[3] = 'p' -- Change A to "mop" function swap (reference a, reference b) object temp if ( (atom(a) and atom(b)) or (sequence(a) and sequence(b)) or (reference(a) and reference(b)) ) then temp = a a = b b = temp return 1 else return 0 end if end function C = swap (x, y) -- now A is "bar" and B is "mop" C = swap (variable_id(A), variable_id(B)) -- now B is "bar" and A is "mop" C = swap (variable_id(x), variable_id(y)) -- now x refers to B, and y refers to A. ------------- These are not show-stoppers, just things to weigh up in the scheme of things. Sure would make OO a lot easier to implement. Of course, if you didn't want a routine to change you're data, if passed by reference, you should be able to enclosed it in parenthesis to have Eu create a temporary copy of the data before passing it. sequence X ProcA ( (variable_id(x)) ) then if ProcA tried to modify the variable, it would only modify the temporary copy and not the original. -------- cheers, Derek
6. Re: RE: pass by reference
- Posted by Kat <gertie at PELL.NET> Feb 19, 2002
- 483 views
On 20 Feb 2002, at 16:36, Derek Parnell wrote: > > 20/02/2002 2:21:46 PM, Kat <gertie at PELL.NET> wrote: > > > > >Wouldn't the PassByReference camp be satisfied with a table of the vars? > >And maybe a table of the functions, like routine_id()s for everything? I have > >a > > feeling this already exists in Eu, but we don't have access to it. Then, > > with > >exception handling, you could check whatever vars you wanted, and do whatever > >you need to do with them. > > > > I can see where you are going here. Something like variable_id() that would > return a reference to the variable. This idea seems nice but it also creates > other side-effects. For example, what exactly would it return? Currently > routine_id() returns an integer. If variable_id() returned an integer, how > would > we distinguish between an integer and a data reference in the routine it was > passed to. With the perfect variable package: the nested sequence! Vars have 3 things we are interested in: 1) the var name 2) the var type 3) the var's contents (yes!) maybe the location of the var in memory would be a bad thing, all things considered. So, pass a nested sequence of {s name , s type}, so one could do: s = getvar(1) -- s = {"data","s"} i = getvar(0)) -- how many vars? while loop = 1 to getvars(0) do if equal(getvar(loop)[2],"s") -- not "ns"! then puts(1,getvar(loop)[1] ) end if end while This might be nice: if accessed(varname) then run some method on it here end if Kat
7. RE: pass by reference
- Posted by bensler at mail.com Feb 20, 2002
- 470 views
I think you misunderstood, The question was not "Why would I want to use typechecking", but "why would I want to use typechecking to make my program crash" Typechecking would make more sense if we could modify the variable in question. Alot of the times, you would be able to change the variable being typechecked to a default value. This would save your program from crashing. As a customer who purchases software, I would be appalled to run a program that I paid money for, to have it crash with some error message that doesn't help me at all. Reminds me of Microsoft :P It makes alot more sense to at least ATTEMPT to rectify the problem before resorting to the BLACK screen of death. Let's face it. EVEN IF you write a program that is 100% error free, it's usually the user who is the cause of the error. And if I'm distributing a program, I want to be sure that I can minimize any program/user errors. There are lots of other uses for typechecks that can mutate it's variable. For example: In exoticaX, I have incorperated the ability to pass either a RGB sequence, OR a color value (atom) to the routines. The routines, in turn, have to determine if it's RGB or a Color value, and convert it if nessecary. There are about 50 or more routines in exotica which take a color parameter. That's about 50 lines or more of mundane code to type and make typing mistakes in. If I could mutate the variable from a type check, all I would need is a type defined like this: type color(object c) if sequence(c) then c = make_rgb(c) end if return 1 end type and then in my routines, all I need is this: procedure some_routine(color c) end procedure I should say, that my suggestion is to have pass by reference ONLY for type checking, not general routines. Like goto, pass by reference, CAN be a good thing, but on the whole, I think it's more detrimental than helpful. Makes for lots of oversights, having to check if a routine is going to modify the variable you pass it or not. Pass by reference isn't nessecary for routines, as you can just use a function. It's alot safer and easier to understand/read. Chris tone.skoda at siol.net wrote: > > ----- Original Message ----- > From: <bensler at mail.com> > > > Why on EARTH do I want to type check my variables only to make my > > program crash 'elegantly', albeit better than the current alternative(no > > type checks). > > With type checking your code fails sooner (when it would fail any way > only > at some other place) and you are closer to the source > of your problem. You find out what's wrong in less time. Faster > debugging. > Same with assert in C. > >
8. RE: pass by reference
- Posted by bensler at mail.com Feb 20, 2002
- 486 views
if EU had a builtin VOID variable, it would solve BOTH of these. Variables would always initialize to VOID (not initialized). atom Test if Test = VOID then -- !! HOLD ON Variable not initialized yet! else ? Test end if Test = VOID -- uninitialize it You should also be allowed to use it for dumping unnessecary function results. I also suggested this about a year or so ago. Chris petelomax at blueyonder.co.uk wrote: > On Wed, 20 Feb 2002 15:41:23 +1100, Derek Parnell > <ddparnell at bigpond.com> wrote: > > >The other thing you might want to add is the ability to detect at run > >time, whether or not a > >variable has been initialized. > > OTOH.. > Suppose I am building result_set but then something semi-catastrophic > happens which invalidates everything about result_set, maybe we should > not even have been building result_set, we suddenly realise it is a > condition_set or something. > > Therefore we should uninitialise(result_set) so that if any other part > of the program tries to reference it, it should cause a trap (to be > fair, the interpereter would have to report different errors to avoid > confusion). > > Just a thought, doubt any milage in it, - might it have useful > application in a multi-threaded environment? > > Pete > >
9. RE: pass by reference
- Posted by bensler at mail.com Feb 22, 2002
- 470 views
<SNIP> > for testing purposes (only) Currently, yes, that's all that typechecks are good for. <SNIP> > >As a customer who purchases software, I would be appalled to run a > >program that I paid money for, to have it crash with some error message > >that doesn't help me at all. Reminds me of Microsoft :P This was a fairly inaccurate statement. As is, a program can have extensive error checking AND recovery if wanted. It's just alot of code. With typechecks that modify, one could typically reduce the error checking/recovery code by half if not more. This makes the code more readable, leading to less errors, leading to faster development time. And makes reading 6 month old code alot easier. Getting the code written faster also usually means more time for testing. Writing error checking routines is also boring. When I'm bored, I'm less productive. Error recovery is even more tedious. > > Are you happier if a program you purchased crashes and burns, or if it > does not perform as advertised/is not fit for task? > > If I spend say 2 hours typing in stuff & the program crashes and > burns, losing all my stuff, then I am NOT HAPPY. > > If I spend say 2 hours typing in stuff & the program either pops up > some drivel warning or simply wipes all the stuff I was doing, then I > am not just "NOT HAPPY", I am seething with rage at the useless <SNIP> If someone writes an error recovery routine that doesn't fully recover from the error, that's the programmers fault, not the language. Obviously, someone shouldn't write a recovery routine that resets a spreadsheet database to DEAFULT. That's just STUPID, and that programmer should be shot. > If the type check fails so you save loads & loads of stuff for > possible recovery, then good on ya, but if you're gonna write code > that says 'This should never be 9. I don't care how, why or at all, so > I'll just set it back to a nice safe 0", then **** you. > > >It makes alot more sense to at least ATTEMPT to rectify the problem > >before resorting to the BLACK screen of death. > > As above, I fail to see how hiding the cause of the problem can > possibly help. If you suspect there is going to be a problem modifying > variable x then why not make it a private variable in a new include > file with all the routines, checks etc to modify it? YOU just answered your own question. A new include file, ALL the routines/checks, etc.. Not only is it ALOT more code, it's harder to follow AND harder implement. <SNIP> > >If I could mutate the variable from a type check, all I would need is > >a type defined like this: > > > >type color(object c) > > if sequence(c) then c = make_rgb(c) end if > > return 1 > >end type > > That's reasonable, however if you wrap your routines: > > procedure setColour(object c) > xsetColour(mapcolour(c)) > end procedure > > then all is well. Wrap what? There is nothing to wrap. This is what is currently in exoticaX: global function clear_surface(object col) if sequence(col) then col = make_rgb(col) end if return c_func(CLEAR_SURFACE,{col}) end function This is what you propose?: (slightly easier to read, but also slightly slower) global function clear_surface(object col) col = setColor(col) return c_func(CLEAR_SURFACE,{col}) end function This is what I propose: (easier to read) global function clear_surface(color col) return c_func(CLEAR_SURFACE,{col}) end function Want another example? Currently: type phone_number(object x) if not sequence(x) then return 0 end if if length(x) !=7 and length(x) !=10 then return 0 end if for i = 1 to length(x) do if not integer(x[i]) then return 0 end if if x[i] <'0' or x[i] >'9' then return 0 end if end for return 1 end type function format_phone_number(sequence num) -- strip out any hyphens,periods, and parentheses integer found found = find('-',num) if not found then found = find('.',num) end if if not found then found = find('(',num) end if if not found then found = find(')',num) end if if found then num = num[1..found-1]&num[found+1..length(num)] return format_phone_number(num) else return num end if end function function get_phone_number() phone_number num sequence msg msg = "Enter a phone number :" num = 0 while not phone_number(num) do if sequence(num) then msg = "Invalid phone number.\n"&msg end if num = format_phone_number(prompt_string(msg)) end while return num end function I would like to see: type phone_number(object x) sequence msg msg = "Invalid phone number entered.\nEnter a phone number :" if not sequence(x) or ( length(x) !=7 and length(x) !=10) then x = prompt_string(msg) return phone_number(x) else x = format_phone_number(x) -- same routine as above for i = 1 to length(x) do if not integer(x[i]) or x[i] <'0' or x[i] >'9' then x = prompt_string(msg) return phone_number(x) end if end for end if return 1 end type function get_phone_number() phone_number num num = prompt_string("Enter a phone number :") return num end function Both versions function identically(In theory. I didn't test this code), but the latter hides all the formatting and error checking/recovery in the typecheck(IMO, where it belongs), leaving the actual routine clear, precise, and easy to understand. And of course, I can plug that typecheck into any other routine I like, and have it perform the same way. Chris
10. RE: pass by reference
- Posted by bensler at mail.com Feb 23, 2002
- 444 views
No offense to you Everett, but I'm tired of lobbying. Euphoria *has the potential to be* the best language I have found. However, it still feels like basic to me. It's not going anywhere very fast. Rob hasn't expressed much interest in expanding the language. I didn't get into programming to discuss compiler language development, and I didn't pick up euphoria so I could write libraries which most people consider essential. Sure, there is the RDS archives, which is packed full of great stuff, but I don't have or want to spend the time to explore each lib and program to see if it has the routines I'm looking for anymore. The least that RDS could do, if it's not going to add to the language, is offically support essential and proven libraries. Which OOP library should I use if I want to use classes? Where's the string library? Why isn't asm.e shipped with euphoria? Where's peek/poke2? Where is the standard c_struct library? Why hasn't RDS added link_dll(), link_func(), and link_proc() to DLL.E? I've been using euphoria for about 2 years now, so I know the answer to most of these questions, but even with what I know, I am constantly finding useful libraries that I didn't before, and spent days writing for myself. Not too many people are so dedicated. Stamping is one way, but it doesn't seem to be utilized very effectively. There should be a list of recommended libraries, sorted by category and demand. Also, we should be able to filter the archives by stamped files, and sort by money donated(popularity). Rob, I know you are only one person, and it's very difficult, if not near impossible to foster a project of this magnitude on your own, but that's why I think you need to reevaluate your vision of euphoria, as well as consider staffing a development team. Don't have the money to employ anyone? Consider offering royalties from future sales. It's a good incentive for calculated development, and will encourage the developers to try harder to do better as well. I'm sure there are people on this list who would help for free, if only to see euphoria succeed and floruish. I too think that moderation and mediation are essential to develop the language to it's fullest, but there comes a time when you need to compromise. Reducing the price of your product should be a huge indication of your progress. I'm not even concerned if ANY of my suggestions make it into the language or your marketing strategies, but you need to do SOMETHING. In the very least, you need to outline your plan for euphoria's future, so people know what to expect and can make suggestions based on what your stated priorities are. There are a lot of extremely talented people in this community making excellent suggestions, and they seem to be not only unnoticed, but ignored. I will continue to use Euphoria, and hope for it's success, but at this rate, like Irv, I will most likely migrate to a more productive language. The only real reasons I am still here, is because would like to see euphoria do well, and because I love a challenge. Probably more the latter, because as selfish as it may sound, I have nothing to gain by promoting and lobbying for euphoria. I'm sure I will be more than challenged by C/C++. This sounds an awful lot like a rant. To a degree it is. But moreover, I think I speak for alot of people. People who are on this list, people who have already left the euphoria community, and people who have yet to discover euphoria. Chris Everett Williams wrote: > Chris, > > Only one small point. There is no error recovery in Eu, > because there is no trapping. All code in Euphoria is > defensive. One must write checking code for every possible > error( a thing that one quickly realizes is not possible > in static data handling and flat unreasonable when handling > dynamic data ). Without some form of error trapping, we > are reduced to after-the-fact debugging of each error. If > we knew how to or could practically check all errors before > they happened, we would probably have a program so large that > it would not be practical to run or maybe even program. We > would also be prescient, and I can think of lots of better > uses for that talent than programming...take me to the race > track and let me start buying lotto tickets. A language > without some form of error trapping makes even debugging a > very difficult task. With error trapping, I can make a test > run, logging each error that I find. Then I can examine that > log and deal with a whole group of errors at once rather > than have to debug and restart after each error. The other > problem with such sequential bug chasing is that each fix > has the possibility of creating or enhancing or hiding other > errors, further complicating the process. > > Everett L.(Rett) Williams > rett at gvtc.com > > bensler at mail.com wrote: > > > > > <SNIP> > > > >>for testing purposes (only) > >> > > > > Currently, yes, that's all that typechecks are good for. > > > > <SNIP> > > > >>>As a customer who purchases software, I would be appalled to run a > >>>program that I paid money for, to have it crash with some error message > >>>that doesn't help me at all. Reminds me of Microsoft :P > >>> > > > > This was a fairly inaccurate statement. As is, a program can have > > extensive error checking AND recovery if wanted. It's just alot of code. > > > > With typechecks that modify, one could typically reduce the error > > checking/recovery code by half if not more. This makes the code more > > readable, leading to less errors, leading to faster development time. > > And makes reading 6 month old code alot easier. Getting the code written > > > > faster also usually means more time for testing. > > Writing error checking routines is also boring. When I'm bored, I'm less > > > > productive. > > Error recovery is even more tedious. > > > > > >>Are you happier if a program you purchased crashes and burns, or if it > >>does not perform as advertised/is not fit for task? > >> > >>If I spend say 2 hours typing in stuff & the program crashes and > >>burns, losing all my stuff, then I am NOT HAPPY. > >> > >>If I spend say 2 hours typing in stuff & the program either pops up > >>some drivel warning or simply wipes all the stuff I was doing, then > >> > > I > > > >>am not just "NOT HAPPY", I am seething with rage at the useless <SNIP> > >> > > > > If someone writes an error recovery routine that doesn't fully recover > > from the error, that's the programmers fault, not the language. > > > > Obviously, someone shouldn't write a recovery routine that resets a > > spreadsheet database to DEAFULT. That's just STUPID, and that programmer > > > > should be shot. > > > > > >>If the type check fails so you save loads & loads of stuff for > >>possible recovery, then good on ya, but if you're gonna write code > >>that says 'This should never be 9. I don't care how, why or at all, so > >>I'll just set it back to a nice safe 0", then **** you. > >> > >> > >>>It makes alot more sense to at least ATTEMPT to rectify the problem > >>>before resorting to the BLACK screen of death. > >>> > >>As above, I fail to see how hiding the cause of the problem can > >>possibly help. If you suspect there is going to be a problem modifying > >>variable x then why not make it a private variable in a new include > >>file with all the routines, checks etc to modify it? > >> > > > > YOU just answered your own question. A new include file, ALL the > > routines/checks, etc.. > > <snip>