Since I've been teaching J how to program in Scratch off and on, I had the rare moment of talking to my parents about programming languages the other day. There's not usually much to say about specific programming languages with someone who doesn't write code--though there's lots to say about the nature of programming, and I have a blog post in the works about that--but I mentioned I was reading some horrible C++ code and it was a little tricky because I don't really know C++. I used it a couple semester in college and that was it. Mom said, "But you can tell it's horrible anyway?", which I can, and that got me thinking about why, and what I understand about programming languages and how they're related, and all kinds of stuff.
Programming languages are not mathematically related to human languages, but they're related inasfar as they're made by and for humans. Much like human linguists, we talk about "families" and "dialects", and languages influence each other's development, often with cycles of back-and-forth borrowing of ideas. To see this profusion, take a look at the canonical
Programming Languages Family Tree, or O'Reilly Media's
much prettier version (now somewhat out of date).
Making a programming language is now well-enough understood that college students do it in one semester. Making a programming language that's
useful is a whole other project, and highly likely to fail. Solving a real-life problem isn't just about the language, but about its associated libraries, which need to:
- manipulate files on disk and otherwise talk to the computing environment.
- deal with networking.
- deal with multiprocessing (doing more than one thing at a time).
- provide utilities for common programmer needs, like finding the length of a string of text.
This is a lot of work, and programmers have limited time to learn new things and even less time to actually adopt them, so your language has to have something special to offer to get off the ground. Java, for instance, looks a lot like C++ but doesn't suck quite as much. Ruby, which I work in, lets you accomplish a lot of work with very little code. Python is similar to Ruby, but a bit easier to read. And so on.
Enough describing. Why can I be judgemental about C++ code when I don't know C++? Let's start with some languages I'm more familiar with. Here's a
class in Java. A class is technically defined as "a thinger that combines data with the operations on that data". Like so:
public class MessageCounter
{
int count;
MessageList messages;
public void receive(Message msg) {
MessageList.add( msg );
count++;
}
}
(None of these examples are complete, by the way. I'm stripping out a bunch of stuff that's needed in real life but would just obscure my point.)
That
receive()
thing is a
function (or sometimes
subroutine), but for irrelevant historical reasons, when a
function is part of a class, we call it a
method. The
++
operator comes from C, and increments a variable by 1.
My second language was Perl:
module MessageCounter;
$counter = 0;
@messages = [];
sub receive {
my $msg = shift;
push @messages, $msg;
$counter++;
}
Okay, that's a bit out there, I'll grant you: Perl is not for the faint of heart. But see how there's still a block marked
MessageCounter
, we're clearly doing something with a structure named
messages
and the message we received, and there's that
++
again.
sub is short for "subroutine".
Here's Ruby, invented some years after Perl by a guy who couldn't take Perl's punctuation any more.
class MessageCounter
def receive(msg)
@messages.push msg
@counter += 1
end
end
See? It's like Perl, but easier to read. Ruby lacks the
++
operator, so we say
+= 1
: in this language family,
=
means "assign the right side to the left side", and
@counter +=1
is shorthand for
@counter = @counter + 1
.
After all that, here's C++, which predates all three.
class MessageCounter
{
int counter;
MessageList messages;
public void receive( Message msg ) {
messages.add( msg );
counter++;
}
}
That's right. There's a one-word difference from the Java. C++ is a huge, awful language, and even professional C++ programmers often don't know all of it, but much like seeing
Catalán when you know
Spanish, you can usually get the gist.
As for judging quality, because all these languages belong in a very, very large category called
imperative languages, and furthermore (because they have classes) they're
object-oriented,
(Pedants: Yes, Perl is not object-oriented. Hush, it's not important right now.)
there are common principles, the subject of many many books, of how to organize programs in a way that is comprehensible. The code I was reading violated many of those principles.
See? Simple!