Lisp and Smalltalk are dead: It’s C all the way down
computinged.wordpress.com
computinged.wordpress.com
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++ :)
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.)
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.
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.
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.
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 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.
Also, keep in mind you learned Python after C, so your experience is not clearcut.
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.
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.
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.
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.
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!(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).
By the way, do you have a point to make, or do you just enjoy being brusque?
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.
I think it's a great way to learn about the way a machine works in one semester :)
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.
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>
(See, e.g., http://www.virtualschool.edu/objectivec/influenceOnJava.html )
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.
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.
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 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.
Lisp programmers tell themselves they are more productive and generate fewer bugs.
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.
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.
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}
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.
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.
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."
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.
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.
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....
And please, please, no C++ unless you understand what you're doing.
However, I think nobody cares about this particular university anyway?