Experience And Productivity
As an easily interested programmer, I've come to realise that there is such a wide variety of amazing things to be done, and nothing gets me more frustrated than realising I'll not be able to do them all, no matter how little I sleep. However, there are many shortcuts that can be taken, which generally help finish the task quicker. These shortcuts and the art of using them at the right time only become obvious with experience, and I still have a lot to learn in that respect.
My next techfile update will consider how the use of interfaces can facilitate, and speed up development. This techfile is concerned with trying to explain why different languages can be better suited to random tasks and more importantly, why some are not. Being able to pick the right language for the job not only requires the programmer to be open minded enough to accept alternatives - which is arguably one of the most important skills to have - but also the capacity to learn how to approach the problem from a different angle, which in time can be reproduced within other languages to aspire perfection (mmm, that sounded nice ;)
My experience of programming languages is fairly broad, but a bit more limited in depth than Pascal or C++ for example. The next few paragraphs will try to show the practical advantages and disadvantages of each of the languages considered, including how easily they can be assimilated and how useful they are to games programmers.
Ada is a very secure language, as it was designed for military use. At first glance, it looks a bit like Pascal and in some respects is just as easy to learn. However, it has among other things very strong dynamic type checking, which most C programmers find quite frustrating. For example if you define a type of integer that can take only values in the range [0..100], and assign a variable of that type the value 101, you will get a nasty runtime exception. And there's no way you'd be allowed to increment a pointer! On the other hand, some other features of the language are surprisingly easy to get accustomed to: you can actually do the 'full Monty' of multiple inheritance, by deriving an object from two classes separately derived from a base class (joining up the inheritance tree), unlike C++. The package structure, different to any other OO language I've used, does actually work quite nicely when you get used to it. Another nice feature resides in its multi-tasking capabilities, which I haven't yet explored fully. I nearly forgot about nested procedures, which make a nice change to C++.
All these sexy features come at a price: there is an overhead for all this. Everything executes slower than C, for example, but still retains its real-time properties. Hence the reason why it's used for real time systems, where concurrency is essential.
Advantages: Secure, well designed
Well, it's been a while... I haven't coded in assembler since the assembler column of The Art Of Demomaking. I have to admit I don't especially miss the frustration of coding so close to the hardware. However, I do miss the satisfaction of having a finely tuned set of optimally efficient instructions, that pair nearly perfectly, that read the cache in a perfectly linear order, and knowing that only M. Abrash himself could squeeze cycles out it.
Although I strongly recommend coding in assembler at least once, just for the knowledge of how the hardware works and how best to optimise higher level code for it, I have to admit it's not the way forward. Code is hard to maintain and understand, even if you have one comment per line, and the time you spend writing the code could be used in a much more constructive fashion. However, if your program spends 99% of it's time in 16 instructions and you need the extra 4 FPS, then don't hesitate to get your hands dirty. The modern approach is leaning towards intrinsics, which strongly hint at the compiler how to assemble the code, but don't force it. I recommend this approach.
Advantages: Simple, low level, fast
I was one of those programmers that was fortunate enough to move straight from Pascal to C++. So I didn't have to go through the tedious process of learning to put up with the restrictions of C, and rather more enjoyably moved straight on to C++.
Anyway, back to the point. Pure C is, or rather should be dead. The only reason I can think of for using the language is portability. C is pretty much the only language you are guarantied to find a compiler for on any old machine or console. That aside, modern and up-to date programmers have no reason not to use C's older brother. Indeed, C++ can do the C aspect or C better than C can! I'm talking about being able to declare the variables anywhere in the scope, using inline functions instead of the dodgy macros, and the snazzy one-line comments. That's style covered, now for efficiency. Const correctness, together with clever use of intrinsics and the restrict keyword with the Intel compiler pretty much guarantee that you'll at least the same performance out of C++. Read on for reasons why to use C++ rather than the plain old C.
Advantages: Portable, a lot of source available, can be fast, fairly low level control
So as we've seen, C++ has now fully superseded C, and it's just a matter of time before every one catches on. The question is, is it worthwhile using the object orientation (hehe ;) of C++. In my opinion, yes. Fair enough, if you want to do things properly, the extra time spent designing and organising classes will be quite consequent. However, most of that you will gain straight back while debugging and maintaining the code (see my update on Good Practice).
Advantages: Everything C can do, structured, safe, very good tools available, lots of source and tutorials
Wow! What can I say... If you've ever wondered how much different to C can a programming language can be, and still remain useful, take a look at this language. It's a fully functional language, which means everything in the language is based on functions. High order functions can for example take a function with say 5 parameters, and a frozen value and return another function of 4 parameters with the specified value fixed.
There are lots of cool tricks to be done with this language, such as lazy evaluation and infinite lists for result storage. These are very elegant features, but in the whole scheme of things, I'm not sure where the language end up...fib n = fiblist !! n where fiblist = 1:1:[a+b| (a,b) <- zip fiblist (tail fiblist) ]
Advantages: High level approach, refreshingly different
Now watch out for this one. It's one of the quickest growing development languages in history. And I have to admit the little Java I have used has been very enjoyable. Although it seems fairly close to C++, the language does reflect quite a lot of maturity in the design, notably the way threads were planned within the OO paradigm right from the start. C/C++ user will complain about the lack of pointers, but in my opinion that makes learning the language easier.
One could argue that the problem with Java is the speed, and indeed due to its portability it can suffer performance-wise. However, machines nowadays can generally handle the overhead, and programmers should rather more concentrate on the complexity of their algorithms rather than the constant by which it runs (that's a nice theory ;). Additionally with Java VM hardware being in the works and with native code Java compilers rumoured, you can expect this language to flourish.
Advantages: Portable, good tools, nice design, lots of documentation and source
Hmmmm, this was the first language I learnt at the start of my course here in York. When we questioned the lecturer about his choice of a language, he said 'If you can apply the concepts with LISP you can do it with any other language.' It does seem extremely confusing at first, but with the correct guidance and enough perseverance it does become possible to program simple tasks!
The AI field seems very keen on Lisp, and to be honest during my assessment in the first year I only explored minute portions of the abstraction possible with this language. Quite recently, I've seen very similar notation used for representing and evolving neural networks, so it seems this stuff is useful after all!
Advantages: Abstraction, it's notation can be reused for other purposes
Aha, the old favourites. This is an amazing language to start learning. At the time when I started, not having the researching skills or any access to the net what so ever, and with the code archive I had available being in C, I had to code most of my core routines up from scratch. This was very good experience, and although it probably took me a lot of time to get not very far at all, I have to admit I've really benefited from it since then.
The language itself is very nice. Easily readable, structured, it even has nested procedures. Shame that the flow went towards C instead, as I believe this language would have done just as well, if not better.
Advantages: Easy to read, lots of source, can use Delphi for OO
Now this is a very useful language. It's fairly confusing to read at first, mostly because of the $ & @ and other random signs before each identifier. Once you've found out that they only represent the type of variable they are associated with (e.g. array, hash table, single value) the code becomes very easy to read. It's like having an in-built naming convention. The rest of the language can be considered as a simplified version of C, with all the redundant brackets removed and advanced regex support. And that's where the beauty of Perl lies: it's amazing string processing capabilities. Apart from the standard web applications for which it is a 'must use', I can see quite a few other uses: generation of trees with L-systems, parsing huge genetic algorithm statistics, DNA sequence analysis in biology.
Advantages: Brilliant string manipulation
Apart from the fact that it's completely different to anything I've done before, the main problem I have with prolog is it's whole concept. Unmodified, it's basically a huge depth first search routine... As I've progressed in Prolog, partly by doing simple AI and Natural Language Processing, I've found it's not all that bad and that you eventually do get your head round to this way of thinking. So adapting to the differences of logic programming if a matter of time, but finding uses for it can be quite challenging (well, among the stuff that you and I want to do ;). And despite the fact you can customise its behaviour in a supposedly flexible way, it only remains a valid option for few specific NLP problems. I would have no problem in using this language again, if only for the refreshing change from procedural thinking, but I doubt the opportunity will arise. Although I'm probably just saying that because I don't actually HAVE to use it anymore...
Advantages: Well suited to specific AI / NLP problems
Learn any language if you have the opportunity and time. It's good experience, and you'll probably welcome the change. If not, then it's good practice to try alternatives, to put things into perspective and acquire the general open mindedness of a programmer. You'll thereby be able to apply new ideas into your current applications.
Besides, it's your duty as a computer scientist to be able to hold conversations with anyone about anything, so knowing many programming languages is a good start!
My 2p ;)
Take it easy,