I don't see why they don't just teach C, x86, and Haskell everywhere. If you know the concepts behind these, you can quickly grok any other programming language. Also I never got the whole hype behind OOP. IMHO its self explanatory, nothing you need an entire course on to be effective and understand OOP programs. Memory layout and management, advanced pointer concepts and monads are a slightly different matter.
If I had to teach someone OOP I'd say, OOP is like the real world if it were made of puppets and every puppet could pull another puppets strings, pull a string and a dog barks and wags its tail causing a cat to meow, the key is just not tangling up your strings.
I really don't understand why people have such issues with monads. I don't have a haskell background and originally built up most of my functional programming skill in Python (going somewhat against the grain) and I find monads to be a fancy scary term for an extremely simple concept. I think if they were named something friendlier perhaps people's eyes wouldn't immediately glaze over and they could realise that, actually, monads are just a simple strategy for controlling how things are executed/computed. Computational or execution strategies, if you will. Lets just call them strategies and see if they are less confusing and scary?
In that sense imperative programming is equally hyped. It too is like the real world, first you do this then you do that. Similarly there is nothing fancy about functional programming since algebra and calculus already introduce the ideas of composing smaller things to get bigger things.
What I'm getting at is that computation exists on several planes of abstraction and maybe covering C, x86, and Haskell might give you a good overview it will still leave things hidden because there is also Prolog and the branch of computation that Prolog leads to. Most schools settle for teaching their students the theory and some marketable skills by sticking to well-known languages like Java and Python.
> If you know the concepts behind these, you can quickly grok any other programming language.
"Grokking" a programming languages is just a means to an end, and far from being the most important means (well, for interesting problems, at least). Most (though not all) of important concepts in CS have absolutely nothing to do with the choice of language.
At my university they taught Scheme (SICP) in Intro to Comp Sci, and C -- both in the first year -- and all the rest was just data structures, algorithms, computational complexity, operating systems, numerical algebra, compilation, and electives in vision/graphics/PLs/DSP/whatever. We could do the exercises in whatever language we chose (usually C). In short they taught us just theory and one practical PL (maybe Java, too, for concurrency problems) so that we could actually do the exercises, and boy did we have a lot of good programmers who came out of that school. I owe to my university the realization that the programming language is one of the least important things in CS and software engineering.
I'm not sure pointer concepts are very difficult, pointers might confuse people that didn't grow up with assembly language, but they really aren't very hard to understand and they are also less and less relevant. Over the years the abstraction level increases, it's far better to teach people to continue computer science to the next 21st century level, not go over stuff from the 70's again that they will likely never use. The breakthroughs in CS coming very likely won't be written in C (or assembly for that matter).
Add a Lisp or Scheme dialect to your list and I'm sold. Homoiconicity, macros, s-expressions and such are too powerful and novel not to cover in a college CS curriculum.
The problem is, people finish their CS study, and do not have such level of knowledge that they could start working right away. So Haskell might be nice, but is hardly a sought for skill. Sure if students would learn different stuff by themselves, they could learn useful skills too, but most of the students are lazy, and only learn what they have to.
It's overall badly (at least foggily) written, but I find this quote really on point:
>The moral of the story is clear: real programmers don't reason about their programs, for reasoning isn't macho. They rather get their substitute for intellectual satisfaction from not quite understanding what they are doing in their daring irresponsibility and from the subsequent excitement of chasing the bugs they should not have introduced in the first place.
And that, ladies and gentlemen, is why I think people think C/C++ is an acceptable tool for anything besides drivers and kernels, for which they're only acceptable because there's no better alternative. Sure, pointer-pointers is a magnificent idea! I'll totally keep that under control!
People who can use C++ need to reason about their programs because otherwise they're going to shoot their foot off. You can be irresponsible in a language like python and get away with it because you're not going to cause the issues you would in C++.
I think that, to some extent, this is true. If you don't know what you're doing I find it's easier to code yourself into a corner in C++ than something like python.
I've never formally studied CS, but I can definitely see the benefit. I can divide my own (amateur) programming experience into pre-Haskell and post-Haskell. Before I started learning Haskell, I thought I knew how to use a good half a dozen or more programming languages. After I started learning Haskell, I realised I'd really only known how to use one all along, and that they were all fundamentally the same. I wish I'd had the experience sooner (plus, learning Haskell is just plain fun).
If you liked the "I'd really only known how to use one" type of experience, then I encourage you to keep learning languages after you are happy with where you are with Haskell. My experience is that languages stop feeling like cohesive entities and start feeling like a collection of features.
The nontraditional categories I've encountered are something like:
The macro facilities in lisp, scheme, forth (or factor), template haskell, and C++ templates.
Array languages like APL, K, or R.
Prototype inheritance with smalltalk or Lua.
Avoiding side effects with Haskell, Ocaml, or C#'s linq.
The "we're serious about type theory" languages like Haskell, coq, agda, and idris.
As much as I love Haskell, one problem with the intro to CS courses is that many of the students are not CS majors, but students from other disciplines that need to learn a little bit of programming. It makes sense here to teach Java and Python, as imperative languages are more useful to real world programming than functional languages.
Perhaps it would be better to create a separate intro course for CS majors. On the other hand, most curriculum in CS demand that students learn about languages like prolog and Haskell, so it's not like students will never be exposed to it.
At my university, pragmatic programming courses were part of the math department. If students want to learn to program, perhaps they should take programming courses rather than CS courses, instead of compromising the education of full-time CS students. The courses do have to be available though, and not all universities provide them unfortunately.
My alma mater is having this fight between the CS departments and engineering/physics/etc. The CS department switched the first two courses of the intro sequence from C/Java to Scala, moving C to later in the curriculum. Instead of C/Java/C++ in the first three semesters, it's now Scala/Scala/C++.
The department only has 7 professors and is struggling to even offer enough intro classes for their own majors, much less for students in other majors who only need a single CS credit. The engineering department is upset because they want their students to learn C. Physics wants them to know something else, the business department wants them exposed to a tiny bit of Java and so on.
When I started in 2008, there were about 30 freshman taking CS1. Now it's >150 last I heard. They really had no choice but to (diplomatically) tell the other departments to go pound sand. They can't compromise their own majors in favor of those from another department.
My guess is they aren't the only CS department facing this problem.
To followup with a note from the article: "A very practical reason for preferring functional programming in a freshman course is that most students already have a certain familiarity with imperative programming. Facing them with the novelty of functional programming immediately drives home the message that there is more to programming than they thought."
It's no surprise that this attitude can discourage students without programming experience... A parallel intro track seems like a nice solution that has worked in a number of schools.
I've always dreamed of building a programmable calculator that runs a lightweight Python (or Haskell) interpreter to replace all that obsolete TI crap that most schools use. I would have loved that kind of thing as a kid.
FWIW, UC Berkeley's intro CS course sequence goes through the following languages in order: [Scratch (in an optional gentle-intro CS course)], Python (with an emphasis on using it for functional programming), a tiny bit of Scheme, a tiny bit of SQL (before they used a toy logic programming language), Java, C, MIPS assembly. I think this walks down the ladder of abstraction very nicely.
Odd to use Python as your intro to functional programming, since it lacks many functional programming features besides lambdas which the language creator doesn't even like (http://www.artima.com/weblogs/viewpost.jsp?thread=98196)
I'm actually somewhat sad that they added the two in front of Scheme. I took an intro to CS course there the summer before heading to college and it was taught in Scheme. The teacher literally taught us the language the first day and then, from there on out, it was learning different techniques through mostly computer labs. Prior to that, my only programming experience had been in TI-Basic, so it was an eye-opening experience to realize that programming was more than just an ordered set of instructions. If I hadn't had that experience, I think I might have learned the wrong lesson when my college CS courses dumped C on me.
I'm not sure about Haskell as a beginner's language, but I consider Scheme to be almost ideal for that purpose since it's so easily digestible.
I particularly like that they walk the ladder of abstraction downwards, not upwards. I'm not totally convinced, but I have a strong hunch that walking down that ladder is more pedagogical than walking up. At least in math I have a much easier time reading the proof if I know what it's trying to prove beforehand.
I was attending UT during this time period, but luckily it took until my senior year before the Java-fication of nearly every class was complete.
My intro class used Dr. Scheme, and I think it worked very well for introducing new concepts. Following classes were mostly C++ with some C and assembly mixed in. When they finally introduced Java it took students a couple days learn it since they all had decent C++ backgrounds from previous classes. I don't think that would work in reverse, a Java background is not going to let you pick up C++ in a couple days. That is what the department did not understand, not knowing Java isn't that much of a determent to getting an entry level Java job. With a solid foundation, a junior programmer can pick up Java quite fast.
Indeed, my first CS class in 1999 at UT was in Haskell. Wow! What a change it was from high school AP Computer Science in Texas, which was (in those days) C++.
Seeing QuickSort in just one line was what hit it home.
I remember thinking at the time that this was really incredible, but that Haskell had no future. This was at the time of Hugs 98, although I remember hearing about GHC. I'm glad to be wrong about this.
Hold on: does Haskell allow "the" QuickSort on one line, or just a sort? Because from what I've read, if you want to make Haskell do all the efficient stuff in a QS, you have to tell it a lot more, bloating the program.
Dijkstra's advocating a Sapir–Whorf[1] of programming languages, which I long suspected to be true; but haven't been able to rigorously prove or disprove.
My main problem with teaching CS courses in Java was that it produces folks who have no clue about pointers or memory management in general. This however applies to Python and Haskell as well. I personally had a strange mix of Java, x86 assembly and Ruby in my curriculum.
That's like saying "The problem with teaching people how to drive cars is that at the end, they don't know how to ride motorcycles".
There are plenty of other classes at the grad and undergrad level that teach you about lower level concepts such as pointers and memory (system, C, OS, ...). The Java classes teach different concepts.
Dijsktra isn't suggesting that the entire computer science curriculum be taught in Haskell. That would be impossible. He's saying only that the introductory course in programming paradigms be taught in Haskell. Haskell and Scheme are well-suited to such a course.
A classic curriculum in functional programming, which goes back as far as SICP and is continued in modern books such as PLAI, is to build an interpreter for a programming language. This forces issues like memory management to be discussed.
I was lucky to get a mix of C, Java, and Haskell. Unfortunately (to my detriment) I totally ignored Haskell, and it didn't really click until I picked it up at the end of my degree out of curiosity- it really does help to clarify one's thinking.
I think teaching the motivation for learning it before beginning would have been better than just throwing it at freshmen, but I can't truly blame anyone other than myself.
I agree with him in the sense that these are CS courses, and in in such a way Haskell ties together well with the math that one learns in a CS program. Keeping that in mind it makes sense to only have taught Java in courses specifically designed for developing software.
I am looking forward to the day the notion that functional languages are not suitable for developing software will die.
It is not only that functional languages are more succinct, easier to reason about and are more readable, they also often come with significantly better type systems. Some have type systems sophisticated enough to specify nearly all the legal states and guarantee these are the only states the program can stay in at compile time. One can look at languages with dependent types for that.
On the more practical front, Erlang proved itself over three decades to be one of the best choices when it comes to fault-tolerant, highly concurrent systems. Jane Street is using OCaml for all of their trading software, Morgan Stanley has moved to Scala, and so on and so forth.
"A fundamental reason for the preference is that functional programs are much more readily appreciated as mathematical objects than imperative ones, so that you can teach what rigorous reasoning about programs amounts to. The additional advantage of functional programming with “lazy evaluation” is that it provides an environment that discourages operational reasoning."
Although I didn't do CS, but electrical engineering, I would have loved to get some more exposure to functional programming. We got Scheme which everybody hated because of the cumbersome bracket counting.
And of course we got C, Java, Matlab, and VHDL, besides a bunch of assembly. VHDL or Verilog would maybe also a nice eye opener for CS students. It's again another mindset.
While I wouldn't start with Java (it's not the simplest language about - I'd probably use C or Python) Dijkstra's anti-Java rant is over the top. It's still a huge language and that's NOT because of any corporate advertising campaign. Something that succeeds as well as Java has to have some actual value.
>Something that succeeds as well as Java has to have some actual value
Well yes, it has some value. However, just because a lot of people like/believe something doesn't make it good/true.
It's not like corporations have some vast conspiracy in place to encourage the use of Java; it's simply that Java, for a number of reasons, is attractive to middle-management types, even though it's not the best language to make good software. That's not necessarily a criticism of Java; from many perspectives, making good software is not the primary goal.
Dijkstra's big thing was prioritizing good software over cheap software. This may not be a realistic goal, but it certainly explains why he preferred Haskell to Java.
He wrote some really good essays on why you need languages like Haskell to raise the overall quality of software floating about. The more you can shift the burden of guaranteeing correctness away from humans and towards infallible mechanical systems (like Haskell's relatively powerful type system), the more likely you are to end up with good/correct software.
[+] [-] jfaucett|11 years ago|reply
If I had to teach someone OOP I'd say, OOP is like the real world if it were made of puppets and every puppet could pull another puppets strings, pull a string and a dog barks and wags its tail causing a cat to meow, the key is just not tangling up your strings.
[+] [-] dkersten|11 years ago|reply
I really don't understand why people have such issues with monads. I don't have a haskell background and originally built up most of my functional programming skill in Python (going somewhat against the grain) and I find monads to be a fancy scary term for an extremely simple concept. I think if they were named something friendlier perhaps people's eyes wouldn't immediately glaze over and they could realise that, actually, monads are just a simple strategy for controlling how things are executed/computed. Computational or execution strategies, if you will. Lets just call them strategies and see if they are less confusing and scary?
[+] [-] johnloeber|11 years ago|reply
The first class in the major is in Racket (Standard) or Haskell (Honors).
The second class in the major is in C, and also covers basic UNIX tools.
The third class is in x86 assembly and C, focused on understanding low-level systems.
[+] [-] dkarapetyan|11 years ago|reply
What I'm getting at is that computation exists on several planes of abstraction and maybe covering C, x86, and Haskell might give you a good overview it will still leave things hidden because there is also Prolog and the branch of computation that Prolog leads to. Most schools settle for teaching their students the theory and some marketable skills by sticking to well-known languages like Java and Python.
[+] [-] pron|11 years ago|reply
"Grokking" a programming languages is just a means to an end, and far from being the most important means (well, for interesting problems, at least). Most (though not all) of important concepts in CS have absolutely nothing to do with the choice of language.
At my university they taught Scheme (SICP) in Intro to Comp Sci, and C -- both in the first year -- and all the rest was just data structures, algorithms, computational complexity, operating systems, numerical algebra, compilation, and electives in vision/graphics/PLs/DSP/whatever. We could do the exercises in whatever language we chose (usually C). In short they taught us just theory and one practical PL (maybe Java, too, for concurrency problems) so that we could actually do the exercises, and boy did we have a lot of good programmers who came out of that school. I owe to my university the realization that the programming language is one of the least important things in CS and software engineering.
[+] [-] pjmlp|11 years ago|reply
On my university in Portugal back in the mid-90's, we had:
Pascal, C, C++, Caml Light, Smalltalk, Prolog, Java, PL/SQL, x86 and MIPS Assembly
Additionally we also got lots of CS stuff like lambda calculus, relational algebra, language semantics and so on.
It always feels strange so to me that there are universities out there focusing on single languages, or paradigms.
[+] [-] hnriot|11 years ago|reply
[+] [-] kyllo|11 years ago|reply
[+] [-] Arwill|11 years ago|reply
[+] [-] pacala|11 years ago|reply
It's really not much to it. Get value records right. Get method records right. Sadly, none of C, x86 or Haskell does this.
[+] [-] fishnchips|11 years ago|reply
[+] [-] tormeh|11 years ago|reply
It's overall badly (at least foggily) written, but I find this quote really on point:
>The moral of the story is clear: real programmers don't reason about their programs, for reasoning isn't macho. They rather get their substitute for intellectual satisfaction from not quite understanding what they are doing in their daring irresponsibility and from the subsequent excitement of chasing the bugs they should not have introduced in the first place.
And that, ladies and gentlemen, is why I think people think C/C++ is an acceptable tool for anything besides drivers and kernels, for which they're only acceptable because there's no better alternative. Sure, pointer-pointers is a magnificent idea! I'll totally keep that under control!
[+] [-] sbov|11 years ago|reply
People who can use C++ need to reason about their programs because otherwise they're going to shoot their foot off. You can be irresponsible in a language like python and get away with it because you're not going to cause the issues you would in C++.
I think that, to some extent, this is true. If you don't know what you're doing I find it's easier to code yourself into a corner in C++ than something like python.
(Disclaimer: I haven't used C++ in a decade)
[+] [-] Osmium|11 years ago|reply
[+] [-] Verdex|11 years ago|reply
The nontraditional categories I've encountered are something like:
The macro facilities in lisp, scheme, forth (or factor), template haskell, and C++ templates.
Array languages like APL, K, or R.
Prototype inheritance with smalltalk or Lua.
Avoiding side effects with Haskell, Ocaml, or C#'s linq.
The "we're serious about type theory" languages like Haskell, coq, agda, and idris.
[+] [-] navait|11 years ago|reply
Perhaps it would be better to create a separate intro course for CS majors. On the other hand, most curriculum in CS demand that students learn about languages like prolog and Haskell, so it's not like students will never be exposed to it.
[+] [-] colordrops|11 years ago|reply
[+] [-] saryant|11 years ago|reply
The department only has 7 professors and is struggling to even offer enough intro classes for their own majors, much less for students in other majors who only need a single CS credit. The engineering department is upset because they want their students to learn C. Physics wants them to know something else, the business department wants them exposed to a tiny bit of Java and so on.
When I started in 2008, there were about 30 freshman taking CS1. Now it's >150 last I heard. They really had no choice but to (diplomatically) tell the other departments to go pound sand. They can't compromise their own majors in favor of those from another department.
My guess is they aren't the only CS department facing this problem.
[+] [-] cafebeen|11 years ago|reply
It's no surprise that this attitude can discourage students without programming experience... A parallel intro track seems like a nice solution that has worked in a number of schools.
[+] [-] Retra|11 years ago|reply
[+] [-] brianchu|11 years ago|reply
[+] [-] cheepin|11 years ago|reply
[+] [-] curun1r|11 years ago|reply
I'm not sure about Haskell as a beginner's language, but I consider Scheme to be almost ideal for that purpose since it's so easily digestible.
[+] [-] tormeh|11 years ago|reply
[+] [-] megaman821|11 years ago|reply
My intro class used Dr. Scheme, and I think it worked very well for introducing new concepts. Following classes were mostly C++ with some C and assembly mixed in. When they finally introduced Java it took students a couple days learn it since they all had decent C++ backgrounds from previous classes. I don't think that would work in reverse, a Java background is not going to let you pick up C++ in a couple days. That is what the department did not understand, not knowing Java isn't that much of a determent to getting an entry level Java job. With a solid foundation, a junior programmer can pick up Java quite fast.
[+] [-] acallan|11 years ago|reply
Seeing QuickSort in just one line was what hit it home.
I remember thinking at the time that this was really incredible, but that Haskell had no future. This was at the time of Hugs 98, although I remember hearing about GHC. I'm glad to be wrong about this.
[+] [-] SilasX|11 years ago|reply
Edit: this is what I had in mind: http://augustss.blogspot.com/2007/08/quicksort-in-haskell-qu...
Btw, I took AP Compsci with C++ in Austin around that time, so we might know each other.
[+] [-] klutometis|11 years ago|reply
[1] http://en.wikipedia.org/wiki/Linguistic_relativity
[+] [-] fishnchips|11 years ago|reply
[+] [-] zak_mc_kracken|11 years ago|reply
There are plenty of other classes at the grad and undergrad level that teach you about lower level concepts such as pointers and memory (system, C, OS, ...). The Java classes teach different concepts.
[+] [-] lern_too_spel|11 years ago|reply
[+] [-] noelwelsh|11 years ago|reply
[+] [-] mp8|11 years ago|reply
I think teaching the motivation for learning it before beginning would have been better than just throwing it at freshmen, but I can't truly blame anyone other than myself.
[+] [-] Gyonka|11 years ago|reply
[+] [-] mathetic|11 years ago|reply
It is not only that functional languages are more succinct, easier to reason about and are more readable, they also often come with significantly better type systems. Some have type systems sophisticated enough to specify nearly all the legal states and guarantee these are the only states the program can stay in at compile time. One can look at languages with dependent types for that.
On the more practical front, Erlang proved itself over three decades to be one of the best choices when it comes to fault-tolerant, highly concurrent systems. Jane Street is using OCaml for all of their trading software, Morgan Stanley has moved to Scala, and so on and so forth.
[+] [-] LukeHoersten|11 years ago|reply
"A fundamental reason for the preference is that functional programs are much more readily appreciated as mathematical objects than imperative ones, so that you can teach what rigorous reasoning about programs amounts to. The additional advantage of functional programming with “lazy evaluation” is that it provides an environment that discourages operational reasoning."
[+] [-] MrQuincle|11 years ago|reply
And of course we got C, Java, Matlab, and VHDL, besides a bunch of assembly. VHDL or Verilog would maybe also a nice eye opener for CS students. It's again another mindset.
[+] [-] codygman|11 years ago|reply
[+] [-] peterashford|11 years ago|reply
[+] [-] wyager|11 years ago|reply
Well yes, it has some value. However, just because a lot of people like/believe something doesn't make it good/true.
It's not like corporations have some vast conspiracy in place to encourage the use of Java; it's simply that Java, for a number of reasons, is attractive to middle-management types, even though it's not the best language to make good software. That's not necessarily a criticism of Java; from many perspectives, making good software is not the primary goal.
Dijkstra's big thing was prioritizing good software over cheap software. This may not be a realistic goal, but it certainly explains why he preferred Haskell to Java.
He wrote some really good essays on why you need languages like Haskell to raise the overall quality of software floating about. The more you can shift the burden of guaranteeing correctness away from humans and towards infallible mechanical systems (like Haskell's relatively powerful type system), the more likely you are to end up with good/correct software.
[+] [-] forkandwait|11 years ago|reply
Like cigarettes?
[+] [-] rdc12|11 years ago|reply
Sounds an awful lot like, the Bandwagon fallacy
[+] [-] unknown|11 years ago|reply
[deleted]
[+] [-] unknown|11 years ago|reply
[deleted]
[+] [-] unknown|11 years ago|reply
[deleted]
[+] [-] JSno|11 years ago|reply
[deleted]