62 comments

[ 3.1 ms ] story [ 144 ms ] thread
At least this way our secret weapons remain intact.
C (not C++) can be a secret weapon too, if it absolutely has to be as fast and efficient as possible.
At my university we still have Functional programming (Scheme/Lisp), but the message is "what C++ can compute, Scheme can compute, only a bit weird, e.g. tail recursive factorial".

We have an OOP "course" that teaches code like this

  class People
  {
    char* name;
  }
The course's mantra: OOP is syntax, syntax, syntax.

The Prolog course was even more weird - the message was "what Lisp can do with lists, Prolog can do too", but it was implicit because the Prolog course was before the Lisp one.

The electives were only marginally better, with Python being the stellar exception.

I had a similar experience, if I'm interpreting this correctly, in that my university was pretty focused on the theory. I had a lot of CS courses where we were programming in "pen and paper." When we did write code it was often Java, but you knew that any course you took the professor could swap in pretty much anything else. Depending on the AI professor, you'd work in Java or Scheme. Compilers class could be a C-like language targeting MIPS with the compiler written using C++ or it could be a Java-like language targeting the JVM with the compiler in Java (though I should say these "little languages" were probably very similar because they were a very small subset of their respective languages).

I think if you learn the fundamentals (and that often means having a good grasp on C) it shouldn't be too terrifying to pick up at decent grasp on lots of languages.

This is downright dumb considering the recent surge in Ruby and Javascript.

And please, please, no C++ unless you understand what you're doing.

However, I think nobody cares about this particular university anyway?

US News says georgia tech is the #4 engineering school in the US...
General engineering and computer science are separate rankings. For 2009, they are #6 in "Computer Engineering", behind MIT, Stanford, CMU, UC Berkeley, and UIUC. This is actually a substantial improvement from the 12th place that I remember. Maybe "industry orientation" improves your US News ranking :-/
I think that all comp sci students should begin by learning to become competent in C. Aside from having the widest support across platforms, and being syntactically similar to many other languages, it's the closest you can get to understanding how computers work at a low level without dropping into asm. Frankly, knowing these things will make you a better programmer.

That said there is definitely a benefit to exposing students to higher level languages, both for productivity in solving more complex problems and understanding what the syntax and expressions of these languages have to offer. And by higher language I don't mean C++ :)

Everyone says that C is as close as you can get to how computers work, but I can't agree with this anymore. C stack management and function calling requires work that is not part of a CPU. malloc and free do not map to anything at the hardware level, these are OS calls. The closest C gets you to the "computer" is pointer arithmetic and manual memory management. If you want to teach someone how basic hardware works, start with an arduino and assembly. If you want to learn how to program modern applications, use a modern language (Java, C#, JavaScript, python, ruby).

I think that people talk about C as an important language because it is difficult to write programs in. To these people it is a badge of honor to write clean, correct C code. Here's the rub: C absolutely sucks at networking, and concurrency, security and readability.

Every year that goes by, C becomes less useful. How is this a good language to teach students? (Edit: BTW, This is the Computer Science curriculum, which is separate from Computer Engineering. Georgia Tech's CS curriculum had no mandatory hands on hardware classes.)

>> C stack management and function calling requires work that is not part of a CPU

Well in C you tend not to manage the stack. As for function calls, what exactly do you think a CPU spends its time doing?

>> malloc and free do not map to anything at the hardware level, these are OS calls

So memory is just some non-physical property of the OS? Erm...

>> I think that people talk about C as an important language because it is difficult to write programs in.

There is a learning curve, but it's hardly difficult. However I think I know the reason for your confusing statements above.

I'm afraid you misinterpreted the parent. The parent is saying that C's function calls and stack management are not implemented in hardware. That there is, in effect, a C 'runtime' that implemented these behaviors. Further, malloc and free are not hardware calls. The physical property would be literal ram addresses (not virtual memory, though there is now hardware virtual memory so i digress.)
> it's the closest you can get to understanding how computers work at a low level without dropping into asm.

Though your points are pretty valid, the parent wasn't arguing that C was at the lowest level.

Plus surely you can provide your own low level implementation of malloc and free for the platform and you'll still be programming C.

(comment deleted)
I believe the choice of C isn't really about "how computers work" as much as "how algorithms work", with C only providing a minimal toolkit of architecture-independent efficient high-level functions that allow for a simple mental model of how algorithms in higher-level languages work underneath, which is extremely useful in the real-world for getting a good overview of algorithm efficiency.

Another good reason is that C is useful as a sort of mid-level psuedocode. This pseudocode is useful for providing a mental model that allows you to make the leap from a modern high-level language to C to an assembly language much more easily than making the straight cognitive leap from a high-level language to the specifics of an assembly language or architecture.

I think that any programmer worth their weight must disagree with the larger message you're giving here.

C does _not_ suck at networking, concurrency, security, or readability.

Most code you write in a 'modern language' like Java, Python, or something similar, is implemented on a very low level in C. So those nice, clean, safe networking functions Python pulls out of nowhere are just well written C code being presented to the user through layers of abstractions. The same goes with modern type-safety and security (that 'proofed' kernel from a few days ago was Haskell mapped into C).

From a readability standpoint, C represents a tradeoff. The core C API can be kept in its entirety in a programmer's mind. Starting from scratch, you are able to know (essentially) every language feature C has, how to use it, and what side-effects it could cause. Compare this to Java, Python, or even C++, and you get into a scary world that's just too big to keep in mental RAM all at once - but a lot closer to english and more compact.

There was an article which came out a few days ago talking about how C has been and will continue to be the top choice for software over C++ _and_ assembly in embedded projects over the past 12-15 years. Given that embedded systems make up something like 98% of the computer market and the number of computers grow with each passing year, the argument should flow the opposite way:

Every year that goes by, C becomes more useful.

In addition, it's an ideal language for teaching the notion of pointers, the reasons for security, the value of good program structure, and yes, it's difficult. If you teach people to be comfortable dealing with C, they'll feel like Python is pie. (or.. py :P)

All that said, I cannot disagree with the value of functional, object oriented, or other paradigms being taught to students. Many people do not really learn to deal with recursion until they've learned a dialect of Lisp. Many people do not really learn the power of design patterns and the object model until they've written something in a high level language that uses it (take your pick).

The fact that these are good things to be exposed to and to use does not in any way diminish the importance or usefulness of C for both career programmers or computer scientists.

tl;dr: "C is still good too homg"

I took classes on C in school. I never really "got it." I then re-learned C after learning Python (and other higher level languages).

I found it much easier to learn on the second try. On the first try I was learning about syntax, functions, loops, variables, and types as well as memory management, header files, and pointers. On the second try I was only learning about memory management, header files, and pointers - I already knew about the other stuff. On top of that, pointers were much easier to grasp because I had experience with 'references' in higher level languages.

It's great to learn C, but I always recommend people learn to program by way of something like Python or Ruby. It's hard to beat print "hello" when you're just starting out.

(Almost) everything is easier to learn on the second try.

Also, keep in mind you learned Python after C, so your experience is not clearcut.

Except I never learned C the first time. That's the point.
So you did not learn it, but you were learning it. Maybe you could not write a good working program in C, but you became aware of a number of concepts that you could build on later when learning other languages and when learning C the second time.
> C does _not_ suck at networking, concurrency, security, or readability

Yes, it does. You will not find buffer overflows in JavaScript. You will not find threads in haskell. You will not see polling loops or select with switch dispatched networking code in Seaside. Your program will be easier to read in python or JavaScript (depending on your block syntax preference).

You say that C doesn't suck at these things, but it is more realistic to say that it is possible for these things to be done correctly in C. It is more likely that they will be done incorrectly in C than in other languages. Maybe the result will be slower, maybe it won't run on your watch, but correctness is more important than speed. Speed (of instruction) is easy to fix - just wait a year. Better to get your program correct and your algorithms efficient than to waste your time on speed.

> The core C API can be kept in its entirety in a programmer's mind

I'm not sure what that means, and I'm fairly certain that you aren't taking into account the complexities of modern compiler runtimes and CPU instruction reordering. If you think that the assembly output and runtime characteristics of C programs are simple, you haven't looked recently. More practically, I can keep as much of the python "API" in my mind as I generally use. Do you include common libraries in your definition of "API"?

> Given that embedded systems make up something like 98%

Well thats a useless statistic (and I hear that 90% of statistics are made up on the spot). Are you suggesting that 98% of programming jobs are for embedded systems?

> Every year that goes by, C becomes more useful.

That must be why the number of C books decreases every year, and why new app platforms use python and Java. C is a really easy language to port to new hardware. It runs in very constrained environments, like tiny embedded systems. It is a generally useful language to know as a computer science major. It is a common language because worse is better, but when it comes to laying the groundwork for your programming career, better is actually better. Practice doesn't make perfect, perfect practice makes perfect.

> If you teach people to be comfortable dealing with C, they'll feel like Python is pie

No they won't, they'll think that Python is C with garbage collection and no curly braces. People who learn C first write programs that look like C no matter what language they're using.

I'm not purposely trolling here, it is my opinion that C is a poor language to teach students. If you find Lisp and Smalltalk to be too removed from industry, lets use python.

> I'm not purposely trolling here, it is my opinion that C is a poor language to teach students.

If you don't teach students C, you're denying them a deep understanding of how all of the higher levels are implemented.

If all you know is Python but I know Python, C, UNIX system calls, and even assembly, I'm going to run circles around you, even if we're both working 100% in Python.

For example, suppose your Python program says "import foo", but it's not finding module "foo". How can you debug what is happening? I'm going to take two seconds and run strace on the program to see what files the process is trying to open. You're going to... read some docs? Post a question on a message board?

Or suppose that your Python program tries to do an open("foobar", "w") but the open fails with:

   IOError: [Errno 26] Text file busy: 'test'
I'm going to look at the manpage for open(2) to figure out what this error means. You're going to... go ask somebody who understands system software?

People who don't understand system software are totally helpless compared to people who do. You may see C fading into history. What I see is every single relevant technological innovation -- 2nd-gen JavaScript interpreters, Flash, the JVM, .NET, browsers, OS's -- ALL using C or C++.

I would challenge you to look around and find ANY stack of software that doesn't have C or C++ in it. It's just a matter of how deep you have to go to find it. Are you saying that we shouldn't equip students to deal with layers of software that deep? Are you saying we shouldn't equip them to understand things like trace compiling, which are the state of the art in language design and implementation?

Sure, if all you want to do is web development, you can probably go a long ways without understanding system software. But you'll always be dependent on the people who understand the stack up and down.

> I'm going to take two seconds and run strace on the program ... > I'm going to look at the manpage for open

Those are some silly arguments for teaching C. Someone with no understanding of C can just as easily read man pages. While it is useful to know C and assembly for debugging system calls via a debugger, this is rare compared to debugging via reading the documentation. Plenty of people wrote C based applications for the original Macintosh, even though the operating system was originally written in Pascal.

> I would challenge you to look around and find ANY stack of software that doesn't have C or C++ in it. It's just a matter of how deep you have to go to find it.

Thats a common, but baseless argument for knowing C. Most stacks are indeed written in C, but this is because most operating system interfaces are written in C, and C compilers are widely available and easy to write. Many efficient VM's have a minimal base written in C and transition to their own language early on. Amusingly, the Squeak VM from the original article is one of these.

> Are you saying we shouldn't equip them to understand things like trace compiling, which are the state of the art in language design and implementation?

Only students who specialize in compilers or virtual machines are going to dig that deep ... but what does that have to do with C?

> Sure, if all you want to do is web development, you can probably go a long ways without understanding system software. But you'll always be dependent on the people who understand the stack up and down.

That raises a good point - stop reading the web and get out there and till those fields, or you'll always be dependent on others for your basic needs. While you're out there, we'll debate the finer points of a specialized society.

I'll just point out that hardware and operating systems are useless without higher level applications. Those writing them are actually always dependent on others to make the combination do something useful.

> Someone with no understanding of C can just as easily read man pages.

If all you know is Python, or Java, or another high level language, how would you even know that manpages that document system calls exist? How would you interpret the C function prototypes that are written there? How would you determine how high-level language constructs map to system calls? In my example, you got lucky because the open() function in Python calls the open() system call, but this is not universally true.

> Thats a common, but baseless argument for knowing C. Most stacks are indeed written in C, but this is because most operating system interfaces are written in C, and C compilers are widely available and easy to write.

So you acknowledge:

  - most software stacks are written in C
  - most operating system interfaces are written in C
  - C compilers are ubiquitous
...but also argue that we shouldn't teach students C? Are you arguing that it's not important for students to understand the system software that we both agree exists and is ubiquitous?

> That raises a good point - stop reading the web and get out there and till those fields, or you'll always be dependent on others for your basic needs.

Maybe you enjoy analogies, but I have direct experience in professional settings where I was able to use my knowledge of system-level software to solve problems that stumped people without this deep knowledge.

Maybe the most relevant example was at a web startup I worked at two years ago. Note that I was working on a website at the application level -- not writing system software. I had to solve several problems like this one:

http://dev.rubyonrails.org/ticket/8704

Solving this problem required repeatedly digging down into the Ruby interpreter, C extensions, system calls, signals, etc. Note that this was in my job as a webdev. Being able to solve problems like this made me stand out among my peers (who were also good developers, but didn't have as much systems experience as I did).

All I can hear you saying is that you don't think students should learn C because you personally don't like it. That's fine, but I am presenting evidence that it will make you a significantly better programmer. Don't tell aspiring programmers that knowing C won't help them, because it's simply not true.

I think that you've misinterpreted my original comment. My argument is that C is a poor language for teaching computing theory. There will be classes where students will learn C, certainly any hardware oriented class. The question at hand is, "Do students benefit from learning concepts in languages other than C", and I think that you'll agree the answer is "yes".
Your initial claims were much broader than that ("I think that people talk about C as an important language because it is difficult to write programs in.", "Every year that goes by, C becomes less useful. How is this a good language to teach students?"), but let's go with your current claim.

Part of me sees the benefits of teaching computational complexity using a high-level language like Python. But part of me still can't buy into it, because what is the computational complexity of this excerpt of Python, in terms of n?

  strings = ["X"] * n
  concatenated = ""
  for s in strings:
    concatenated += s
The answer is that it depends on the implementation of Python!
Well yeah, and the computational complexity of a program which calls a function in the C standard library depends on the implementation of C.
You don't need the C standard library to write algorithms in C. Therefore you can do computational complexity analysis that is independent of the C language implementation.

(I don't actually think you could name a function from the ISO C standard library that differs in complexity across implementations, but it's besides the point).

You don't need malloc, then? Please explain.
If you're analyzing complexity and your algorithm needs malloc(), then you implement and analyze malloc(). For example, see Knuth section 2.5.

By the way, do you have a point to make, or do you just enjoy being brusque?

I don't understand you here. If you write an algorithm in C that uses malloc, it will perform differently on different C implementations. This is exactly parallel to the fashion in which your python program will perform differently on different python implementations.
An OS call is a lot closer to "the way computers work" than a call to a managed runtime environment on a virtual machine running on top of the OS.
Err malloc, free, pthreads are all abstractions and are not black box generally. You can look in them and find out what the hell is going on if you need to.

C is great at networking (sockets), concurrency (pthreads), security (brain) and readability (brain). If you know what you are doing. The same is true with any language. You can write shitty C# and JavaScript.

Our intro to computing class involves learning about gates, an academic architecture (LC-3), programming in bytecode, programming in assembler, learning how we assemble the bytecode into assembler, then learning C. Our final project is a basic compiler from C to ASM given an AST.

I think it's a great way to learn about the way a machine works in one semester :)

This sounds great, you learn how a machine could be programmable, and how existing programmable machines operate; but the question mostly under dispute here is whether C brings out the nature of 'programmability' -- i.e. whether it brings out very clearly the purpose that all these strata serve, namely general programmability. --And thus whether a C-only environment is missing something essential. Myself I would think it does, and that for example Lisp and Haskell and ML help bring this out more clearly, and so, in another way, do the happening scripting languages. Your experience with with assembler seems to me more important than experience with C -- though of course everyone has to learn C. In my own case, for what it's worth -- I wouldn't think everyone else would need this -- it's only when I saw that a properly assemble machine could compile Haskell that I really grew to respect the machine...
Smalltalk may be dead but there are millions of smartphones using Objective C which is in many ways a direct descendant.
(comment deleted)
Saying Smalltalk and C... Oh boy.. That's the danger of the beer goggles.
The College of Computing has been alienating their more academic members in favor of "industry" orientation. I suspect that this comes from trying to increase funding, but more simply it is indicative that those making the decisions no longer have a clear vision of what they are teaching students. It isn't enough to say that they are showing preference to C based languages, as one of the primary "weeder" courses which was taught in C was discontinued years ago.

I don't know if this uncertainty and doubt of academic computer science is limited to Georgia Tech. Just recently, MIT dropped their scheme course for one in python, with the goal of being more "practical". Is it better for undergraduate computer science to be practical or academic? I will suggest that if students don't learn abstract computing when they are undergrads, they are never going to.

To be fair, when 2130 (along with the ECE2030 requirement) was cut they replaced it with 2110 and 3240. As I understand it (I tested for standing, so I can't claim first-hand knowledge), 2110 does a very good job of combining the relevant parts of ECE2030 and the C bits of CS2130. That, to me, makes it a solid replacement for those concepts.

The first time 3240 was taught, Olin was the professor teaching it. It covered a fair chunk of the material you'd expect to see in CS4510 that semester while also being an excellent class on lexers, parsers, and interpreters (not so much on compilers, but of course it's not a compilers course). I can comfortably say that it was by far the most interesting and educational course I took during my undergrad career. Since Olin's unfortunate departure, 3240 has apparently turned into just another lexer and parser course.

On the whole I'd say the changes they made w.r.t. CS2130 were good. However...

Threads has made it so that you can get a CS degree without taking an algorithms or data structures course above the 1000 level, which I find wholly disappointing. It's not that the degrees these students are walking away with aren't perfectly valid things to have degrees in, but I have a hard time calling a lot of these undergrads "computer scientists".

</rant>

I agree entirely with this. I am not intending to start a flame war here, but this is how I see it:

My rationale is that C/C++-based software powers nearly of all computer CPU cycles these days either directly or indirectly.

From mobile phones to massive distributed systems like Google, it's there. It's probably even there in your fridge or smoke alarm these days albeit somewhat feature constrained.

For the Ruby, PHP and Python users, most of your language is written in C!

The .Net framework is mostly C/C++ underneath (Google for shared source CLI). Even the C# compiler is written in C++.

Java is mostly written in C as well.

The iPod software is written in C (not it's not objective-C - check out the About/Legal section for the libraries it uses).

Objective-C even started as a load of C preprocessor macros.

Ultimately, C/C++ is the foundation of the most software in frequent use, the Internet and our society. That's why they should teach it over Lisp/Scheme/Smalltalk/etc etc.

Oh and possibly just as importantly, it works.

> Objective-C even started as a load of C preprocessor macros.

So did C++, IIRC.

{edit} To add a bit more than a one-line comment, it seems to me that the gist of the article was that young programmers should be exposed to a wide variety of different programming paradigms. (i.e. functional languages, procedural languages, etc) Teaching only C and C-like languages is encouraging a monoculture. It doesn't matter whether or not they will use Lisp or SmallTalk in the real world. The idea is for them to come away with ideas and concepts they would not have been exposed to otherwise. I mean this is a university and not a vocational school. I would expect university students to be exposed to more ideas (even if they are ideas that never get commonly applied in the real world) than someone coming out of a vocational school. {/edit}

The problem with a university education is that it is becoming less relevant. A formal education doesn't necessarily teach people to deliver software, which is critical for the captialist society we live in to operate.

A monoculture is seen to be negative due to this insane emphasis on diversity recently. Diversity generally hinders resource pooling which is what allows monumental things to be created.

For the record, I am a pure autodidact with no formal qualifications.

I'm not necessarily saying that people need to have a university education to be a productive member of the tech/developer community. But I believe that without a diversity of ideas, the tech community will languish.

Requiring a university education for everyone isn't necessarily the answer, but neither is diluting a university education by turning it into a vocational curriculum.

"For the Ruby, PHP and Python users, most of your language is written in C!"

Are you seriously trying to suggest that understanding the concepts behind C teach you the concepts behind how Ruby works, just because Ruby has a runtime written in C? If not, what are you getting at?

"That's why they should teach it over Lisp/Scheme/Smalltalk/etc etc."

Are you seriously trying to suggest that Computer Science students should learn only one language, or only closely related languages?

That is the part that bugs me. That GT is deciding that their Computer Science students are too dumb to learn more than one kind of language. I wish someone at that school had read Joel's rant about "Java schools."

> Are you seriously trying to suggest that understanding the concepts behind C teach you the concepts behind how Ruby works, just because Ruby has a runtime written in C?

That sounds reasonable to me...certainly not ripe for a "seriously?" label. Of course knowing C would help one to understand how Ruby, Python, etc. work, just like knowing assembler helps one to understand what C is doing. Rich languages like these don't just happen out of the blue.

You need to understand C to understand how Ruby works via observation. Observation and reverse-engineering visually is more important than you think. Understanding programs and being at one with them is the true path to enlightenment, not poking several different languages down your throat.

They should however understand theory and implementation separately. Implementation should be the most common form.

People forget that you need a job when you leave university.

> C/C++ is the foundation of the most software in frequent use, the Internet and our society. That's why they should teach it over Lisp/Scheme/Smalltalk/etc

But maybe this is like saying that the oppression of women is the foundation of our households, economy and our society. That's why they should teach it over justice/equality/common sense.

But maybe in school they should at least give one a glimpse of other possible utopias....

I fail to see how this analogy is valid.
Me neither. Sounds like words for the sake of words.
How is the choice of C/C++ a decision in favor of simplicity?
He references Richard Gabriel's "Worse Is Better", which compares the simplicity of implementation model (C/C++) with the simplicity/correctness of interface model (Lisp). C/C++ are "simple", ya know, kinda like Cletus from the Simpsons.

One could also generally argue that C is simple to use, as well. K&R is a tiny book, and it covers most of what you need to know to read C, and a good bit of what you need to know to write it (some of the ancillary tools, like cpp, make, libraries, etc. complexify things a bit, though).

C++, on the other hand, is a huge pile of interwoven concepts and is extremely complex, so I don't think it's polite to combine them in to C/C++, but I don't get to make that call.

CS departments are just less and less able to maintain illusions about what they really are -- trade schools for cranking out interchangeable corporate programmers. And there's nothing wrong with that. Honesty and unity of purpose are good things. Lisp and school never got along anyway. Lisp is for hacking. Its interests have moved elsewhere.
I took CS 2340 in Smalltalk a year ago at Georgia Tech. I think most people in the class disliked the IDE more than Smalltalk itself. Visual works was absolutely unusable on a mac and the Windows version certainly had its quirks. That, coupled with the fact that Smalltalk isn't used too often anymore led to students being really unsatisfied with the language.

I do think that the language needed to be changed for that class. The College of Computing is not entirely C though; I did learn lisp for an Artificial intelligence class, but not all students are required to take it.

> e.g., Lisp programmers are more productive and generate fewer bugs

Lisp programmers tell themselves they are more productive and generate fewer bugs.

You must not be familiar with this study.

http://www.flownet.com/gat/papers/lisp-java.pdf

A sample composed of volunteers from a particular usenet group doesn't seem like it would have people of equal skill in each of the languages in question, however. I'd expect that you'd get a different language winning in each newsgroup you sampled from.
Is that study a joke? Do you really take it seriously?
No, but when people bring up "C vs Lisp" or "Java vs Lisp" it comes up. I don't give it much due however.
One train of thought seems notably absent in this discussion:

The skill a good school attempts to teach has very little to do with any particular language. Instead they are seeking to teach you the one skill "to rule them all":

To learn how to learn, how to acquire new skills, how to analyze, how to synthesize and how to think systematically;

or said another way

the ability to identify and understand the problem space, to identify a tool that fits the problem well (even though you've perhaps never used it before), to acquire that tool quickly, and to wield it powerfully.

Consider that in your typical engineering degree, the half-life of your direct knowledge is but a few years -- half of what you "know" is obsolete within years. At the same time schools do want you to be "rapidly productive" in something that sees relatively wide use, or the job market gives them hell, and there just isn't enough time to cover all possible principles from all scenarios.

So they can but strive to stimulate your intellect and pique your curiosity so that you will naturally want to be aware of the possibilities and be open minded to all the various tools out there; and that you will have some framework available to you to understand what you will come across.