Bad reasons you should learn C.

DAxelrod on 2006-11-30T02:21:30

Beatnik's response to an unconvincing argument for learning C got me thinking. Here's my response.

2) Device drivers and operating systems are written exclusively in C. Now, you may never write a device driver or an operating system, but what if you are ever required to modify one?

Rare modification of device drivers aside; I think a better reason (sorta related to this) is that C was designed to write Unix in. Learning C may allow you to learn more about the internals of your OS.

4) C programs are smaller and faster then any other program created in a different language. Sometimes your program needs that speed boost that only C can give it.

False. Sorry, but this is no longer the case. Compiler research has come a long way.

For example, look at perl's highly fine-tuned regular expression engine written in C. CL-PCRE, a Perl-compatible regular expression library written in Lisp, claims to outperform perl's (when compiled with CMUCL). Yes, there are many problems whose C implementations are faster, but this does not hold true for all programs or all architectures.

5) If you have learned C, you can learn any modern programming language. The reason behind this is that all modern programming languages are based on C

Many programming languages have syntax that's kind of like C. But all? Scheme is based on Lisp. Prolog is almost nothing like C. As isn't Haskell. I have trouble believing that SQL and C share much in the way of parentage. XSL? I could go on.

Much more important than syntax is paradigm. My problem with the "learn C and you can learn anything" argument is that maybe if you learn C you can learn other procedural languages. Knowing C ain't gonna get ya very far in learning functional or logic programming. And most of the languages that are based on C have powerful language constructs that C lacks. Closures, for example.

8) C is the only language that teaches you what pointers really are. C# and Java skip the subject completely. It is pointers that give C its power.

A power we have yet to fully understand how to harness. Like goto. The indirection role is played by references in Perl and equivalents in other languages. The continguous addressable block of memory space? Arrays and iterators mostly take care of that. The fact that dynamically allocated memory is only accessible through indirection is not a feature, though.

Face it, C's pointers (and the language infrastructure they're related to) are the reason buffer overflows exist. Let's figure out how to stuff them back into Pandora's box before they become widespread. Oh wait, we didn't.

I can see the power of C's pointer implementation because it allows for all kinds of crazy Turing-machine possibilities. With those possibilities come risk.

9) C is still the most commonly required language for programming jobs.

My gut feeling is that the language of choice for PHBs these days is Java, but I have no data to back up my assertion either.

10) Anything that has a microprocessor in it has support for C. From your microwave to your cell phone, C powers technology.

I could sort of see this argument being valid if you were talking about IA32 (which seems to have a lot of C primitives as instructions), but otherwise not so much. The processor has no support for C.

If you want to argue almost every architecture has a C compiler for it, you'd be a lot closer. Some of this is because C is self-hosted, but some is also because C is good for getting close (but not too close) to hardware.

Please note that I am not trashing C. I happen to think it is also worth learning, for different reasons. I'll have to write those down later.


different alghoritms

salva on 2006-11-30T08:45:23

For example, look at perl's highly fine-tuned regular expression engine written in C. CL-PCRE, a Perl-compatible regular expression library written in Lisp, claims to outperform perl's (when compiled with CMUCL).

CL-PCRE is a compiler while perl regexp engine is an interpreter, so it's not the compiler, it's the algorithm what is faster!... though you can argue that writing portable compilers in C is almost imposible while in a high level lenguage like LISP it is trivial.

Anyway, I agree with you that C is not the fastest think anymore, I just didn't like the example!

Re:different alghoritms

DAxelrod on 2006-11-30T21:30:23

I'm ignorant of CL-PCRE's internals, and (fairly) ignorant of perl's internals, but I'm not sure it comes down to a compiler vs an interpereter. It's about whether the intepereter is implemented directly in hardware.

As I understand it, perl compiles a regex into its own intermediate (bytecode) representation, and then interperets the compiled regex.

Unless CL-PCRE's compiler outputs native code that the processor can inteperet (I guess it could also output Lisp that CMUCL could compile into native code), I really don't understand how it's different. (Or maybe it uses a different compilation algorithm?)

I accept that I could be totally wrong, because my experience with the implementations is limited. Could you please elaborate?

Re:different alghoritms

salva on 2006-12-01T00:11:56

I guess it could also output Lisp that CMUCL could compile into native code

exactly, that's how it works!

In Lisp, you can extend the language using macros (functions that can manipulate the program structure at compile time) and writing a compiler is usually as simple as writing an interpreter.

In that case, a regular expresion is expanded into a chunk of Lisp code that gets inlined and compiled with the rest of the program.

Most Lisp hackers believe that macros are one of the most important features of the language, for instance, see this essay by Paul Graham.

Re:different alghoritms

DAxelrod on 2006-12-01T17:20:23

Aha. The more I thought about it, the more I thought this was probably the case.

If the regular expression is known at compile time, I could see how this would lead to big savings.

But what if the regular expression is not known until runtime? In that case, perl has to compile the regex and then interperet it while the program is running. Depending on how CMUCL implements eval, CL-PCRE would have to either: compile the regex into Lisp, then invoke CMUCL to compile into native code to be interpereted by the processor; OR do some sort of non-native interpretation anyway. I wonder if the double-compile is still a performance savings.

Re:different alghoritms

informatimago on 2007-02-20T22:28:19

The lisp compiler is available at run time.

It's true that EVAL may interpret (in implementations that have an interpreter), but if there is a compiler, you can call it and have the regular expressions compiled to native code at run time.

The question is whether the application will need to execute the run-time defined regular expression more than once, to amortize the cost of the compilation done at run-time, or whether the regular expression will be applied to a text big enough.

Re:different alghoritms

DAxelrod on 2006-12-01T17:41:36

though you can argue that writing portable compilers in C is almost imposible while in a high level lenguage like LISP it is trivial.

Anyway, I agree with you that C is not the fastest think anymore, I just didn't like the example!

Well, this is always the problem when making language comparisons. If we're just comparing compilers, then I agree that you'd want to compare performance of the exact same algorithm.

A programming language, however, influences greatly how the programmer expresses themselves. It feels natural to write Lisp that writes Lisp. Writing C that writes C is much more difficult (despite that both languages are self-hosting). To compre languages based on the lowest common demoninator seems to devalue some of the most important aspects of the languages.

Pointers considered important

Aristotle on 2006-12-03T06:35:01

Understanding pointers remains an important cornerstone of understanding how the machine works. They’re how you get any nontrivial work done on the machine level. You don’t want to use them in everyday programming, sure, but if you don’t understand pointers, you’re not going to understand why Perl’s data structures are as costly as they are, when you should worry about it and when not, why substr is not as cheap as you would instinctively imagine, etc pp. My knowledge of assembler has a direct (if generally faint) impact on how I write Perl.

Re:Pointers considered important

DAxelrod on 2006-12-03T20:28:07

My knowledge of assembler has a direct (if generally faint) impact on how I write Perl.

If anything, I think assembler helped me understand pointers better than C, because of the way data is untyped.

The main reason I answered how I did was that "pointers" is really shorthand in C for a whole bunch of different concepts. Many of them you can learn in other languages. Some of them you can't.