The C language is old. Really old. It's older than the parents of some of the people reading this.
(Okay, it's not that old; the English language is older and so are some of the houses in which the people reading this are sitting, but it's old in terms of technology, which evaluates technology in units of "how new is this?" and "how few people know this yet?")
C is more than four decades old, and yet C compilers are still being written and C specifications are still being written and I have a fair amount of money invested in a semiconductor company that sells to a lot of people who write C code to make phones and calculators and microwaves and DVD players and all sorts of industrial and consumer electronics devices work.
C may not be a language with the ironic mustache and candy-colored rounded corners of the latest Y Combinator-funded todo list social networking app for marmots who love mobile analytics (they pivoted halfway through me typing that sentence), but people use it to get things done, and even among the brogrammer set, you will get people admitting that "You know, I don't consider myself a real programmer, because I don't know how pointers work."
No one really thinks "I want to use the C language version 5.20" or "Wow, if C had a newer version number, I could totally justify using it for the touch-screen microcontroller!"
Then again, C has a specification. GCC and LLVM both attempt to keep up with what's in, for example, the C11 specification. So do the C standard libraries on many operating systems.
(Okay, Microsoft's a holdout here. It took Microsoft several years to get around to supporting CSS in IE, which would have had arguably more users than a C compiler, but Microsoft's too busy trying to figure out how to release a tablet computer one of these years, so I'll give them a break. Technology is hard.)
C does have its warts: its type system is a series of patches on the PDP memory model, its linking and symbol visibility mechanism is baroquen, and it's funny how people like to communicate in text with things like string data and the language really doesn't support that. Oh, and its mechanisms for parallelism and concurrency mechanisms for parallelism and concurrency mechanisms for parallelism and concurrency dead lock memory corruption purple monkey dishwasher contents of /etc/shadow:.
Go won't kill that off either.
What C does have going for it is a history, a commitment to backwards
compatibility, an ecological niche that's grown to expand just about every
operating system everywhere—even places where the only operating system
you get is the bootloader you wrote yourself in 256 bytes and if you want to
printf for anything more complicated than 16 bit integers,
floats, and strings, you get to write it yourself (I told you, I'm not running
the timing system of my new car on an embedded web browser through a RESTful
single-page Angular.js app, no matter how much you insist it's the wave of the
future)—because it's useful. That's pragmatic. Also, there's a
specification the degree to which you can decide your implementation will
That's why GCC exists. That's why LLVM exists.
I'm not sure that anyone thinks C is more or less relevant because there's a K&R specification, a C89/C90 specification, and a C11 specification.
Now what about Perl?
Perl first appeared in the '80s. You can claim the current version of Perl dates from either 1994 (Perl 5.0) or 2007 (Perl 5.10).
Perl has an enormous test suite. It's almost comprehensive. It covers major, minor, and esoteric features of the language. It also has very comprehensive documentation (almost too comprehensive in places).
Yet Perl has a single implementation. It's had at various times attempts at alternate implementations—some used the test suite and some didn't—but there's no serious worthy secondary implementation.
Contrary to the six-monthly nonsense that "Perl Cannot Be Parsed", this isn't because writing a parser for Perl is difficult. (It is, but writing parsers for complex languages is difficult anyway. You're not a language designer. You polluted a global namespace with a bunch of silly little self-chaining methods and called it a DSL.) This is because implementing a Perl is difficult, and that's because no one knows exactly what you have to do to implement enough of Perl.
... whereas everyone knows exactly what you have to do to write a JVM or a C compiler and standard library, because there are specifications.
The presence of a specification makes the task of reimplementation neither easy nor simple, but it makes the task more possible and much, much more plausible.
More than that, you can revise a specification, such that you identify the essential, experimental, and ephemeral components of a modern implementation of the language and runtime and ecosystem. People who want the old version know where to get them, and you get to continue to evolve because you're setting concrete and specific expectations.
In the Perl world, Task::Kensho has attempted to do this with a collection of recommended CPAN modules that would form an extended core of libraries the average Perl developer should have installed. In the Python world, one might fairly characterize a recent slowdown in proposed enhancements as a love letter to alternate implementations to help catch up to the 3.x series. (A specification is not in and of itself a sufficient precondition to language success. P6 has had a specification for years. Perhaps specifications are, like frameworks, best when extracted from working projects.)
This is difficult work and it's less rewarding than it sounds. It's fraught with peril. (Do you specify smartmatch? ithreads? XS? Autodereferencing? Tie?) I haven't mentioned this to p5p and the idea might be met with universal disdain or even polite ignoring.
Yet there are advantages beyond even the ability to promote a language and platform as current and vibrant—but that's the subject of another post.