Re: Let's talk about scope

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

Alan Tu wrote:

> This anecdote will demonstrate the problem, which Ralf actually brought up
> a few days ago.  I balked at first, but now I totally see the point.
>
> I was trying to convert Language Wars v2.1 alpha into a game that had WAV
> files.  The first thing I did was to make the torpedo firing play a WAV
> file I have, using Jacques Deschenes sfx2.e file.  Guess what?  There were
> compile-time conflicts due to conflicting global types and constants.  So I
> started to hack the various includes.  Three changes later, I got a
> run-time error, which I was unable to diagnose because I'm not registered.
> I'm sure I probably could have made this work, but I just gave up.
>
> Ralf's suggestion was to change the scope rule to allow routines in deep
> includes inaccessible.  This would solve my problem, but create others.  I
> think I have included graphics.e file.  I know it includes machine.e.  So,
> in my main file, I call machine.e files without directly including it.  I
> am exploiting the scope rules.  If this new scope rules is implemented, all
> such programs would no longer work.
>
> It seems to me that the first priority should be portability.  Currently,
> the scope rules do not allow portability.  This is bad.  But, what would be
> the new scope rules?  Are we ready to make hundreds of programs un-runnable
> without hacking it?  In deeply nested and complex includes, this could
> cause inefficient code.  On the other hand, this could certainly lead to
> more discipline.  Perhaps this should be dynamicly turned on and off.  Any
> thoughts, Robert (or anyone else?)
>
> Alan
>

Well, I think the way the scope is set up is cool and all, but you, and
everyone else is right about naming conflicts.  I think there should be two
syntaxes for the "include" keyword..

1) include filename
2) include filename local

Syntax 1 would run like it has been running in all versions of Euphoria, so
programmers wouldn't have to change their code around.

But with syntax 2, if file A included file B, the code for file B would run,
but all symbols declared as "global" can only be used by file A.  Any other
file wouldn't be able to use the global symbols.  If file B was then later
included with either syntax, the code wouldn't run again, but the global
symbols would be usable, depending on the rules of the syntax.

Another thing that would be pretty cool would be routine overloading.  For
example:

-- Routine overloading example (Win32) --

--
-- This is just an example,
-- There is no error checking, so
-- this way, my point can be explained
-- much more clearly.
--

-- Includes --
include dll.e

-- Constants --
constant

   -- Open the user32.dll file --
   user32 = open_dll("user32.dll"),

   -- Define a function --
   xSendMessage = define_c_func(user32, "SendMessageA", {C_UINT, C_UINT,
C_UINT, C_LONG}, C_LONG)

-- SendMessage as a procedure --
procedure SendMessage(atom hWnd, atom uMsg, atom wParam, atom lParam)
   if c_func(xSendMessage, {hWnd, uMsg, wParam, lParam}) then
   end if
end procedure

-- SendMessage as a function --
function SendMessage(atom hWnd, atom uMsg, atom wParam, atom lParam)
   return c_func(xSendMessage, {hWnd, uMsg, atom wParam, atom lParam})
end function

--
-- Let's just pretend the Win32 constants and all of
-- the other functions are defined.
--

-- Call the SendMessage procedure --
SendMessage(HWND_DESKTOP, WM_PAINT, GetDC(HWND_DESKTOP), 0)

-- Call the SendMessage function --
if SendMessage(HWND_DESKTOP, WM_PAINT, GetDC(HWND_DESKTOP), 0) then
   puts(2, "Hey there!\n")
end if

-- End of example --

If this feature was implemented, function overriding should also be supported.
All you would have to do is declare the routine the EXACT same way as the
previous one.  Yes, I know you're all asking, "But how will we be able to call
the old routine?"  Simple!  Use routine_id()!  Example:

-- The example --

-- useless #1 --
procedure useless(sequence s)
   for count = 1 to length(s) do
      puts(2, s[count] & '\n')
   end for
end procedure

-- Afraid of losing it?  Let's get it's ID.. --
integer id
id = routine_id("useless")    -- Hahaha.. Now we've gotcha. --

-- Call the routine --
useless("Hey hey hey!")

-- useless #2 --
procedure useless(sequence s)
   puts(2, s & '\n')
end procedure

-- Call the routine --
useless("Hey hey hey!")    -- See the difference? --

-- Let's call the old routine. --
call_proc(id, {"Hey hey hey!"})

-- End of example --

Well, I don't know about everyone else, but, I think it rocks.  But the reason
why I think it would be hard to implement would be because it's quite hard to
tell most integers from most atoms (when they're whole numbers), so the
interpreter won't know which routine to call.

As far as overriding constants and variables, I think that would rock.  Just
define the variable with the same name.  Simple as that.  The only disadvantage
would be that there's no way to manipulate the old variable, unless you used
syntax 2 of the include keyword (which hasn't been implemented).

If anyone wants, they can email me at this address, or afterbeat at hotmail.com

   The AfterBeat

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

Search



Quick Links

User menu

Not signed in.

Misc Menu