In Defense of C
girtby.net
girtby.net
Anyone sitting down to write an article on what a programmer needs to know should take that sentence as their mantra.
C is definitely one of, if not the most important languages a well-rounded programmer should know. But realistically, there are millions of programmers who get along perfectly well without knowing it. In unusual cases like those described in this article, they'll get around their ignorance of C by leaning on a forum, guru, or a third-party library. In fact, the number of programmers who do know C is (vastly) smaller the number who don't.
Lest anyone think I'm celebrating ignorance, that's not the point. I come at programming from an engineering perspective, and C rates highly in my pantheon. The point is that for any requirement someone can come up with for a 'good' programmer, a pretty good chunk of the community has gotten along just fine without knowing it.
Ultimately this debate is less a question of what someone _needs_ to know, and more about how circumscribed a professional life they're comfortable with.
all the major operating systems, all the high-level language runtimes, all the databases, and all major productivity applications are written in C
Live in high-level language land for your entire career?
but sooner or later a crack is going to open up and the abstraction is going to leak.
And on that day, boy will you wish you knew C.
</quote>
On the other end of the spectrum, I have also worked on a large client-server app at a company whose workforce was taken from the local community college with courses in programming taught in C. Every time these programmers wanted a new collection, they rewrote Linked List. No exaggeration. There were many hundreds of independent implementation of Linked List. I was looking over a shoulder of a programmer, who was showing me that this was what I should do, and watched her showing me how to reimplement linked list. One client even got fed up and tried to introduce a library called "Super Link." Programmers in this shop ignored it and went on reimplementing Linked List. Management at the company determined that "Super Link" would just be particular to that client. (No one understood passing function pointers.)
These programmers thought the C compiler was some kind of "magic." Every time I tried to talk about the call stack, they would give me blank stares.
Reading Guy Steele's late-1990s defenses of Java, and observing how C and C++ actually are used in industry -- yeah, I actually am happy that Sun managed to bring Joe Application Programmer about halfway to Lisp. In general, magic features like built-in garbage collection and all the basic collections in the standard library are a Good Thing. The main problem I see is that C is designed for systems programming, where everything really should be explicit, while most of the code that actually gets written belongs at a much higher abstraction level. Still, even in higher-level languages there are edge cases that make much more sense if you understand how the situation looks from the level of C -- for example, performance profiles.
(At the self-deprecating C shop where I worked last, I was the one deleting macros, wrapping lower-level code with Swig, and pushing Python and shell scripts for new code. We used glib, too -- which removes 10% of the pain while demonstrating ever more clearly that C should not be the primary language for big userland applications.)
That's not to say knowing C isn't a good idea, in part for the other reasons the author listed and in part because C and Lisp are near, if not at the ends of the high/low level language spectrum. Understanding the machine provides valuable insight for programmers, even if they never actually use C in real programs.
What is it built on top of? Your environment is not based on Unix, Mac OS, or Windows? I thought Lisp Machines were part of history.
You write a fairly straightforward* Lisp interpreter in some existing language (often C, though ML seems like a good fit as well), use that to execute a Lisp compiler written in Lisp on itself, and presto, you have Lisp all the way down to the machine code. The non-Lisp scaffolding is only a temporary support for the initial construction. It may be built with C, but then the C vanishes. It isn't on top of it in any sense.
See also: http://en.wikipedia.org/wiki/Self-hosting -- Compilers for Haskell, Smalltalk, Factor, C, etc. have been done this way, too. There's nothing specific to Lisp about the process. Consider: What are C compilers written in?
* I.E., don't bother optimizing it much if it's only run to build the compiler. Making it simple for easy porting is more important than speed.
mechanical_fish is correct that I'm running CL on Linux, which is written in C. If I have a problem that requires me to gain some deeper understanding of Linux than I can get from the documentation, I will have to read C.
All of that said, I think this isn't an especially compelling argument for learning C. The understanding it brings of how computers work is more valuable for most programmers, I think.
The only thing that tripped me up for a while was pointer syntax, but that wasn't a problem after I realized that * simply means "dereference". Segfaults suck, but then again you can just printf() something right before and after a suspicious block to see where the problem lies.
Finally, what I'm getting at here, is that I'm not sure if I can say I "know C" or not. I've written several apps, including a RPG/style game engine and a chess AI. But essentially, there was no learning curve. It just makes it really hard to judge my skill level.
Also, I would like to note that C is a great programming language. Did I mention I like C?
I apologize for that incoherent post. But hey, logic is for programming.
I think this is the text that was intended to be cited.
Thanks to the GP for posting that article, it's well worth reading for any and all of Bram Cohen's insights.
#include <stdlib.h>
#include <stdio.h>
int main()
{
printf("true that\n");
return EXIT_SUCCESS;
}