Re: Routine_ID Is No Doubt My Solution...

new topic     » goto parent     » topic index » view thread      » older message » newer message

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. blink
> 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

new topic     » goto parent     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu