1. [DOS] Can we emulate "pass by reference" in Eu?
Dear List
For my general knowledge, rather than with a specific program in mind, I'd like
to ask how to pass a non-global variable (two scenario's: an atom; a sequence) as
an argument to:
1 a procedure that changes the variable (eg increments it)
2 a function that changes the variable (eg increments it) but returns some
other, different, variable
A "minimal" example to achieve the above, would be enough.
Thank you
Alex Caracatsanis
2. Re: [DOS] Can we emulate "pass by reference" in Eu?
On 18 Oct 2004, at 20:58, Alex Caracatsanis wrote:
>
>
> posted by: Alex Caracatsanis <CaracatsanisA at ramsayhealth.com.au>
>
> Dear List
>
> For my general knowledge, rather than with a specific program in mind, I'd
> like
> to ask how to pass a non-global variable (two scenario's: an atom; a sequence)
> as an argument to: 1 a procedure that changes the variable (eg increments it)
> 2
> a function that changes the variable (eg increments it) but returns some
> other,
> different, variable
>
> A "minimal" example to achieve the above, would be enough.
Not sure if this is what you meant ........
atom var1
sequence seq1
procedure add1(atom var2)
var1 = var2
end procedure
function add2(atom var2)
var1 += var2
return var1
end function
procedure app1(sequence seq2)
seq1 = seq2 & seq2
end procedure
function app2(sequence seq2)
sequence nothing
nothing = ""
seq1 = seq2 & seq2
return nothing
end function
procedure test()
atom var0
sequence seq0
var0 = 12
seq0 = "something"
add1(var0)
var0 = add2(var0)
app1(seq0)
seq0 = app2(seq0)
end procedure
test()
> Thank you
<curtsey>
Kat
3. Re: [DOS] Can we emulate "pass by reference" in Eu?
Alex Caracatsanis wrote:
>
> Dear List
>
> For my general knowledge, rather than with a specific program in mind, I'd
> like to
> ask how to pass a non-global variable (two scenario's: an atom; a sequence) as
> an argument
> to:
> 1 a procedure that changes the variable (eg increments it)
> 2 a function that changes the variable (eg increments it) but returns some
> other, different,
> variable
>
> A "minimal" example to achieve the above, would be enough.
>
File name "mem.e" ...
----------------------
sequence Mem, MemUse
Mem = {}
MemUse = {}
global function NewRef()
integer lPos
lPos = find(0, MemUse)
if lPos = 0 then
Mem &= 0
MemUse &= 0
lPos= length(Mem)
end if
MemUse[lPos] = 1
Mem[lPos] = 0
return lPos
end function
global procedure FreeRef(integer pPos)
MemUse[pPos] = 0
Mem[pPos] = 0
end procedure
global function GetRefData(integer pPos)
return Mem[pPos]
end function
global procedure SetRefData(integer pPos, object pData)
Mem[pPos] = pData
end procedure
--------------------
File name: "test.ex" which uses "mem.e" ...
--------------------
include mem.e
--------------------------
function addCustomer( sequence pNewCust)
--------------------------
integer lNewRef
lNewRef = NewRef()
SetRefData( lNewRef, pNewCust )
return lNewRef
end function
--------------------------
function calcInterest( integer pCustRef )
--------------------------
sequence lCust
atom lInterest
atom lRate
lCust = GetRefData( pCustRef )
if lCust[4] = 'A' then
lRate = 0.1025
elsif lCust[4] = 'G' then
lRate = 0.1550
else
lRate = 0.0
end if
lInterest = floor((lCust[3] * lRate) * 100) / 100
lCust[3] += lInterest
SetRefData(pCustRef, lCust)
return lInterest
end function
--------------------------
procedure displayCust( integer pCustRef )
--------------------------
sequence lCust
lCust = GetRefData( pCustRef )
printf(1, "%-25s Balance=%9.2f Rate=%s\n", {lCust[1] & ' ' & lCust[2],
lCust[3], lCust[4]})
end procedure
sequence vCustList
vCustList = {}
vCustList &= addCustomer( {"Derek", "Parnell", 1000, 'A'} )
vCustList &= addCustomer( {"George", "Potter", 200, 'B'} )
vCustList &= addCustomer( {"Joyce", "Grimwade", 300, 'G'} )
vCustList &= addCustomer( {"Jim", "Ng", 321, 'G'} )
vCustList &= addCustomer( {"Diane", "Smith-Jones", 827, 'B'} )
vCustList &= addCustomer( {"Horace", "Thomas", 1211, 'A'} )
vCustList &= addCustomer( {"Betty", "Boo", 9820, 'A'} )
atom vTot
for j = 1 to 3 do
printf(1, "\n\nCycle %d\n", j)
vTot = 0
for i = 1 to length(vCustList) do
vTot += calcInterest( vCustList[i] )
end for
printf(1, "Total interest: %9.2f\n\n", vTot)
for i = 1 to length(vCustList) do
displayCust( vCustList[i] )
end for
-- Delete third customer
FreeRef( vCustList[3] )
vCustList = vCustList[1..2] & vCustList[4..length(vCustList)]
end for
------------------------
--
Derek Parnell
Melbourne, Australia
4. Re: [DOS] Can we emulate "pass by reference" in Eu?
Alex Caracatsanis wrote:
>
> Dear List
>
> For my general knowledge, rather than with a specific program in mind, I'd
> like to
> ask how to pass a non-global variable (two scenario's: an atom; a sequence) as
> an argument
> to:
> 1 a procedure that changes the variable (eg increments it)
> 2 a function that changes the variable (eg increments it) but returns some
> other, different,
> variable
>
> A "minimal" example to achieve the above, would be enough.
>
> Thank you
>
> Alex Caracatsanis
>
Maybe I should add: what I'm thinking about is something like this...
procedure incrementProcedure( object obj )
-- code that will increment the actual parameter (num),
-- not a copy of it, such that num is now 11 or {11, 21}
end procedure
function incrementFunction( object obj )
object retVar
-- code that will increment the actual parameter (num),
-- not a copy of it, such that num is now 12 or {12, 22}
-- code to do other things as well
return retVar
end function
procedure main()
atom num num = 10
sequence seq seq = {10, 20}
object retVal
incrementProcedure( num )
? num -- now num = 11
retVal = incrementFunction( num )
? num -- now num = 12
-- retVal is anything; not interested in it for now
incrementProcedure( seq )
? seq -- now seq = {11, 21}
retVal = incrementFunction( seq )
? seq -- now seq = {12, 22}
-- retVal is anything; not interested in it for now
end procedure
main()
Hope that's clear.
Thanks
Alex Caracatsanis
5. Re: [DOS] Can we emulate "pass by reference" in Eu?
Alex Caracatsanis wrote:
>
> Alex Caracatsanis wrote:
> >
> > Dear List
> >
> > For my general knowledge, rather than with a specific program in mind, I'd
> > like to
> > ask how to pass a non-global variable (two scenario's: an atom; a sequence)
> > as an argument
> > to:
> > 1 a procedure that changes the variable (eg increments it)
> > 2 a function that changes the variable (eg increments it) but returns some
> > other, different,
> > variable
> >
> > A "minimal" example to achieve the above, would be enough.
> >
> > Thank you
> >
> > Alex Caracatsanis
> >
>
> Maybe I should add: what I'm thinking about is something like this...
>
> }}}
<eucode>
include mem.e
procedure incrementProcedure( object obj )
-- code that will increment the actual parameter (num),
-- not a copy of it, such that num is now 11 or {11, 21}
object lData
lData = GetRefData( obj )
lData += 1
SetRefData(obj, lData)
end procedure
function incrementFunction( object obj )
object retVar
-- code that will increment the actual parameter (num),
-- not a copy of it, such that num is now 12 or {12, 22}
-- code to do other things as well
object lData
lData = GetRefData( obj )
lData += 1
SetRefData(obj, lData)
retVar = 0
if sequence(lData) then
for i = 1 to length(lData) do
retVar += lData[i]
end for
else
retVar = lData
end if
return retVar
end function
procedure main()
integer num
integer seq
object retVal
num = NewRef()
SetRefData(num, 10)
incrementProcedure( num )
? GetRefData(num)
retVal = incrementFunction( num )
? GetRefData(num)
? retVal -- retVal is anything; not interested in it for now
seq = NewRef()
SetRefData(seq, {10,20})
incrementProcedure( seq )
? GetRefData(seq) -- now seq = {11, 21}
retVal = incrementFunction( seq )
? GetRefData(seq) -- now seq = {12, 22}
? retVal -- retVal is anything; not interested in it for now
end procedure
main()
</eucode>
{{{
Here you go. It this the sort of thing?
--
Derek Parnell
Melbourne, Australia
6. Re: [DOS] Can we emulate "pass by reference" in Eu?
Kat, Derek,
Thanks for your helpful examples. Now to study them...
Alex Caracatsanis
7. Re: [DOS] Can we emulate "pass by reference" in Eu?
>
> posted by: Alex Caracatsanis <CaracatsanisA at ramsayhealth.com.au>
>
> Dear List
>
> For my general knowledge, rather than with a specific program in mind, I'd
> like to ask how to pass a non-global variable (two scenario's: an atom; a
> sequence) as an argument to:
> 1 a procedure that changes the variable (eg increments it)
> 2 a function that changes the variable (eg increments it) but returns some
> other, different, variable
>
> A "minimal" example to achieve the above, would be enough.
>
> Thank you
>
> Alex Caracatsanis
Yes:
sequence sharedvars
sharedvars=repeat(0,27) --whatever max limit to the number of shared variables
--extending it dynamically is trickier, see below
procedure proc1(integer passedbyref,object othervars)
object whatever
--some code
sharedvars[passedbyref]=whatever
--...
end procedure
--...
sharedvars[slot]=myarg
proc1(slot,optionallySomethingElse)
--sharedvars[slot] holds the modified value
Replace "procedure" by "function" as needed. After all, that's how the network
interrupt #5C works.
You have to keep track of slot alloction and return types yourself.
Now some code in order to forget about any max size of sharedvars:
sequence sharedvars sharedvars={0,0,0}
integer usedslots usedslots=0
function allotslot(object x)
if usedslots=length(sharedvars) then sharedvars&=0 end if
usedslots+=1
sharedvars[usedslots]=x
return usedslots
end function
procedure endgame() usedslots=0 end procedure
--...
procedure proc1(integer passedbyref,object othervars)
object whatever
--some code
sharedvars[passedbyref]=whatever
--...
end procedure
integer slot
slot=allotslot(myarg)
proc1(slot,optionallySomethingElse)
--sharedvars[slot] holds the modified value
--...
endgame() --current tempvars no longer valid, clean up
That's clumsier, but you no longer take care of slots; just remember which
holds what.
And you can typecheck sharedvars[slot] at any time and take any appropriate
action.
CChris