1. Routine_ID Is No Doubt My Solution...

...so what's the problem? How come I get no valid routine_ids? (I suspect
why, so what I'm really looking for is a solution!) C'mon, guys! I know you
know!!! Matt, I know you've done a M:TG type program, which I'm going to
examine shortly... any advice here? TIA!

---- Start of Code --
-- ccg_dex.ew
-- Collectible Card Game Deck Maker

sequence cards -- the big list of cards, with CARDNAME as first element
sequence attributes -- attribute names
     -- will serve as a card template for now
sequence command_list -- all available commands
sequence command_id -- routine ids of all commands

object junk

global constant CARDNAME = 1

cards = {}
attributes = {}
command_list = {}
command_id = {}

--------------------------------------
-- CCG Cardmaker ---------------------
--------------------------------------

procedure add_command( sequence newcommand )
 command_list = append( command_list , newcommand )
 command_id = append( command_id, routine_id( newcommand ) )
end procedure

function delete_all_cards()
 cards = {}
 return {1,""}
end function
add_command("delete_all_cards")

function delete_all_attributes()
 attributes = {}
 return {1,""}
end function
add_command("delete_all_attributes")

function removeCard( atom which )
 cards = cards[1..which-1] & cards[which+1..length(cards)]
 return {1,""}
end function
add_command("removeCard")

function addCard( sequence cardname )
sequence newCard
 -- add new record to cards db
 for t=1 to length( cards ) do
  if equal( cards[t][CARDNAME] , cardname ) then
   cardname &= "1"
  end if
 end for
 --cards = append( cards , { { cardname } } )
 newCard = repeat({},length(attributes))
 newCard[1] = cardname
 cards &= { newCard }
 return {1,""}
end function
add_command("addCard")

function addAttribute( sequence attrname )
 attributes = append( attributes , attrname )
 -- add this field to all cards
 for t=1 to length(cards) do
  cards[t] = append( cards[t], "unknown" )
 end for
 return {1,""}
end function
add_command("addAttribute")

function removeAttribute( integer which )
sequence errMsg
 errMsg = {1,""}
-- remove attribute #which from list and from cards
 if which > 0 and which <= length(attributes) then
  attributes = attributes[1..which-1] &
attributes[which+1..length(attributes)]
  for t=1 to length(cards) do
   cards[t] = cards[t][1..which-1] & cards[t][which+1..length(cards[t])]
  end for
 else
  errMsg = {0,"Attribute number out of range for removeAttr()"}
 end if
 return errMsg
end function
add_command("removeAttribute")

function get_all_cards()
 return cards
end function
add_command("get_all_cards")

function card_exists( sequence cardname )
atom ce
 ce = (1=2)
-- does the cardname already exist?
-- loop through each card
 for t=1 to length(cards) do
  if equal(cardname, cards[CARDNAME]) then
   ce = (1=1)
  end if
 end for
 return ce
end function
add_command("card_exists")

function get_commands()
 return command_list
end function
add_command("get_commands")

function card_count()
 return length(cards)
end function
add_command("card_count")

function attribute_count()
 return length(attributes)
end function
add_command("attribute_count")

function card_data( integer cardnum, integer index )
 if index = 0 then
  return cards[cardnum]
 else
  return cards[cardnum][index]
 end if
end function

global function ccgcm( object order )
-- ccgcm is the global function through which all commands are processed
-- sequence order is made of two sequence elements: command, parameters
sequence command, params, errCode
integer cnum

 -- set errCode
 errCode = { 0 , "" }
 if not sequence( order ) then
  errCode = { 0 , "Order must be a SEQUENCE of two sequences" }
 else
  if length(order) != 2 then
   errCode = { 0 , "Order must be sequence of TWO sequences" }
  else
   command = order[1]
   params = order[2]
   if not sequence(command) or not sequence(params) then
    errCode = { 0 , "Order must be sequence of two SEQUENCES" }
   else
    cnum = find( command , command_list )
    if cnum = 0 then
     errCode = { 0 , "Unrecognized command '" & order[1] & "'" }
    end if
   end if
  end if
 end if

 if errCode[1] = 1 then -- order is properly formatted
  -- verify params are appropriate for command?
  -- process command!
  junk = call_func( cnum , params )
  if junk[1] then
   -- if the command is processed, return its errCode
   errCode = { 1 , "" }
  end if
 end if
 return errCode
end function

?command_id
junk = find( "card_count" , command_list )
?command_id[junk]
junk = call_func( command_id[junk] , {} )

-- junk = wait_key() -- you might need to uncomment this line in Windows

---- End of Code --

new topic     » topic index » view message » categorize

2. Re: Routine_ID Is No Doubt My Solution...

On Thu, 10 Apr 2003 16:23:15 -0500, "C. K. Lester"
<cklester at yahoo.com> wrote:

>How come I get no valid routine_ids?
Yikes, now there is a nasty programming gotcha. Somehow at the point
where routine_id is called it appears to be searching a saved list of
routine names known at that point during parsing... rather than the
expected scan of the full symbol table at that point during execution!
Maybe an over-zealous optimisation, Rob?

Anyway, comment out the call to routine_id within add_command() and
insert the following code after all add_command()s have been issued.

command_id =3D repeat(-1,length(command_list))
for i =3D 1 to length(command_list) do
	command_id[i]=3Droutine_id(command_list[i])
end for

Pete

new topic     » goto parent     » topic index » view message » categorize

3. Re: Routine_ID Is No Doubt My Solution...

--- Pete Lomax <petelomax at blueyonder.co.uk> wrote:
> 
> On Thu, 10 Apr 2003 16:23:15 -0500, "C. K. Lester"
> <cklester at yahoo.com> wrote:
> 
> >How come I get no valid routine_ids?
> 
> Anyway, comment out the call to routine_id within
> add_command() and
> insert the following code after all add_command()s
> have been issued.
> 
> command_id = repeat(-1,length(command_list))
> for i = 1 to length(command_list) do
> 	command_id[i]=routine_id(command_list[i])
> end for

Pete, that's the exact solution I used about one
minute after I posted that last message... I was going
to post a "NEVERMIND" response, but I didn't see that
message till today!!! Like, what's up with Topica's
posting speed lately... ;)

Thanks!


__________________________________________________
Do you Yahoo!?
Yahoo! Tax Center - File online, calculators, forms, and more
http://tax.yahoo.com

new topic     » goto parent     » topic index » view message » categorize

4. Re: Routine_ID Is No Doubt My Solution...

----- Original Message -----
>From: "Pete Lomax" <petelomax at blueyonder.co.uk>
>To: "EUforum" <EUforum at topica.com>
>Subject: Re: Routine_ID Is No Doubt My Solution...
>

>
>On Thu, 10 Apr 2003 16:23:15 -0500, "C. K. Lester"
><cklester at yahoo.com> wrote:
>
>>How come I get no valid routine_ids?
>Yikes, now there is a nasty programming gotcha. Somehow at the point
>where routine_id is called it appears to be searching a saved list of
>routine names known at that point during parsing... rather than the
>expected scan of the full symbol table at that point during execution!
>Maybe an over-zealous optimisation, Rob?
>
>Anyway, comment out the call to routine_id within add_command() and
>insert the following code after all add_command()s have been issued.
>
>command_id = repeat(-1,length(command_list))
>for i = 1 to length(command_list) do
>command_id[i]=routine_id(command_list[i])
>end for

Pete's solution is the right thing, but this behaviour of Euphoria is
designed. RDS explicitly wants Euphoria to be like this - it is NOT
"over-zealous optimisation". The design philosophy for Euphoria is "nothing
can be referenced until it has been 'seen' by the translator first".

<soapbox>
IMHO, this is a dumb decision and one of the most annoying things about this
great language. The lack of forward referencing makes things harder for the
coder. I can understand the excuse for it in the early days when computers
were slow, but with modern computers I really don't mind waiting the one or
two seconds it takes to parse the whole code before execution.
</soapbox>

----------------
cheers,
Derek Parnell

new topic     » goto parent     » topic index » view message » categorize

5. Re: Routine_ID Is No Doubt My Solution...

--- Derek Parnell <ddparnell at bigpond.com> wrote:
 
> Pete's solution is the right thing, but this
> behaviour of Euphoria is designed.
> RDS explicitly wants Euphoria to be like
> this - it is NOT "over-zealous optimisation".
> The design philosophy for Euphoria is "nothing
> can be referenced until it has been 'seen' by the
> translator first".
> 
> <soapbox>
> IMHO, this is a dumb decision and one of the most
> annoying things about this great language.

Derek, your opinion on just about anything EUPHORIA is
highly regarded in my mind. I'm sure if I knew more
about the topic I might agree with you. You also have
helped build one of the greatest expansions of EU
code, namely Win32Lib, so your experience in this
regard is well established and without question.

In this case, the solution to my initial problem turns
out to be quite simple and, when I first thought of
it, enough to be intuitive that I thumped myself for
not thinking of it beforehand... it was simply my lack
of knowledge regarding routine_id(). I still have yet
to find something lacking in EUPHORIA, or something I
consider to be a detriment to programmers.

> The lack of forward referencing
> makes things harder for the coder.

I kinda chuckle because VBA lets me put my subs and
functions all over the place, willy nilly. Sometimes I
have looked and looked for the referenced function
ABOVE where I have coded it, only to find it soon
after BELOW the code... sigh. Stupid VBA and its
anarchy!!!

> I can understand the excuse for it in the
> early days when computers
> were slow, but with modern computers I really don't
> mind waiting the one or
> two seconds it takes to parse the whole code before
> execution.

This I agree with and have always espoused: EU is not
so slow (not slow at all) that this generation of PCs
is going to be bogged down by whatever you execute. I
remember saying this even at the very beginning of
EU's existance!

I did get bogged down ONE time when creating a program
where a forward reference would have resolved the
issue much sooner than I did without it. I wonder,
however, if the program would have been as good in
regards to modularity and maintenance had I been able
to use that forward reference. Since then, the issue
has not been raised again. (I like to this it's
because my programming skills have just skyrocketed
exponentially. heheh)

-ck


__________________________________________________
Do you Yahoo!?
Yahoo! Tax Center - File online, calculators, forms, and more
http://tax.yahoo.com

new topic     » goto parent     » topic index » view message » categorize

6. Re: Routine_ID Is No Doubt My Solution...

On Sun, 13 Apr 2003 08:30:28 +1000, Derek Parnell
<ddparnell at bigpond.com> wrote:

>Pete's solution is the right thing, but this behaviour of Euphoria is
>designed. RDS explicitly wants Euphoria to be like this - it is NOT
>"over-zealous optimisation". The design philosophy for Euphoria is =
"nothing
>can be referenced until it has been 'seen' by the translator first".

Derek is right again blink  I now fully understand and accept this (but
I'll beat it to death anyway)  eg:

a=3Droutine_id("b")
...
procedure b()

will not work, because when routine_id is executed, b() has not yet
been defined; it is not yet in the symbol table. But:

constant name=3D"b"
procedure a()
	?routine_id(name)		-- line 3
end procedure
procedure b()
end procedure
?routine_id(name)			-- line 7
a()						-- line 8

In this case, line 7 passes the same constant to the same built-in
function as line 3, which is actually executed after line 7, but it
gives a different result(!!). Hence somewhere for line 3 it must be
deliberately storing an index of some sort specifically to force this
behaviour. So Derek is right, this is not an optimisation, in fact it
is an (admittedly insignificant) overhead! And as usual the
documentation is spot-on, I just assumed it was using "after" in an
execution sense rather than a dogmatic absolute line number sense.
 You live and learn.

><soapbox>
>IMHO, this is a dumb decision and one of the most annoying things about =
this
>great language. The lack of forward referencing makes things harder for =
the
>coder. I can understand the excuse for it in the early days when =
computers
>were slow, but with modern computers I really don't mind waiting the one=
 or
>two seconds it takes to parse the whole code before execution.
></soapbox>

Agreed.

Pete

new topic     » goto parent     » topic index » view message » categorize

7. Re: Routine_ID Is No Doubt My Solution...

----- Original Message -----
From: "C. K. Lester" <cklester at yahoo.com>
To: "EUforum" <EUforum at topica.com>
Subject: Re: Routine_ID Is No Doubt My Solution...


>
>
> --- Derek Parnell <ddparnell at bigpond.com> wrote:
>
> > Pete's solution is the right thing, but this
> > behaviour of Euphoria is designed.
> > RDS explicitly wants Euphoria to be like
> > this - it is NOT "over-zealous optimisation".
> > The design philosophy for Euphoria is "nothing
> > can be referenced until it has been 'seen' by the
> > translator first".
> >

[snip]

>
> In this case, the solution to my initial problem turns
> out to be quite simple and, when I first thought of
> it, enough to be intuitive that I thumped myself for
> not thinking of it beforehand... it was simply my lack
> of knowledge regarding ...

Heck, I do this on a daily basis.


> I still have yet
> to find something lacking in EUPHORIA, or something I
> consider to be a detriment to programmers.

Horses for Courses. I have a host of coding paradigms that I enjoy using,
(because they increase *my* efficiency) that I have to use workarounds for
when coding in Euphoria. In other words, using Euphoria, I'm not as
efficient as I know I could be. I'm just lucky that that is still better
than using C/C++.

> > The lack of forward referencing
> > makes things harder for the coder.
>
> I kinda chuckle because VBA lets me put my subs and
> functions all over the place, willy nilly. Sometimes I
> have looked and looked for the referenced function
> ABOVE where I have coded it, only to find it soon
> after BELOW the code... sigh. Stupid VBA and its
> anarchy!!!

I do most of my commercial coding in VB. I organise my code so I can find
related routines quickly. Also, the IDE (and the MZTools add-in) makes
finding routines so simple. The key is, that routines are physically
organised according to their relationships to each other, rather than their
physical location in the source file, which can lead to totally unrelated
routines having to be located next to each other.

----------------
cheers,
Derek Parnell

new topic     » goto parent     » topic index » view message » categorize

8. Re: Routine_ID Is No Doubt My Solution...

{{{

Derek Parnell on his

<soapbox>
IMHO, this is a dumb decision and one of the most annoying things about this
great language. The lack of forward referencing makes things harder for the
coder. I can understand the excuse for it in the early days when computers
were slow, but with modern computers I really don't mind waiting the one or
two seconds it takes to parse the whole code before execution.
</soapbox>

Yeah, thats the problem with those Circular-List, always chasing their tails.

hehe Euman

new topic     » goto parent     » topic index » view message » categorize

9. Re: Routine_ID Is No Doubt My Solution...

On Sunday 13 April 2003 10:23 am, Derek wrote:
>
> ----- Original Message -----
> From: "C. K. Lester" <cklester at yahoo.com>
>
> > I still have yet
> > to find something lacking in EUPHORIA, or something I
> > consider to be a detriment to programmers.
>
> Horses for Courses.

What in all of creation does that mean? I could Google it, but it's close to 
bedtime.

> I have a host of coding paradigms that I enjoy using,
> (because they increase *my* efficiency) that I have to use workarounds for
> when coding in Euphoria. In other words, using Euphoria, I'm not as
> efficient as I know I could be. I'm just lucky that that is still better
> than using C/C++.

Here's how I see it: you are as efficient as you can be in EUPHORIA. So far, 
that's good enough.

> I do most of my commercial coding in VB. I organise my code so I can find
> related routines quickly.

You have that luxury... I have to, often, spew out massive amounts of code in 
a day or less. It can be fun!

> Also, the IDE (and the MZTools add-in) makes
> finding routines so simple. The key is, that routines are physically
> organised according to their relationships to each other, rather than their
> physical location in the source file, which can lead to totally unrelated
> routines having to be located next to each other.

My main base of code is like this... I've put all the related functions/subs 
together in groups. It does make it real nice!

new topic     » goto parent     » topic index » view message » categorize

10. Re: Routine_ID Is No Doubt My Solution...

On Sun, 13 Apr 2003 22:50:51 -0500, C. K. Lester <cklester at yahoo.com> 
wrote:

>
> On Sunday 13 April 2003 10:23 am, Derek wrote:
>>
>> ----- Original Message -----
>> From: "C. K. Lester" <cklester at yahoo.com>
>>
>> > I still have yet
>> > to find something lacking in EUPHORIA, or something I
>> > consider to be a detriment to programmers.
>>
>> Horses for Courses.
>
> What in all of creation does that mean? I could Google it, but it's close 
> to bedtime.

Sorry - I didn't realize this expression is not used in the U.S. It 
generally means that each situation is best suited to some solutions rather 
than others. In the context of my usage, I was trying to say your view of 
Euphoria, "I still have yet to find something lacking in EUPHORIA..." and 
mine, "I have to use workarounds" are obviously different but we are both 
still able to use it for the tasks we have chosen.

>> I have a host of coding paradigms that I enjoy using,
>> (because they increase *my* efficiency) that I have to use workarounds 
>> for
>> when coding in Euphoria. In other words, using Euphoria, I'm not as
>> efficient as I know I could be. I'm just lucky that that is still better
>> than using C/C++.
>
> Here's how I see it: you are as efficient as you can be in EUPHORIA. So 
> far, that's good enough.

I have a different set of expecations - just as valid as yours, of course.


-- 

cheers,
Derek Parnell

new topic     » goto parent     » topic index » view message » categorize

11. Re: Routine_ID Is No Doubt My Solution...

On Tue, 15 Apr 2003 00:13:28 -0300, <rforno at tutopia.com> wrote:

>
> Derek:
> I can assure you that "Horses for Courses" is neither used in Argentina, 
> not
> even in English-speaking circles;)

Must be an Australianism - ain't diversity a wonderful thing.

> Regarding the subject of programming in different languages, I in a 
> certain
> way agree with Mr. C. K. Lester. I think that every programming language 
> has
> its pros and cons, and you have to adapt you programming style to each
> language you program in.

Yes, every language (human and programming) has pros and cons. However, I 
refuse to believe that anything is "as good as at can get". Euphoria can be 
better than the current 'cons'.

> Particularly, I find Euphoria very manageable and
> akin to my programming style.

That's fine then.

> I think the its weak spots lie in the trace and debugging facility, even 
> its being better than most other languages.

Of course, if some other area were 'improved' there would be less need for 
tracing and debugging.

> I will welcome facilities to:
> 1) See expressions, not only variables, during trace.

Yes please.

> 2) Show only variables (expressions) that one selects, and not 
> automatically
> selected ones.

Yes please (as an option).

> 3) Allow changing variable values, and perhaps executing routines while 
> in
> trace.

Yes please.

> 4) Save the status of the program in order to continue execution later.

Hmmm. Never really needed to do this.

> In addition, I would like to be able to execute strings read or created
> during program execution,

This would require a complete rewrite of the RDS interpreter as its 
internal architecture prevents it doing this.

> 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 as it is today, Euphoria is a very, very useful language (at least 
> for the tasks I am using it for).

This is the meaning of 'horses for courses'. One uses Euphoria for the 
purposes it is best suited to, just like one uses the right sort of horse 
for the specific course to be raced over.

> I only had to resort to C for a large program,
> CPU intensive, for speed reasons.

Yes, C is a lot closer to the metal; the next level down is machine 
language (assembler). I've heard it said that 'C' is really the PDP-11's 
high-level assembler.

-- 

cheers,
Derek Parnell

new topic     » goto parent     » topic index » view message » categorize

12. Re: Routine_ID Is No Doubt My Solution...

On 15 Apr 2003, at 15:30, Derek Parnell wrote:

> 
> On Tue, 15 Apr 2003 00:13:28 -0300, <rforno at tutopia.com> wrote:
> 
> >
> > Derek:
> > I can assure you that "Horses for Courses" is neither used in Argentina, not
> > even in English-speaking circles;)
> 
> Must be an Australianism - ain't diversity a wonderful thing.

The only thing i can think of is the line from the Mr Ed tv show of the 50's "A 
horse is a horse, of course, of course, and no one can talk to a horse of 
course....", which could have been mangled to what you said.

Kat

new topic     » goto parent     » topic index » view message » categorize

13. Re: Routine_ID Is No Doubt My Solution...

C. K. Lester wrote:

> I did get bogged down ONE time when creating a program
> where a forward reference would have resolved the
> issue much sooner than I did without it.

The EE editor has its loops written "inside out" because callbacks didn't 
exist at the time. If they had, the code would have been much nicer. 

Win32Lib would be unthinkable without forward references, and it's probably 
the premiere example of their use. Still, I've never been happy with the 
scope of routine_id. I always wanted to be able to put it into a routine like 
this:

   function new_control( int control_type, sequence callback_name )
      int the_callback

      the_callback = routine_id( callback_name )

      ...
   end function

So the users could pass the name of their routines:

   create_control( button, "my_callback" )

This, of course, doesn't work, because my_callback isn't defined until after 
create_control is defined, and routine_id is limited to seeing things that 
exist at the point where it's defined, so you have to use:

   create_control( button, routine_id("my_callback") )

The reason for scoping routine_id like this has always baffled me. There may 
be a compelling reason internally to code it like this, but, it's not the way 
I want it to behave. And I'll leave it at that before I start ranting away...

I have particularly unhappy memories about trying to write an interpreter 
before routine_id() existed. There are a lot of recursive relationships in 
parsers, and I had run into one situation where A called B, and B called A, 
with no forward referencing available.

The only available option was to fold all the routines into a single routine 
with a huge case statement. It took a while to refactor and rewrite it.

But the kicker was that the function was so large, Euphoria was unable to 
compile it. And since it had interdependancies, there was no way to shrink 
the code. That killed the project dead.

But perhaps my most nastiest encounter with routine_id had to do with bind and 
shroud. I'm getting into ancient history here, and most of this has already 
been solved, so feel free to bail out...


You were warned...


OK, at the time, bind and shroud were blissfully unaware of routine_id. So if 
you shrouded code like this:

   -- file1.ex
   function foo()
   end function
   ? routine_id("foo")

You'd end up with something like this:

   -- file1.ex
   {_ r01()
   &# (_
   @ ^_("foo")

Obviously, the shrouded name of 'r01' isn't going to match up with the name in 
routine_id. So you couldn't use shroud with routine_id and expect the code to 
work. This was a bit of a bummer, since it meant that people couldn't use 
Win32Lib and shroud their code.

The real problem was with bind. For those unaware of what shroud does, it 
collects all the source files into a single file. But therein lies the rub: 
when these files are collected together, routines that were scoped to a 
particular file (and thus made unique) are no longer made unique, because 
they exist in the same file. That is, consider the following two files, 
"file1.ex" and "file2.ex"

   -- file1.ex
   function foo()
   end function
   ? routine_id("foo")

   -- file2.ex
   function foo()
   end function
   ? routine_id("foo")

Although both files have functions 'foo', they are private due to the fact 
that they exist in seperate files. (Euphoria didn't have "real" namespaces at 
the time. I said this was ancient history).

Now, consider what happens when Euphoria bound them together into a single 
file:

   -- file1.ex + file2.ex
   function foo()
   end function
   ? routine_id("foo")

   function foo()
   end function
   ? routine_id("foo")

Obviously, there is a problem: since these routines now share the same file, 
they are no longer made unique. If this were left as-is, Euphoria would 
generate an error, since 'foo' is defined twice.

At this point, Euphoria did something clever. When it bound the program, it 
noticed there is a name duplication, and - without mentioning it - renamed 
the duplicate routine:

   -- file1.ex + file2.ex
   function foo()
   end function
   ? routine_id("foo")

   function rename_1()
   end function
   ? routine_id("foo")

The problem is obvious: the second call to routine_id() is going to refer to 
the first routine, not the second. This was a particularly nasty bug, because 
it wouldn't generate an error. Instead, you'd have the wrong callback 
attached to a control. 

To get around this, I had to write a routine called 'fix.ex' that did the same 
thing as bind, but not only renamed the routines, but fixed the reference in 
routine_id as well.

In fairness, these problems have long since been solved. But my encounters 
with routine_id have not been especially happy ones.

-- David Cuny

new topic     » goto parent     » topic index » view message » categorize

14. 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. 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 message » categorize

15. Re: Routine_ID Is No Doubt My Solution...

On Tue, 15 Apr 2003 01:19:00 -0700, David Cuny <dcuny at LANSET.COM>
wrote:

>But perhaps my most nastiest encounter with routine_id had to do with =
bind and=20
>shroud. I'm getting into ancient history here, and most of this has =
already=20
>been solved

I wish. C. K. Lester's post spurred me on to try shrouding my program.
The problem I faced is that as a library routine it uses win32lib.ew
and database.e; however I _really_ did not want them packed with the
routine; instead I want to use the ones included by the calling
application (so there is only one event loop, only one WinMain, etc).

Anyway, it has been a long hard four day slog, but I eventually got it
working (today) with:

<shrouded part:>
80 of these:
integer zAddItem
global procedure AddItem(integer id, object item)
-- add item(s) to List/Combo id
	call_proc(zAddItem,{id,item})
end procedure

and 17 of these:
global integer window,....

global procedure initialise_pprg(integer rid, integer vid)=20
	-- note this is called by the unshrouded part.....
	zAddItem=3Dcall_func(rid,{"addItem"})
	....
	s=3Dcall_func(vid,{})
	window =3Ds[1]
	....

and 251 stolen copies of various constants, eg
global constant=20
	WS_POPUP		=3D #80000000,
-- fingers firmly crossed on that set!
(I do expect to get slapped each time a new version of win32lib is
released, but making that safer is a problem for another day)

<unshrouded part:>

[You gotta love this one!]
global function routineid(sequence name)
	return routine_id(name)
end function

global function vset()
	return {Window,....
end function

initialise_pprg(routine_id("routineid"), routine_id("vset"))

The unshrouded part is needed so that routine_id can "see" the copy of
win32lib loaded by the application and set up the bank of 80
routine_ids and 17 control types for the shrouded part.

Oh, and I forgot about editing the three and a half thousand lines of
code of my routine replacing eg "addItem" with "AddItem", "Window"
with "window", etc.

Not a very happy bunny,

Pete

new topic     » goto parent     » topic index » view message » categorize

16. Re: Routine_ID Is No Doubt My Solution...

On Tue, 15 Apr 2003 15:30:21 +1000, Derek Parnell
<ddparnell at bigpond.com> wrote:

>> 4) Save the status of the program in order to continue execution =
later.
>
>Hmmm. Never really needed to do this.

Possibly badly worded. Resume the status of a debug session
definitely. I want to start the next debug session with result,
params, local var x etc showing their current values.
I'll not be the first dumb numbskull that needs more than one debug
session to solve a thorny problem & I freely admit that.

The debugger should allow a "permanent view" to be defined - not as it
stands overwrite randomly/sequentially those variables you are
interested in tracking with "fluff";  eg for i=3D1 to 10; you *know*
what i is, cause you're single-stepping the loop; when it blats the
current value of i over a value you are waiting to see go wrong, it's
a pain, 'cos you have to "?" it again to get it back on the screen.

Some kind of ini file, only read when the debug/trace window opens?
The debugger is smart enough to cope if I define some variable such as
"result" which is not in scope at the trap point & say "<undefined>"=20

The other one I'd vote for is viewing the *end* of a large sequence in
the permitted 80-char view. I know 2.4 allows you to see the whole
thing, but when you are single-stepping through, waiting for it to go
wrong...

Pete

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu