[gameprogrammer] Re: More scripting engines

  • From: David Olofson <david@xxxxxxxxxxx>
  • To: gameprogrammer@xxxxxxxxxxxxx
  • Date: Thu, 29 Apr 2004 10:52:15 +0200

On Monday 26 April 2004 08.41, grant hallman wrote:
> At 06:39 PM 24-04-04 +0200, you wrote:
> >On Saturday 24 April 2004 17.18, Bernhard Bliem wrote:
> >> That's an interesting idea. However, wouldn't a goto be actually
> >> sufficient?
> >
> >Sufficient, but not adequate. In fact, I'm probably not going to
> >support goto at all, considering the horrible mess it tends to
> > create when mixed with higher level flow control constructs. (Etc
> > etc.)
> >
> >In short, goto is plain evil. :-)
>
> Personally, i suspect brainwashing ;)

Dunno if that has anything to do with it, but I'm a mostly self taught 
programmer, and I just plain don't like goto in languages that 
provide higher level control flow constructs. It makes the code 
confusing and easier to break when refactoring.

I used gotos for error handling in C until not too long ago, but I 
never liked it, so I stopped. (And this is in a language without 
try...except blocks or similar... EEL will have those, of course.)


> Goto can be part of hideous code, no doubt about it. But according
> to the NRA, goto's don't hurt programs, it's programmers who hurt
> programs ;-D
>
> IOW, if a programmer does not think and code clearly, nothing the
> language does can save the results, and if (s)he does, (s)he will
> write good code whether goto is available or not.

Of course, that's a good point. :-)

Either way, it's my language, and I don't use goto. If you really want 
it, you can submit a patch and see if you can convince me that it's 
useful. ;-)

More seriously; I'd prefer it if the control flow constructs actually 
did the job, so you don't have to "fix" them by using goto. High 
level control flow constructs are *nested*, but goto totally violates 
that whole idea, even if that's not what the programmer intends.


> A good clean goto

IMNSHO, a goto can never be clean if it jumps across nesting levels. 
Right; not that I really care about rules just for the h*ll of it, 
but this one is actually important. Funky stuff easily happens when 
you start bypassing the native constructs of a language...


> with a sensibly-labelled target in plain view, is far easier to
> read, support etc. than the eleventy-deep-nested "break"

How is the goto any less deeply nested than the break...? The break 
would refer to a nesting level by name, and the goto would refer to 
some labelled location in that nesting level.


> which the
> compiler will turn into an asmb goto anyways.

If the generated code had anything to do with anything, I'd just drop 
all the high level control flow constructs and throw in conditional 
goto instead. ;-)


> It's better, because
> it's explicit.

I disagree. The "break <name>" is *more* explicit than a goto.

        * The block name referenced is explicitly a block name,
          and not just some place where the coder happens to put
          a label.

        * You can't accidentally place some code on the wrong
          side of the label, because the name is associated
          with a nesting level; not a code position.

        * "break some_level;" explains more accurately what
          you want to do than "goto some_label;". It actually
          means "keep break;ing until we're on some_level",
          which is *exactly* what I mean when I use such a
          construct.


> >However, "break <n>", while rather nice and useful in cases, is
> > pretty evil as well. The biggest issue is that you can't clearly
> > see where you land, and it's easy to mix up ordinary {...} blocks
> > with breakable blocks and land totally off without even getting a
> > compiler warning.
>
> Hey, if u have a clear goto label, u see just where u land.

Yeah, but I don't want to tell the compiler where I want to land. 
"break;" means "leave the current breakable control flow block." I 
don't want to use some completely different construct just to say 
"leave the current block, and then leave the block I land in as 
well".


[...]
> >So, I figured if I reference outer scopes by name when breaking
> > more than the current level, the code gets more readable, you
> > can't accidentally land on the wrong level, and the risk of
> > breaking stuff when you modify the code is lower.
>
> A close runner-up, IMHO, and rather more tedious to implement.

No big deal. I just support explicitly naming code blocks (as opposed 
to giving them an internal dummy name), and then I put a loop around 
the code that prepares for leaving a code block. (That's where local 
reference variables and stuff is dealt with, so you don't leak 
objects when backing down the stack.) And finally, the jump 
instruction. :-)

Implementing goto is actually harder in a language with automatic 
memory management, it seems... The biggest issue isn't this part 
(dealing with leaving "contexts"), but the fact that you can also 
jump over initializations. It's hairy enough as it is to verify that 
conditional code can't leave variables uninitialized.


//David Olofson - Programmer, Composer, Open Source Advocate

.- Audiality -----------------------------------------------.
|  Free/Open Source audio engine for games and multimedia.  |
| MIDI, modular synthesis, real time effects, scripting,... |
`-----------------------------------> http://audiality.org -'
   --- http://olofson.net --- http://www.reologica.se ---


Other related posts: