|Comments on Friday 5 December 2003:|
|Why You Shouldn't Believe Anything University Teaches|
Today I was struck by a realisation related to my programming practices. I have been programming for many years; I wrote games for the Atari ST in 68000 Assembly language, and in STOS Basic. I finished writing many games, and had very few unfinished. In fact, I don't remember ever having an unfinished project in those days, except for one insanely ambitious project - and even that was going quite well, but it was too big a project for the deadline I had.
C is not so different from STOS Basic or Assembly language. The one main difference is that there's a lot more emphasis on using the stack rather than global variables. Especially if you learn C from a higher education institution. They will tell you that using global variables is bad.
I have finished some projects in C(++). Those finished projects all have a high concentration of global variables. I have many many unfinished projects in C(++). Those projects were "well-written", with lots of "reusable" code. I have never reused any of that code.
Global variables being bad is largely a holdover from the days of yore, when memory paging was a slow painful operation. Nowadays, global variables are often no worse than using the stack - and most of the time even if you weren't using global variables you'd be using malloced structures which end up on the same heap your globals would be on.
Reusable code is a consideration if you write many things that are exactly alike. Excel and Access, for example. Most programmers, especially game programmers (except for those bastards who keep writing Quake over and over again), don't write many things that are exactly alike. Reusable code is a waste of time and effort, and will just end up abstracting away the functionality you'll later find yourself wanting.
This realisation struck me when I realised my latest project has stalled, during the menu-writing phase. Most of the gameplay code works, and works well. Most of the gameplay code, though not using global variables, is functionally equivalent to using global variables. The menus, on the other hand, I was writing reusably, object-oriented, in a manner not unlike Windows; buttons as controls that are stored in a list within a given menu screen, things optionally nested within other things. Now I realise that writing it this way involves three times as much code as it would be to just write each menu screen as its own pair of functions, or even as a simple switch within two functions; "draw screen", which would have several calls to a "draw sprite" function for each button, per menu screen, passing coordinates and sprite identifier, and a "do click" function which would have simply a sequence of 'if' statements redirecting to the appropriate piece of code if the click is within the appropriate button. Parsing through lists of button structures with virtual functions and passing links back to the current menu for dealing with the result is complicated and awkward in comparison to this simple method.
For the sake of comparison, imagine the code for "user presses tab". In the object-oriented example, you'll want to parse through all the controls to find which one currently has the focus, deselect it, loop through the linked list of next controls until you find a focus-compatible control, looping back to the first one if there isn't a next one, and select it, then redraw both controls. In the simple global-using method, you'd add one to a "selectedcontrol" variable, make it zero if it has exceeded the maximum value, and redraw the screen.
Programming in C should be as easy as programming in Basic, once you have the lower-level functions down.
If, and only if, you make sensible use of global variables, it is that easy. Most versions of Basic don't have a stack, and don't have a malloc. This is very rarely a problem. Most games don't need a stack and don't need a malloc.
As for me, I intend to scrap my existing menu code, and rewrite it as if I was coding in Basic. It'll be faster to code, faster to run, and maybe I'll actually get something finished for a change. [11:01]
|im a sucker for punishment... i use globals, they sound like penis ;) - damn that shift key|
|I have no idea what any of that meant. Suddenly I feel much less like a genius. Maybe I'm an English genius - Lord knows I don't get math or computers. I'm confused.|
|Dang, this really makes me wanna start working on my own stuff again. Course, that means getting what I need, for the things I have, but dang, I really should get back to it all.|
|Hrmm... I've always hated the idolisation of OOP style. Sometimes it's wonderful; other times, it's just stupid. My Java class at school aggravates me to no end- sometimes, if statements are NOT the enemy. An example that springs to mind is that of a simple RPN (Reverse-Polish Notation, AKA Postfix) terminal app we wrote. Rather than using some bizarre 'OOP' method of writing a reusable Stack class that stacks Objects in a LinkedList, I opted for a simple array-based stack implementation directly in my driver class- its a very simple program, no need for multiple classes, right? Wrong. I was made to rewrite it using the 'better' implementation of a Stack that uses LinkedList which uses ListNode and then deal with the hell of ridiculous amounts of type-casting when all I wanted to store was a few lousy ints. Just for fun, I think I'm going to write a simple benchmark for each one (some extremely basic method; I'll start a timer at the beginning of each main and print out the time it counts at the end) to see just how inefficient the 'superior' OOP method is, never mind the much longer, less readable code (Which do you prefer, stack[k] = Integer.parseInt(str); or stack.push((Object)(new Integer(Integer.parseInt(str))));?) or the higher memory usage.|
|I've been doing OOP for 15 years. The purpose of OOP is to reduce the cognitive load on the programming team, not make the code more efficient. If OOP isn't doing that, then you are either not using it right, or trying to use it for the wrong problem|
|Ah, but how many projects have been completed in that 15 years?|