Re: Routine_ID Is No Doubt My Solution...

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

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 thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu