RE: Routine_ID Is No Doubt My Solution...
- Posted by rforno at tutopia.com Apr 17, 2003
- 416 views
Derek: I am afraid I don't completely understand what you are saying. When you speak about a "reader", are you referring to a human reader? When you speak about code optimizations, are you referring to: a = b (being b a sequence) not really making a copy until some element of a or b is changed, or some other optimization? ----- Original Message ----- From: Derek Parnell <ddparnell at bigpond.com> Subject: Re: Routine_ID Is No Doubt My Solution... > > On Wed, 16 Apr 2003 00:10:00 -0300, <rforno at tutopia.com> wrote: > > [snip] > >> > >> > and I'd prefer passing all parameters as > >> > references, excepting constants and expressions. > >> > >> Now I can see why you want better tracing and debugging features - you > > need > >> them when passing by reference. Too many opportunitites for things to > >> get > >> 'accidently' updated. > > But Derek, now I'm not passing variables a references (not possible in > > current Euphoria), and I still think I need better tracing (this is so > > because I am not doing commercial programming, some special kind of CPU > > intensive programs). > > Moreover, now you have > > a = foo(b, c) and of course have 'a' updated. > > Is it so big the difference with: > > foo(a, b) where you can have 'a' and 'b' updated? > >> > > The difference is that, using the current Euphoria functionality, the code > reader (and thus the interpreter) can at this very point know if 'a' is > being updated or not. When using pass-by-reference (PBR) the reader is > *never* sure if the parameters being passed will also be updated, unless > they also examine the code in the routine being called. By being sure at > the time of the routine call, the interpreter can make some optimisations, > and the code reader can focus on the immediately visible code rather than > track any *potential* updating code that is not necessarily next to the > code being read. > > A further complication occurs with sequences. Currently we always know that > the whole sequence is being replaced by a new one, but with a PBR scheme, > we are never sure which elements may or may not be being updated by the > called routine. This just adds uncertainty, which needs to have extra > effort to resolve when inspecting code. > > So in summary, there is nothing intrinsically wrong with PBR, its just that > it increases the degree of difficulty in reading the code and increases the > probability of mistakes being made. This is exactly the same effect with > using GOTO. So my rule-of-thumb is that both PBR and GOTO should only be > used if its the only way to gain the **NECESSARY** performance improvement > for a specific algorithm or piece of code. The costs of maintaining code > that uses these two techniques is larger than not using them, so this needs > to be taken into consideration. > > We need to take a look at what problems the PBR technique is trying to > solve. > > One of the main reasons for using PBR is to avoid the overheads of passing > large 'stuctures' to routines and receiving large structures back again. > So, an early recommendation for Euphoria was to introduce a simpler syntax > for multiple return values. Something along the lines of ... > > $(a, b) = foo(a,b) > or > > $(s[Name], s[Telephone]) = UpdateCust(s) > > and the special circumstance that current takes the form "x = func(x)" > could be replaced by ... > > func( $x ) > > Another common use for PBR is in situation where the routine called only > knows at runtime (rather than at the time the code was written) if the > parameter needs updating or not, or which elements of a structure might > need updating. Currently we usually perform the tests for updating outside > of the called routine. > > if length(s[Addr]) = 0 then > s[Addr] = NewAddress() > else > s[MailAddr] = NewAddress() > end if > > But in the interests of putting all the 'smarts' in one place, this test > would be better placed inside the routine. > > function NewAddress(sequence s) > . . . if length(s[Addr] = 0 then > return {newaddr, s[MailAddr]} > else > return {s[Addr], newaddr} > end if > end function > $(s[Addr], s[MailAddr]) = NewAddress(s) > > And another PBR usage occurs when there are common data items shared by > many routines, such as Stack or List structures. > > function Push(s, newitem) > s = append(s, newitem) > return s > end function > > function Pop(s) > object item > if length(s) > 0 then > item = s[length(s)] > s = s[1..length(s)-1] > return {item, s} > else > abend("Stack Empty") > end if > end function > > Currently we code like this... > > ParameterStack = Push(ParameterStack, item) > OperationStack = Push(OperationStack, op) > > x = Pop(ParameterStack) > item = x[1] > ParameterStack = x[2] > > But with a syntax change we can get... > > Push($ParameterStack, item) > Push($OperationStack, op) > > Pop($item, $ParameterStack) > > With this syntax idea, we emulate PBR and still tell the reader exactly > what we are doing. Note that PBR is not actually happening, its just that > we are using a coding shorthand to assign returned sequence elements to > multiple items UPON return. > > > -- > > cheers, > Derek Parnell > > > > TOPICA - Start your own email discussion group. FREE! >