Saturday, July 10

Language Complexity

"Simple things should be simple. Difficult things should be possible." This is the hallmark of any good computer programming language. If it is hard to do a simple thing, then the language is poorly designed.

I don't know who this quote is attributable to, but it is language design in a nutshell. The devil, however, is in the details, as ever. I'd like to start this series of posts about language complexity by taking aim at two canards within the game development community:

One: Garbage collection is evil. There's a myth that garbage collected languages are unsuitable for game development because games are soft real-time applications and a decent framerate is one of their prime requirements. The pauses due to garbage collection are often cited as a reason for not using such languages as Java and Lisp or Python. Each has separate issues that are problematic for game development, but Garbage Collection isn't among them. Typically a soft real time game allocates all the resources it needs prior to entering a main loop and then does NO MORE ALLOCATION. It's at this point garbage collection is moot as no more garbage is being created for collection, providing the compiler has a mechanism for creating function-local variables on the stack frame or in registers rather than the heap - which both Java and Lisp compilers can do. So the recipe for a game would be: pre-allocate all arrays, globals, etc needed for resource tracking in the main loop, switch off garbage collection, make any heap allocations an exception (so they don't creep in by accident), then when the main loop (shooting the aliens, driving round the city, flying the spaceship, whatever) is done, switch off the exception and switch garbage collection back on. Yes, it's really that simple. It's dynamic allocation and heap walking that is the true problem for a soft-real time system..that's all. More information can be found in the Garbage Collection FAQ.

Two: Static typechecking is a win. Yes it is, but only in a language like C++ where the cost of compilation is HUGE. Compile times of an hour were common on Driv3r. However, your typical Python or Lisp program is composed interactively, and run instantly. In this case, pushing type checking to run-time is no big loss. Which is Python's approach. The other approach is the Lisp approach - to pick out a single, versatile data structure and operate on it as much as possible as in : "It's better to have 100 functions operating on 1 data type than 10 functions operating on 10 data types.". Further discussion of this can be found *here* on Bruce Eckels Weblog .

I'm going to follow up this post with the implementation of a name-generation algorithm in a number of different languages, starting with the original, in Python. It's better that the languages speak for themselves.

No comments: