Old Content   This page is now considerably out-of-date.
Languages

Introduction

I've been programming for years now and have used many languages, here I talk about my favourites. On one level they're all quite similar - if you can program in any one of these, you've cleared the main hurdle; learning another is a smaller effort. There is no 'best' language - this depends on what you use it for. However I would say that my favourite language is Python.

Machine Code & Assembler

Machine code is the binary that the CPU directly understands. No-one programs machine code. Assembler uses human-readable names for instructions, variables and code blocks, but is essentially the same, as each instruction maps directly to a machine code instruction.

This promotes a certain logical way of thinking, as you are forced to think in terms of the very simple things the processor can directly do. However, it takes forever to create just a trivial assembler program, and the code is completely processor specific. Because of this, few people now program assembler.

For most general-purpose programming, assembler doesn't run significantly faster than optimised C. However, particularly CPU intensive tasks, e.g. encryption, are sometimes written in assembler. Slimming these down by microseconds is a highly-skilled discipline. Another use of assembler is performing processor specific tasks, e.g. implementing virtual memory.

C

C is low-level and compiled; in a way it's portable assembler. You have a good idea what your code will translate to in machine code, but the language offers enough built-in features to make programming practical. It is intended for building serious programs, OS kernels, networking stacks and interpreters. It is one of the most popular languages; Unix operating systems are built on and around it. The user space library is called "libc".

Using C, you have unmonitored memory access and complete control over memory allocation. This invites efficiency, but makes it prone to hard-to-find bugs. Despite all the tools available, developing a robust C program is a much greater task than doing so in a higher-level language. Maintaining good programming style is always possible in C, but often hard work - the language does very little to help you.

A feature pretty unique to C is the pre-processor. This lets you have sections of code that are included or excluded at compile time. One thing this enables is having both a debug and a release build of a product. The debug one contains a load of code to double check things are working ok, provide tracing hooks, etc. The release version is lean and mean.

Shell Scripts

This a very high-level language - a line of shell script often translates to running an entire C program. There are loads of utilities made for shell scripts, e.g. sed, awk, basename, sort, tr. By putting these together creatively, you can do very powerful things easily, for example to process a kind of log file I had into a list of URLs and hit counts:

cat log.txt | awk '-F|' '{print $5}' | sort | uniq -c > pghits

A similar C program would require at least 25 lines, even in its most hacky form, and without much further complication would impose arbitrary limits on length of lines in the log file and the number of different URLs. However, trying to handle shell script errors intelligently is difficult, so they aren't particularly suitable for distribution.

Perl

Perl tries to bridge the gap between C and shell scripts. From C's point of view it looks after memory allocation, does bounds checking, is loosely typed, provides high-level IO and has loads of modules. From the Shell's point of view it can do loads more without having to run an external program. From my point of view this is really cool stuff!

You can make Perl very concise, which is great for quick hacks, but quickly becomes illegible. You can make it more verbose and readable, but this isn't very natural and you code is still full of weird things like @$_ Perl does have object-orientated capabilities but they have clearly been bolted-on afterwards; they're not a natural part of the language.

Python

Python aims for similar niche to perl, but is a much more structured language. Everything is done is a neat, object-orientated fashion that feels very natural to me, and the code doesn't end up full of weird symbols. Three things I love about Python are loading a file - open('filename').read() the inline sprintf operator - "%s is %d years old" % (name, age) and the unique way of doing loops, which uses the indentation to tell where the loop finishes:

for i in range(1,10):
 print i

Now, Python is probably my favourite language, but Perl still beats it for doing quick hacks. For example the other day I wanted to add up a list of numbers quickly. This is a few lines of python, but perl was brilliant:

perl -ne '$a+=$_; END{print $a}'

C++

This is arguably the most powerful programming language that currently exists. It aims to combine high-level object orientated style with the low-level efficiency of C. It has several unique features, e.g. template classes. The Standard Template Library (STL) is very impressive in its breadth and efficiency. However, the language seems to have fallen into the trap of being too complicated. Traditional compiling/linking schemes are broken by templates. Debugging is made difficult by function name mangling and polymorphism. Different compilers are not fully compatible with each other. In trying to be both high and low level, I feel it has got the worst of both worlds, not the best.

Java

The language itself is quite similar to C++, though it lacks features like templates and operator overloading. In Java pointers are hidden behind references in a very clean way, and it has built-in garbage collecting. The major difference is that Java is compiled to byte-code, not assembly. This is portable, which allows clever things like embedding Java in web page. Java is a fantastic language, but I don't actually use it that much.

SML

Standard Meta Language is very elegant and mathematical, wonderful for understanding the flow of algorithms. It's quite different to the other languages presented here, as you generally don't use loops or variables. This style is called functional programming where you break everything down into function calls - so a loop becomes a recursive function. Some functional languages can be completely theoretical, but ML can be used for practical applications. A Particularly impressive feature is the type checker, which is strict, but doesn't require you to define everything. If it sees (x+1) then it knows x must be a number, as you can only add numbers to numbers. But if it sees (x+y) it lets x and y be any two types that can be added e.g. vectors, co-ordinates.

© 1998 - 2012 Paul Johnston, distributed under the BSD License   Updated:13 Jul 2009