This is one of a very very small number of programming-related articles I've ever been glad to read. Programming should be taught as an approach to problem-solving and structured logical thinking, not as an approach to a particular language.
If you can understand the core concepts of programming, the individual languages begin to matter a lot less. Python is great. Java is great. C++ is great. But they are just tools for solving classes of problems; if you don't understand how to, as the author says by way of example, deconstruct problems and understand the advantages and disadvantages of various solutions, then the software you write will never be as efficient or as elegant as it could be.
There is a compelling argument that, in the age of nearly limitless computing resources, it doesn't matter anyway. You will in all likelihood be a glue programmer: you'll rely on APIs and libraries, most of which have been written by someone else, and you will simply string them together by applying the functions that most obviously address whatever problem you're trying to solve. Who cares, really, if you're using Quicksort or heap sort, you're just going to call sort() on your array (or map, or key-value store, or whatever), and define a callback function that will evaluate any two given values in the array to be sorted, and that's it. Who cares if one requires a little more memory than the other, or a little more time to execute?
Just knock it out, and then get back to arguing online about the One True Language, or the One True Framework.
But, I've been programming for about 25 years now, in dozens of languages, and I can't help but feel that this language-specific approach to programming is producing anemic programmers.
Programming can be a craft; in can be done well, and elegantly. I can hack together a decent, reasonably strong wooden workbench for my shop, but it doesn't possess the same craftsmanship as a dedicated wood worker. It does the job, but it is ugly and uninspiring, and nobody admires it.
So, I guess I think that programming is similar, and moving from SICP to teaching Python or Java is just another representative sample of a disappointing sea change away from what I've come to know and love about programming.
It's not "what the school wants to teach" but more "what the student needs to know at the end of the semester". I love SICP -- for me it was a revelation which opened a new world, and is still my favorite book -- but not everyone is like that. 90% of my colleague in my university would hate that book.. (As they hated the dragon book and anything less practical). So, as they say, "Hate the game, not the gamers". What a school teaches is a reflexion of what is needed in the society and sadly what the students want.
I do hope however that great professors will still strongly suggest the book to students who want to go one step deeper.
p.s. A new version of SICP could include a couple of pages on python; i.e. make a list comprehension, yielding, etc. :)
There is a compelling argument that, in the age of nearly limitless computing resources, it doesn't matter anyway. You will in all likelihood be a glue programmer: you'll rely on APIs and libraries, most of which have been written by someone else, and you will simply string them together by applying the functions that most obviously address whatever problem you're trying to solve. Who cares, really, if you're using Quicksort or heap sort, you're just going to call sort() on your array (or map, or key-value store, or whatever), and define a callback function that will evaluate any two given values in the array to be sorted, and that's it. Who cares if one requires a little more memory than the other, or a little more time to execute?
I'd argue that such a programmer does not need a degree in computer science to do this work. How do I know? Because I don't have a degree in CS, and that's mostly what I do. And if I can sit down and learn, say, C# for a job, certainly someone that has come out of a good CS program can, too. A CS degree shouldn't be about learning a single language (or three).
I agree that a programmer doesn't need a degree in CS, but to have a CS degree doesn't mean you're a programmer. A topic earlier showed that 26 of the ACM Turing Award winners had degrees in mathematics, and a lot of the theoretical CS is math anyways.
If a student in college wants to acquire a CS degree, they should be exposed to fundamental ideas in CS, not just what they'll need to be a professional programmer.
This is really the root of the problem. Computer science/programming is immature as a profession. There are not clear, broadly accepted rules for what roles exist and what requirements there are for one to fill the role.
Looking at building houses (just the construction side, not the mechanical systems), we have:
- Architect
- Structural Engineer
- Architectural Technologist
- Carpenter
plus construction employees not officially certified.
Each of these has a specific test, both written and practical (apprenticeship), and specific roles in the building process.
In software, we have no standardized tests, so companies substitute "BSCS" for "Software Engineer" in the requirements. And there is only ever one role officially defined; there is no separate "Software Programmer". Internally every companies has "Software Engineer I", "Software Engineer II", etc however this is rarely exposed in job postings and requirements and is never standard between companies.
The software industry could solve all this hand-wringing by creating a set of standardized roles, testing to create Certificates of Qualification for each, and getting HR departments to require these. And it would be possible, even with an established industry. Canada has added several new Professionals over the last decade, working with the existing industry to define the job, requirements, and build a phase-in plan that allowed the industry to continue operating.
It's a specific field within mathematics, with its own emphases and body of knowledge, much like how podiatry is distinct from general human physiology.
Really, though, all mathematicians specialize once they reach a certain level, for the same reasons all physicians specialize. It's just that you only happen to know the name of one of those specialties.
So basically you and 90% of your colleagues hate computer science. You want a vocational education in software development, which is something different.
No, I said SICP was by far my favorite book. I already knew how to program before joining the university.. my goal there was to go deeper than what I already knew.
However, the big majority of my colleagues there didn't want that. They really enjoyed "Design patterns", "C++".. but hated anything potentially more abstract (Like compilers, Algorithm). Note that I'm talking about software engineering.. and not about computer science, which is really different imo (as engineer might have a more practical mind).
What does your comment have to do with what I wrote? No one is denying that many people really want a vocational education. No one is claiming that smart people should want to be academics. The point is that what people want is not computer science. Civil engineers do not enroll in physics programs and then complain that their physics professors are not teaching them anything about practical bridge construction.
If you make a degree a prerequisite to getting a specific job, or even a specific job at a specific (higher) pay scale, you always end up with people treating traditional four-year programs like trade schools. Especially if you also make people think of trade schools as where you go if you only barely passed high school, or if you failed high school and wound up with a GED. (And we could recurse and talk about how one-size-fits-all high schools aren't the only option, either, but we won't.)
Now you have four-year programs becoming the only option. This leads to a mix of philosophies, and by 'mix of philosophies' I mean 'raucous all-out war between two different groups punctuated by useless tracts calling for peace like this one.' The two different groups are the people who want to understand the theory at a respectable university level and the people who are on a fetch quest to get the paper to get the best ending (uh, job).
Neither group is wrong, but one group would be much better served by a non-stigmatized trade school system.
This fight invariably leads to the airing of two philosophies:
One, the student-as-customer philosophy, says that as long as tuition costs money the schools damned well better dance to the students' tune chop chop. They're more sympathetic than that once you realize how eager companies are to shitcan anyone who doesn't have enough letters after their name, which might actually be the real problem.
The other, the university-as-noble-institution philosophy, says that universities are places apart from the world where real research can be done and grants can be funded and, incidentally, there are these undergrad things running around that the exterminators refuse to extirpate so we might as well rope some researchers into making them the next generation of people educated enough to further our culture and, incidentally, keep our technical society from collapsing. In this model, the students don't get to influence pedagogy and coursework and so on because they, as per hypothesis, aren't educated enough to know what they want: If they were they could teach themselves and save everyone a lot of money.
Like I said, neither philosophy is wrong. It's just that one of them should be in a completely different set of institutions.
I wholeheartedly agree. The schooling system was set up more than 60 years ago. Any social system instituted by man is time limited. With time, people (because we're intelligent) try to maximize the benefits while minimizing the effort, and this compromises the system.
Sixty years ago, finishing high-school was a major accomplishment, opening lots of opportunities. One went to college because he/she wanted to learn stuff which will be useful on his/her voyage to the frontiers of human knowledge. Intellectual curiosity is the main motivating factor for this kind of people.
College education today assumes the same role that high-school education had 60 years ago, and it's NOT because there's more stuff that has to be learned. (I think 12 years of education is more than enough to keep the world spinning. We're just doing it wrong, but that's another story. Paul Lockheart's Mathematician's Lament is a great read on this subject, feel lucky on Google).
The question is, what will provide today what colleges provided 60 years ago?
I don't mean to sound catastrophic. Top-class research is being done today as well. It's just that we're making things unnecessarily hard for everybody.
"You will in all likelihood be a glue programmer: you'll rely on APIs and libraries, most of which have been written by someone else, and you will simply string them together by applying the functions that most obviously address whatever problem you're trying to solve."
If you come out of a curriculum where all you learn is how to string together APIs and libraries, it's pretty much guaranteed you will end up with a job doing that, because that's all you will be qualified for.
If you want a job where you are pushing the envelope of what's possible with computers, you're going to be much having taken SICP.
> If you come out of a curriculum where all you learn is how to string together APIs and libraries, it's pretty much guaranteed you will end up with a job doing that, because that's all you will be qualified for.
If all you learn is how to string together APIs and libraries, then it probably wasn't a "curriculum" at all. But emphasizing certain technology domains other than programming and computer science does have its advantages, especially for program meant for engineers more than computer scientists.
It's hard to argue against the merits of SICP and I'm not going to try, but if your goal is to produce engineers that push the envelope of next generation technology beyond just computers (eg robotics, optics, advanced human-computer interfaces, gene sequencers, advanced materials, etc.) then "stringing libraries and APIs" together might be more exciting than one might assume.
> if your goal is to produce engineers that push the envelope of next generation technology beyond just computers
Then computer science isn't where you belong. There is a solid argument for teaching everyone the basics of programming, and this is it. I can hammer a nail into a wall, too, but that doesn't make me a carpenter.
If computer science is all you want to study, then an engineering school might not be the best place for you. You're probably better off at a small liberal arts school. At Schools like MIT and Berkeley, computer science is an optional specialization in the EECS program. If you look at the MIT course maps for the three main degree paths (EE, EE+CS, and CS) you'll see that 6.01 and 6.02, the replacements for 6.001 (the SICP course) are foundational for all 3 specializations.
This is kind of sad, like an english department no longer teaching Shakespeare because it is written in archaic language and can't hold the student's interest. But computer science isn't like english, so I guess it is a bit of false analogy.
Fortunately the text and lectures are available for free online, so there is nothing to prevent the curious student from digging in.
edit: now that I've more time to reflect, I want to revise my thoughts...
I would be pretty pissed I was handed dive into python or something similar as my freshman programming text at a college like MIT or Berkley. I would hope that most CS majors wouldn't be going to into one of the top CS programs in the country cold, having never written a line of code. This is in no way meant to disparage Dive into Python or similar books, but it is something you can read on your own over the course of a week or two. If you aren't going into CS at a top uni to study the hard shit like SCIP, I don't really see the point.
This isn't a question of whether we should teach SICP, it's a question of whether it's an appropriate introduction.
I love SICP, I think it's one of the most brilliant didactic texts ever written, but I think it's a terrible starting point for most students.
To me it appears that SICP is used as a trial by ordeal, intended in large part to scare off 'unsuitable' candidates. SICP is all about the beauty and interest of computation for it's own sake, but it doesn't really engage with solving the kinds of problems most software is written for. I think we're inadvertently dissuading people who would make great programmers, but who see computer science as a means rather than an end and need to relate algorithms and data structures to practical problems.
There is clearly value in CS for its own sake and academics are obviously inclined towards this, but I think dismissing the practical application of CS is unhelpful. If we segregate programmers into 'Computer Scientists' and 'Software Engineers', we lose the most precious part - the bit in between, where radical ideas meet great engineering.
I want to see more diversity in computing and I think SICP as an introductory course is a serious hindrance to that aim. We don't teach children to read and write by starting with linguistic theory. I think we should teach software the same way - start with Dick and Jane and work our way up to lambda calculus.
I guess beauty is in the eye of the beholder. A simpler way to analyze this problem is noticing the f(n-3) term implies your function has to memorize up to 3 previous results. Then just use the coefficients from the formula to cycle the next result into memory. Using algebra and generating new coefficients as per the OP's solution is unnecessary.
function f(n)
if n<3 then return n end
local a, b, c = 0, 1, 2
for i=3,n do
a, b, c = b, c, c+2*b+3*a
end
return c
end
Nice! Also your solution makes it easy to move on to a logarithmic time solution: going from (a,b,c) to (b,c,3a+2b+c) is a linear transformation which can be expressed as a 3x3 matrix, therefore iterating it n times is equivalent to raising that matrix to the nth power, which can be done in log(n) time using square and multiply [1]. Disregard programming, study math!
In fact the exact same reasoning can be used to derive the closed form expression for the Fibonacci numbers [2], which are defined by a recurrence relation similar to the one in the OP. You raise the corresponding 2x2 matrix to the nth power by going to the eigenbasis where the matrix becomes diagonal, raising the values on the diagonal (which turn out to be the golden ratio (phi) and -1/phi) to the nth power, then changing the basis back.
Awesome! But actually I think my comment was inadvertently a bit more illuminating than the SICP exercise :-) Despite being on the web, SICP is a "traditional" textbook and doesn't bother to link to Wikipedia. Instead they use some sort of stone-age technology called "footnotes", stuffing all supplementary material right into the book as a couple lines of tiny text. So the student gets the feeling of following a twisty cluttered rabbit hole instead of exploring a new land.
Well, SICP was a printed book before being put on the web (as it is quite a few years older than it), and the version you see on the webpage is just a rendition of it in HTML. Still, I didn't know until today that you could link to individual figures and exercises, it will be even more fun to cite it in a quasi-religious, trollish way.
Also, you generalized the principle (and fused two exercises of the book in one :), or at least I'll have to believe you ;) I didn't form really much of an intuition on eigenvectors during the completely proper Linear Algebra course that I took, which is only my fault.
But I think that the exercise serves to reinforce the underlying theme that with enough attention, one can either supply or draw the insight to chip away yet one more part of the problem, to attack it from another angle, to pull it from just another direction that one had not seen before. It celebrates cleverness and knowledge, used to make complex things simple, to find the easy way out the hard way and end up better in the end, and that's partly why it's so cherished, but we all know that.
> Instead they use some sort of stone-age technology called "footnotes", stuffing all supplementary material right into the book as a couple lines of tiny text.
A bit OT.
I got tired of clicking on the footnote links, and click to come back to text, and wrote a little Greasemonkey script that shows the footnotes on mouse hover. Makes reading the text a bit easier.
Yeah, the rewriting goes a bit far for my taste as well... but it is a valid solution, and a purely functional one at that. Yours is valid as well, but introduces local state (which in this case probably doesn't matter, but it's worth noting nonetheless). You could write it this way in Scheme too, using a "let loop" for example, or even using a more imperative style.
That's definitely the standard way to solve it. He did something unnecessarily clever (and no faster). The tail-recursive version of your loop would look about the same structurally as his bizarre change-of-variables solution.
I think that starting with Python is a fine choice. Please keep in mind that it's just the introductory course-- these students are going to be battered with CS theory later on.
We are graduating around 20% fewer students in CS than we were in 2004. We need to find a way to make CS more accessible. I'm not saying that we should make the whole degree easier, but I think that having an easier & more practical first course would be good. The students might not learn as much theory, but they'll get the adrenaline rush of being able to code quickly and do some real damage with their code.
I think the more likely explanation is that a lot of people saw insane fortunes being made from computer science in the dot-com boom and went and got their degrees, hoping to cash in as well. In the subsequent bust, the party was over and computer science reverted to being a program for those who were truly interested in it. I'd rather it stayed that way.
It should be noted that both Stanford and MIT have seen a major recent increase in CS enrollment, MIT in the last academic year, Stanford a bit earlier: http://news.ycombinator.com/item?id=2442274. (CMU caps their annual enrollment at 135 students so isn't useful here ... but interestingly enough, contrary to the others in the top 4 they're moving even more towards instead of away from functional programming...).
Those percentages don't mean much out of context. Was the curriculum less stringent back then (I.e. graduating people that shouldn't have been able to)?
Unfortunately, that context (a survey of the difficulty of curriculums for CS programs across the country, per graduation class) would be very hard to collect.
However, we could try to look at CS school drop-out rates, and how many students picked-up or dropped the CS major. Nevertheless, it would be hard to separate "difficult courses" from "students who don't really love CS" as boit and pnathan suggested.
There is a rather breathless presumption that underlies many of the comments to this article, and it is this: that the only way to learn anything thoroughly is to learn it from the inside out: to start from first principles and gradually pile up complexity and abstraction. There is something very compelling about this approach, probably because it purports to model the mind after nature. Just like complex phenomena in nature is built up of smaller, fundamental particles, so too understanding will be built up from atomic units. But stop and think for a moment: how many things in life are really learned that way? Isn't it more often the case that you hack around and only later come to understand what it was that you were doing? I think the fact that it is so intuitively compelling disguises the fact that this conception of learning is really quite bizarre and implausible.
We learn mathematics from the most basic principles and upwards. I don't think there is a way that you could start with higher level concepts and figure out the theory later. It would be incredibly confusing.
Programming is quite different of course. It's not terribly difficult to write a simple program to keep a database of your puzzle collection or build a website to share your puppy photos. One could start from such humble beginnings and build ever-more clever programs and have a steady career doing so. Computers are just machines after all.
But I don't think that's what computer science is really about. IMO it's the study of the nature of computation. Given it's theoretical nature it only makes sense to me that one would start with small foundational concepts and work their way up the ladder as one does in mathematics.
"We learn mathematics from the most basic principles and upwards."
Interesting point, although I'm not sure it's 100% true.
For instance, we learn mathematical skills that are readily applicable to life at an early age. Solving a word problem might be the mathematical equivalent of writing a working program that actually does something. And we memorize "formulas", like the simple one to multiply large numbers, at an early age, but don't learn why it works for quite a while.
Induction and abstract algebras might be considered more fundamental, but are introduced much later.
I also think that bottom-up learning might lead to a false sense of completeness, a sort of "now I know everything". But in reality, there is always some other perspective that will really improve understanding.
That being said, I think learning fundamentals is very valuable, of course.
I love SICP as much as the next person. I've spent vacations devouring it while despairing girlfriends try to get my attention. Seriously, it is awesome.
But, being realistic, an incredible amount of value is currently being created by software engineering. Value to society, and (hence) value to those who can practice the craft. I'm not surprised that so many schools are teaching software engineering, instead of computer science.
But engineers of the physical world variety learn the fundamentals of physics while learning the pragmatics of building codes, loads, and laws. Shouldn't software engineering aspire to the same level of preparedness?
I dispute that. Mechanical engineering isn't physics and neither is electrical engineering. Chemical engineering isn't chemistry (it is, in fact, more thermo- and fluid-dynamics). So, in the same way, software engineering isn't computer science. At best, it has a relationship analogous to that between applied mathematics and pure math.
Unfortunately the trend seems to be the replacement of one with the other. What I am suggesting, one major for each, is exactly the opposite of either/or.
Note that this contention is over one course in the entire CS curriculum. I think there is quite a lot to be gained by continuing to teach SICP somewhere early on, even if the degree programs begin to take on a more earthy, practical approach to compsci. There is no reason "Dive Into Python" can't be taught in something like "Modern Software Engineering 101" and SICP taught in "Fundamental of Software Design" or something to that effect. I think there's place for both, and I fully agree with the author that SICP (or a modern equivalent, if one is ever published) is an important formative text in the mind of the novice programmer. SICP is usually one of the most serious interactions a working "software engineer" will have with functional programming until his beard grays a bit more and he takes a deeper interest in the craft over the day-to-day "engineering". A very valuable experience imo.
So did anyone else look at the challenge problem, see f(n-3), f(n-2), and f(n-1), then immediately think "oh. A three element array would solve that"? Took me less than 60 seconds...
I'm a little worried that I'm so good at imperative programming, though, since it might indicate that I'm "crippled" when it comes to functional programming. I bet one of you could code circles around me when it comes to e.g. implementing a DSL.
Anyone have advice about how I'd go about "diving into functional programming"? What's a fun project to do in Haskell, for example?
I rarely approach a programming problem by trying to define functional routines. Instead, I almost always use state. Seems like a bad habit that I need to focus on breaking.
I looked at it and thought, "easy, I'll just rewrite the Scheme function in Mercury and tell the compiler to memoize the function."
Of course, obviously the point of the exercise is to encourage thinking about how a computer actually performs computations, which is in a linear, imperative fashion. In that case, why use Scheme in the first place? Its syntax and semantics encourage exactly the opposite style of programming, and in my opinion, obstruct the learning process in this kind of problem.
To make an analogy, teaching this problem using Scheme is like teaching someone how to bake a cake using an unplugged Kitchenaid. The Kitchenaid would work great if it was plugged in, but it's not, so you have to push the beater around by hand. Why not just use a hand beater in the first place? [Scheme would work great for this problem if it had memoization, but it doesn't, so you have to solve the problem as if you were using Python. Why not just use Python in the first place?]
The point of Scheme isn't to provide you with a given feature like memoization, its to provide you with the tools so you can do it yourself. SICP covers memoization at the end chapter 3.3.3 (http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-22.html...):
(define (memoize f)
(let ((table (make-table)))
(lambda (x)
(let ((previously-computed-result (lookup x table)))
(or previously-computed-result
(let ((result (f x)))
(insert! x result table)
result))))))
And SICP quits at this point? What if "previously-computed-result" is false, because f computes boolean values? This is just an 80% solution, which works for "fib".
The implementation of tables that he uses isn't actually reasonable for most use. If actually implementing memoization, one would probably use SFRI-44 style maps, which come with a 'contains-key' function that solves this problem.
The same could be said of any Turing-complete language (though I'll admit Scheme's macro system gives it a leg up when it comes to implementing new features.) But given that Scheme's syntax encourages thinking in terms of mathematical recursion, it seems silly that (a) I can't write something so simple as the Fibonacci function by using its traditional mathematical recursive definition, and that (b) SICP encourages the use of Scheme to solve problems which require thinking in terms of iteration and mutation -- this is a pedagogical faux pas.
The difference between Scheme and any "Turing complete language", is the philosophy behind it, which is one of minimalism. That's why memoization isn't implemented for you.
Scheme was also designed to encourage implementing non-recursive control structures, as well as programming with side effects. Scheme isn't supposed to be totally pure. If you encounter a problem that requires mutation, you're supposed to try to abstract away from the mutation, if possible, and it gives you the tools to do that. (first class functions, macros, continuations, etc. are all very effective tools for abstraction, once you learn them.)
I recommend that you use SICP to learn Scheme, as it will make more sense when you actually know how to use it. It's an incredibly elegant and beautiful language, and it's certainly still relevant.
P.S. If you're thinking of those problems in terms of iteration and mutation, you're probably doing it wrong :). Think more functionally.
>I recommend that you use SICP to learn Scheme, as it will make more sense when you actually know how to use it.
I used it my entire graduate career, under an advisor who is part of the inner circle of PLT/Racket. I'm quite familiar with it.
> P.S. If you're thinking of those problems in terms of iteration and mutation, you're probably doing it wrong :). Think more functionally.
I primarily program in Mercury and Coq (languages which are both purely functional). I can promise you I have no problem "thinking functionally". The solution presented in SICP is not structurally recursive (while the "naïve" solution is) but rather relies on an accumulator, tail calls, and a measure to terminate recursion... this is much closer in spirit to an iterative algorithm than a recursive one.
Just sit down and start coding in Haskell. Not that Haskell is the world's best langauge or anything, but it strictly enforces a functional mode of thought, and that's what you want if you want to be forced to program functionally.
Dive into Haskell with whatever interests you. Try solving some Project Euler problems (http://projecteuler.net). Or, maybe web programming suits your fancy (http://snapframework.com). If you're more visual you might play around with these exercises which don't even require you to install anything.
What's a fun project to do in Haskell, for example?
I recommend a project with lots of IO and State. You'll quickly come to understand why the monadic approach to such things is excellent (even if Haskell's implementation is a bit verbose).
In my opinion the idea that there is a division between functional and non-functional programming at all comes because of a disagreement or misunderstanding with the principles of SICP: C is a perfectly functional programming language if you say that each statement is a function from machine state to machine state. . .
It looks like the rationale for Berkeley's change is different than MIT. At MIT the change was made because "being a better programmer" in the classical sense was deemed to be less important than other aspects of engineering. If you look at the new MIT course, you'll see that it starts with an intense overview of python and programming techniques and then moves on to apply those techniques in a variety of relevant engineering-related areas. This makes sense in the context of the MIT major given that the choice to focus on software development doesn't have to be made until later on.
(edit: also there's an interview floating around somewhere that talks about the rationale being that modern programming is different in the sense that it more often requires ability to figure out existing libraries as much as an ability to compose well-structured programs.)
I basically agree with the OP that Dive into python is a pale replacement, but at the same time there is something to SICP's critics. Peter Norvig seemed to think most people would get the most out of it after getting some experience, and the HtDP authors definitely have a point about how much heavy math is involved. It's still a wonderful book, and won't be lost, I'm sure.
"Peter Norvig seemed to think most people would get the most out of it after getting some experience,"
I have to strongly agree with that. In general, you can't understand a solution to a problem until you encounter the problem yourself, and SICP too many solutions, too quickly, for problems you've never encountered, for it to stick very well to a novice. It may seem strange to criticize something for student use for having "too much solution in it", but based on what I've seen it's the truth. It would be a better junior or even senior level course than a freshman intro, when you have something to hook the solutions on to. Or an honors freshman course, for people you know have done some prior programming.
> ...and the HtDP authors definitely have a point about how much heavy math is involved.
I get why people object to heavy math in programming -- it makes the entire field less accessible -- but programming is heavily based on mathematics, if not entirely a subset of mathematics. Saying, "it requires too much math to learn this" strikes me as a lot like saying "there's too much biology in learning to be a doctor".
I strongly disagree that programming is heavily based on mathematics. Rather, mathematical formalisms exist for much of programming, and the better our programming languages become, the more heavily they are based on sound mathematical concepts, because mathematically sound concepts happen to have desirable qualities around consistency and orthogonality.
But simple imperative programming at the level of assembler, for example, I would argue is more closely related to cooking recipes than it is to mathematics. And the reverse mapping of mathematics to programming isn't terribly strong either; most general-purpose programming isn't abstract enough to get big gains from maths.
As a practical matter, I work professionally on compilers - i.e. far closer to the CS end than the glue code end of things - and outside of the usual bits of parsers and grammars and graph theory, I would still submit the only really important piece of CS maths a self-motivated student programmer needs is the analysis of algorithm complexity; big-O notation for space and time, in other words.
All that said, I'd prefer by far students being taught from SICP or CTM[1] than any book targeted at introducing people to a programming language, rather than using a programming language to introduce people to CS concepts. Using practical, industrial languages like Python or Java warps your perspective because in the interests of practicality, those languages are quite opinionated in how you should structure your programs. Things are different with Scheme or Oz.
[1] Concepts, Techniques, and Models of Computer Programming
Ugh. I don't really understand the criticism of too much "heavy math" in SICP. The calculus involved is very basic. The rest involves infinite sequences and series, which are pretty fundamental to Computer Science. Really, students only have to have brushed up against derivatives and have a basic notion of what integrals are to complete SICP.The amount of "calculus" that SICP requires can be learned in a fun-filled afternoon.
I completely agree, but at the same time, it's a barrier to entry that I think might be unnecessary. Some college freshman haven't taken calculus, and SICP would seem a bit daunting at times to those students, I imagine. Unfortunately, I think HtDP goes too far; it's too dumbed down.
Yeah, and that's a serious problem, too -- and one that I'm guilty of! ...that is, if I'd ever gone to college. :-(
I am very much not encouraged by a "race to the bottom" when it comes to education. If calculus is too difficult for the student, then perhaps the student should not consider a career in programming. I say that without any malice whatsoever; I'm not sympathetic enough to be a counselor, and I wouldn't expect counseling courses to simply disregard the importance of counseling so that I could have a job in the field.
To bring all this back to a more practical argument: I am annoyed daily by the great and heaping piles of inefficiencies and bloats and bugs and weaknesses of software. I have to, on a regular basis, explain to clients that they should throw out their old computer and get a new one, so that they can continue to do what is, to them, exactly the same thing they were doing with their old one. That can be a rather challenging thing to explain to some people.
I find it difficult to believe that this ongoing pattern of abuse of resources is not at least partly related to a greater and greater ignorance of the fundamentals of programming.
I really don't see what connection calculus has with the vast majority of programming. Calculus, and algebraic manipulation in general, has next to no relationship with programming. I really don't see any reason why someone who has difficulty with calculus would have similar difficulties with programming; for all I know, they missed out on some fundamentals because they were sick in school, or they fell out with their maths teacher, or god knows what.
The only time I've ever used calculus in a program in 20+ years of programming is in physics simulation in some toy game apps; and that was just to derive some formulas that plugged in. They could have easily been solved today with some googling (other people probably solved the same problems) or questions on forums.
(FWIW, mathematics has always been my best and favourite subject in school, aptitude tests put me in 99th percentile, etc. IOW, I have no personal grudge against maths. I just see very little connection to programming outside niche areas, and even then they usually barely scrape the surface of the related mathematical area.)
PS: I think your specific bugbears are not related to mathematics either. Bugs: best approached with proper programming style like invariants and defensive programming, along with testing. The quality of software that people actually use can be measured from feedback, bug fix rates, etc. A bigger issue with bugs is usually economics; it's frequently more important to get things into people's hands quickly and cheaply than it is to have higher quality and compromise the other two. Bloat and sluggishness have two cures: measurement and big-O. I'd put both in engineering rather than maths. Understanding big-O, either explicitly or intuitively, is absolutely essential, though it's all blatantly obvious when you spend some time thinking about it.
The only thing special about calculus is that it is where practically all universities have decided to start teaching students to create real proofs with the level of formalism expected in other courses. This is likely due to the fact the world needed more engineers than programmers or mathematicians when this stuff got hashed out.
tl;dr: This promotes a view that those who reviewed SICP negatively did so because they were akin to people who wanted to learn how to drive rather than how their car works.
I read the 1st and last page (of 6, tl;dr etc.) reviews and I can't agree with this viewpoint. The negative reviews seem to be based on the structure (viz. haphazard) and tone (viz. boring) of the content rather than the level. That's not to say that I agree with these reviews; I'm just pointing out that the linked page seems inaccurate.
"Starting with the latter, in 2011-12, 61A will be taught by John DeNero (fall) and Paul Hilfinger (spring) using lecture notes based on SICP (since its text is now available on the web with a Creative Commons license that permits such use) but with the program examples recoded in Python. This is, on its face, a strange idea; Scheme and SICP build on each other's strengths and programming in Python as if it were Scheme will surely result in some of the examples looking unlike the way a native Python speaker would code them. But the long-term plan is that over time, the 61A curriculum will gradually change to include "more modern" ideas, leaving out some of the SICP ones to make room; because of its huge collection of application libraries, the new ideas will be more easily expressed in Python than in Scheme. Also, there is currently a vibrant open-source project community using Python, and 61A students can be introduced into that community."
At my school our intro class was in Python, but an SICP class was required for majors. I think this was a pretty decent compromise, especially since many prospective majors placed out of the intro class anyway. I agree that SICP (really FP in general, though the consensus seems to be that SICP is the best way to teach it) is a necessary part of any serious CS curriculum, but I don't think it's necessarily a good place to start--especially if non-CS people are taking the intro class.
Whoa, stop. There's a lot of issues in this article. First of all, Berkeley is NOT getting rid of SICP and SICP ideas. This is flat out untrue.
I'm a recent instructor for the course, and I've spoken to several TA's about this course. Below is a rough summary of what we've discussed. This should not be construed as the "official line", but take from it what you will.
First, Berkeley are not getting rid of SICP. For those who aren't aware, they (the future TA's/instructors) are making lecture notes based on SICP but using Python 3).
From a TA:
At the end of the day most of the reason for moving to Python (beyond the weak argument that it's a bigger community), is that there was a meeting where they realized that nobody wanted to teach the course in Scheme after Brian retires. I'm not burning him at the stake, I read his argument and I've considered it. All I'm saying is that he has bad information. Also, lambda is cool but the only difference between that and defining a function inside the body of another function is the requirement of a name. I know lambda's amazing and it's not nearly as magical when you do it in Python, but Python supports proper closures which is the real reason lambda in Scheme is so powerful.
A different TA:
But the real reason it's not being taught in Scheme? My understanding is that it's not being taught is because no professor wants to teach it in Scheme.
Secondly, we talked about some concerns about whether SICP is actually a good INTRODUCTION. I don't think we dispute that there's a huge value in the course, but whether it's good for an introduction is I think, debatable
I do know that when I was a student, I raised many of these same concerns and frankly, I dont think those concerns are invalid. I think that until you have an appreciation for mathematical elegance and REALLY REALLY understand SICP, which appears to only be true for less than half of the students, much of it is lost. I know that was the case when I took the class, at least.
Should clarify. I'm not saying that 50% of the class "doesn't get it", but there's a deeper level that I think is hard to grasp for people who either don't spend 40 hours a week on this, or don't have a mathematical background.
Good example: Data directed programming. Me as a student was: WTF is this? So I always just call this 'get-data' function? What's the point? Where's the application?
The examples in Scheme are often /SO SIMPLE/ that exercises seem like they are dumb. They often look like a point docking trap in exams to students.
In my mind, SICP is better as a capstone, senior course. Think about all of us who defend it. Do we think that we could reach a better audience with that message if the audience were seniors looking for a summary/enlightenment, rather than freshmen exploring CS and engineering applications?
Correct me if I'm mistaken, but my understanding is that this is essentially SICP if they were to teach a graduate-version of the course. This looked /insanely/ cool.
In any case, for future TAs and Instructors of this course:
It is now up to you to make sure the spirit of SICP and CS education lives on! Not that it's been any different since the beginning of time.
In my mind, SICP is better as a capstone, senior course. Think about all of us who defend it. Do we think that we could reach a better audience with that message if the audience were seniors looking for a summary/enlightenment, rather than freshmen exploring CS and engineering applications?
Indeed. I read SICP while in grad school w/ the online lectures. Frankly, I'm not sure I would have appreciated SICP nearly as much in my freshman year. With that said UCB and MIT are probably the two places you'd expect to find freshman that would appreciate it. But given the fact that the text is freely available online, and there are great lectures available for free online, it might be reasonable to say that for the inquiring student, they can use MIT's Open Courseware.
Here's an interesting direction to take SICP: http
The link you posted is dead. I'm interested in what it is. Could you post a new link?
The link was the 6.945 course at MIT. As I understand it, it's SICP used in a graduate course. It still shows up on google if you search 6.945.
For the truly inquiring student, there's also a planned self-paced version of the course that may also include an honors option to dive deeper than what we can do in 61A (aka, SICP/6.001).
I have taught short programming classes for total beginners, and had the most success by following the first chapter of SICP.
1. It explains what computation is. Total beginners generally have no idea how a program executes and what it does. Explaining it using the substitution model is extremely helpful.
2. It introduces functions right away. This is a way better introduction than trying to explain type-related nonsense like "this is an integer, and this is a floating point number, and this is a string, and these are operators."
3. It avoids IO as the first thing people do. This helps avoid the problem of people thinking that printing "hello world" to the screen is equivalent to returning "hello world" from a function. Beginners should write functions which return stuff, not worry about whether the gets function (Ruby) returns something with a trailing newline.
4. Minimal syntax. Beginners have a hard time with semicolons and begin/end blocks. Python? You're kidding. Beginners don't understand whitespace indentation until they've been programming for at least several days, and making things align right is a horrible thing to throw at them.
I'm willing to accept that SICP's requirement of knowledge of basic calculus makes it a high barrier for many students, but frankly, it's the only book I've seen which introduces beginner concepts in the correct order.
There's no denying raw SICP demands a high level of mathematical maturity, since that could be assumed of all students taking 6.001 (all must master the calculus and calculus based Newtonian mechanics and E&M). But since you can't have an accredited by ABET CS program without requiring the calculus....
Is this a recent development? Without proper lexical scoping, don't you have to do weird stuff like creating an array if you want to update a value inside a "closure"?
One might argue you shouldn't mix functional programming with side effects. ;P
But it's not so much the case of scoping as the case of variable binding. Assignments/statements in Python don't work like they do in some other languages. So your inner function can reference the outer "x" all it wants, but you'll get problems if you try to do something like x += 1.
I find it pretty disappointing that SICP is considered too tough for matriculants of a top CS program. Perhaps you should consider enrolling fewer students and raising standards.
I'm haven't said that, so please don't insult my students by saying that. My argument for it being a capstone stems not at all from that it's too hard. We can not, should not require our students to be putting in the amount of time necessary, in my opinion 40hrs/week, to completely 100% understand this material as a freshman. In my mind, completely understanding it is required for the 'enlightenment' that many like about SICP, but this is not true for many other courses. By putting it in Python, students can learn many useful skills along the way.
Furthermore, I'm arguing that all things being equal, the time is better spent as a senior when you might be able to get the same points for a much lower time commitment.
And, please, remember that this is just one class in a curriculum of CS courses. There is a lot of effort being put in by dozens of professors to graduate the best and brightest, which we do.
"First of all, Berkeley is NOT getting rid of SICP and SICP ideas."
Yeah, that's what they said at MIT, and to my somewhat limited knowledge it simply didn't happen (e.g. most of that material is supposed to be taught in a course that uses Java, which invokes the surface of the phrase "not even wrong").
Ah well, "and then there was one" (CMU among the top 4).
I do like the idea of having it as a capstone. It's what Brian said: "I wish we could teach SICP both to incoming freshmen and seniors before they leave." I definitely understand a lot more of everything the second time through as a TA!
Hi! As a member of the Python community, could you please pick a better textbook than Dive into Python? Think Python is a far better book, off the top of my head, but nearly anything's better than DiP for people not acquainted with the language. (http://greenteapress.com/thinkpython/)
The factual inaccuracies in the Strings chapter, covering encodings and Unicode, are horrific enough. Confusing UCS-4 and UTF-32, getting historical orderings wrong, completely forgetting to mention Latin-1, and worst, failing to directly outline the connection between encoded streams of bytes, and Unicode strings, in clear and direct language.
Also, the horrific RE abuse at the beginning of Chapter 6 is a remarkable standalone example of Doin' It Wrong:
Even MIT abandoned SICP for its introductory course in favor of Python. But I believe it's featured in its second course, no? I don't consider that a mistake. If you're getting rid of it from the curriculum altogether, though, that's a mistake. This article didn't say if that was the case or not. (Also the point of SICP being language agnostic is fairly false. I mean sure you can implement iteration as recursion in other languages, but without tail call optimization it's going to be ugly. Then there's the whole "code as data" problem that's not easily extendable outside the s-exp world. I guess one might say the important, deeper parts of SICP work across languages, but is there an equivalent somewhere to SICP that's not in Lisp?)
Yes, not even the authors of SICP defend it as a good introductory text any more. They have observed that their students don't graduate into a world where they program using the pure, low-level constructs taught in SICP. Instead they have to grapple with layers and layers of APIs written by other people, and messy real-world problems. These require different skills, and it's not bad to have to learn them in school.
Still, SICP is one of the greatest computer science texts ever written, precisely because the learning curve is about as steep as it gets. Each chapter builds on the last, and by chapter three you're learning concepts that clarify some of the thorniest issues you will ever face in an average programming career. Even if you don't get to use a language like Scheme, it's sad if you don't know what SICP has to say about these problems.
1) MIT did not abandon SICP: it decided that it no longer wanted to teach core CS concepts. There was an interview with Abelson on HN a while back, look that up for more. SICP is not featured in the courses at all, unless you count 6.945, an advanced class with Sussman, that goes far beyond.
2) The fact that iteration is a special case of recursion is a fact that does not depend on a language. For its part, SICP distinguishes between the two specifically because most languages don't make this theoretical unity a practical one.
3) Code-as-data is not used much in SICP until the final chapters, where you implement a metacircular interpreter. It is impossible to implement a metacircular interpreter without making use of code-as-data, because that is its point. And in Python, a Scheme interpreter is just as approachable as in Scheme (a Python interpreter is not, simply due to how huge the Python langauge is).
4) There is not, AFAIK, and equivalent to SICP, because we already have SICP.
MIT did not abandon SICP: it decided that it no longer wanted to teach core CS concepts.
Wait, what? Are you claiming that the MIT undergraduate CS program does not "teach core CS concepts"? Or are you only talking about a single introductory course?
Yeah, but how well is the rest of SICP transmitted in a course using Java (6.005, at least according to the original plan)? Based on what I've seen (at a distance nowadays), MIT decided fundamentally change what it means to get an EECS education and degree in a panic move when enrollment dropped by half after being steady for decades.
> Also the point of SICP being language agnostic is fairly false.
I remember reading a bit of Eli Bendersky's SICP blog posts[1], where he started with the premise that he was going to work through SICP using Common Lisp rather than Scheme. I think that lasted through about half of the first chapter before he moved back to Scheme because he found it too hard to handle the differences between the two - I don't remember what specifically Common Lisp was lacking, but I remember he made it seem like a huge stumbling block.
[Disclaimer: This comment is based on a half-remembered perusal of only a couple of blog posts well over a year ago. Contents may not adequately reflect reality.]
Edit: I may have been badly misremembering. From Eli's "Conclusion" post[2]:
> Also, I originally planned to reimplement all the code do all the exercises in Common Lisp. Later I changed my mind and decided to use PLT Scheme for some of them. Eventually, I’ve been using both languages interchangeably, which is a good thing, as I got some practice with both.
When I started the project, I preferred CL over Scheme. Later, however, I had some experience with PLT Scheme and really liked the programming environment, so I decided to give it a try. I figured that using both languages will help me understand the differences between them better. It was not some serious limitation of CL, in any case.
As I said in my update, I was apparently badly misremembering a comment on your blog regarding the use of CL.
You've actually inspired me to take up a similar SICP reading/blogging project, though I'm hesitant for two reasons. First is the concern over the depth of the material. I don't have a CS degree and I'm mathematically out of shape (and I never even did a calculus class), so I'm concerned about making it to a certain point and then completely failing to be able to continue on. Second is a concern about copyright and plagiarism. I've never been clear where the line is with regards to the sort of summarizing knowledge of a whole book, since paraphrasing is still plagiarism AFAIK. Less of an issue with SICP, I'm sure, since you ended up with a signed copy, but I'm a very risk-averse individual and like to know exactly where I stand before attempting such a thing.
I'm sure that your blog will be a great resource for me when I do my version of your project, so I'd like to thank you in advance for having blazed the trail for me.
You should by all means do it, because you don't have a CS degree. Don't worry about the math too much - it is all explained there, and whatever isn't you can easily find out. Don't forget that the most important thing here is the learning experience. It may take you longer to complete, but you will learn more in the process.
IANAL. Plagiarism is only relevant in a classroom environment where you aren't doing work in the expected way. Copyright infringement is different. In the case of SICP, the entire book is available online for free, as far as I know the book doesn't contain answers to all of the exercises (so most work you do there is your own), and many of the code snippets are small enough that I don't think they would withstand a copyright claim in court. (It'd be like trying to copyright "for (int i = 0; i < MAX; ++i)".) Even if you blatantly copy out large sections from the ebook for a blog entry, I'm still pretty sure there's a strong fair use claim to be had. (I guess it would be weakened if your blog serves ads.) Cite your source and you'll be alright.
re: Calculus, you could always watch a few videos at Khan Academy. ;) I don't remember needing all that much calculus, but if you don't have a concept of derivatives or integrals then some of the earlier examples of higher order functions will go over your head. You could watch some online lectures here: http://academicearth.org/courses/the-structure-and-interpret... which don't ramp up the difficulty as steeply.
Right, sorry. `s/plagiarism/copyright infringement/g`. I've been reading a bit too much about education lately, and I guess it snuck in.
I knew SICP was CC-licensed, so I guess it was relatively clear that I'd be in the clear here. I have a sort of end game in mind where I build myself up enough to work through TAOCP as well (ha!), and it's certainly not CC-licensed. I rather enjoy the idea of doing something like this in public, for moral support and random acts of guidance, so it'll become important for me to know where the line is.
And yes, I'm quite familiar with Khan. I had a couple complaints about the site early on and ended up falling out of the work because of it (the main issue specifically was that I was working through the exercise section, and I had to do a geometry section for which there seemed not to be a relevant video, so I got stuck on a given node in the progress graph). The end game for that plan was to get at least through introductory calculus, since it almost feels like my geek card is illegitimate without it. I definitely need to take another run at it.
Publishing a Python version of SICP would solve the problem. Sure, you can't always translate Scheme to Python with ease, but even a smaller, modern edition of SICP written in a Pythonic way would be extremely beneficial.
My introduction to Scheme, incidentally, came while I was learning JavaScript, and it was through a book that hadn't originally been written in Scheme, either: http://javascript.crockford.com/little.html
How introductory programming is taught should really be approached from two directions these days. (1) How to teach a firm foundation for those likely to pursue computer science, and (2) how to motivate and teach a breadth of material to those students who likely will not take more computer science courses.
At a place like Stanford, a majority of undergraduates will have taken an introductory computer science course by the time they graduate, but it's obviously not true that a majority will be computer science majors. And while I appreciate SICP and Scheme and functional programming, and completely understand why that kind of thinking should be valued, it may not be the best way to present a breadth of introductory programming knowledge that will motivate, interest, and offer practical examples. Sure, lambdas are awesome, but when you are just starting out in your first programming course, the deep theory behind why lambdas are so interesting will almost certainly be lost on the students. It's like building up a field of math from, say axiomatic set theory or algebra. By the time you get to multiplication and fields (perhaps akin to variables or for loops in programming), you gain a very deep understanding and appreciation for the topic that can only be gained by this bottom-up problem based approach, but then again, a non-mathematician (or non-computer scientist) could have probably just assume the existence of multiplication or loops for the sake of solving higher-level problems.
So SICP is awesome. The article makes that assertion in the third paragraph, and then continues making that point for most of the rest of the article. It does not, however, make a good, convincing argument for why "Dive Into Python" is significantly worse, especially as an introductory text.
> It’s just.. it’s just not the same.
Never say this. Horrible people (like me?) will point to it as you admitting that your argument is founded on nostalgia for the way things were, regardless of how strong the rest of your argument is.
"Stop. Take a deep breath. Think about all that you have just discovered (or if you have already discovered it all, reflect on how awesome it is). By page 45 of SICP, you will have;
Translated recursive definitions into iterative processes
Examined the differences in the space requirements of various processes
Used tail-recursion to implement efficient iterative procedures
Seen that iteration can be thought of as a special case of recursion
Realized that iterative processes can be restarted easily by capturing and restoring their state variables
Given thought to complexity, optimization, and state transition theory
Been encouraged to explore creative solutions to challenging problems
Learned the basic syntax and semantics of Scheme
Observed a quasi-religious experience
What will you have accomplished by page 45 of Dive Into Python? Don’t hold your breath. I’ve looked into it. You’ll be learning how to use the and-or “trick” to make simple programs difficult to read. Soon afterwards you’ll be exposed to Python’s intentionally crippled lambda statement."
"Scheme is considerably less complicated and idiosyncratic than Python. It’s simplicity and consistency have immense pedagogical value. It might take you anywhere from a day to a month to pick up the basics of Python. Scheme, on the other hand, has virtually no syntax. It’s definitely possible to get a solid grasp of its fundamentals in less than an hour.
Python can be used to accomplish many of the same things as Scheme. Practically anything you can do in Scheme you can do in Python, and formally speaking, the two languages are equivalent.
However, until a Python textbook emerges that surpasses SICP in teaching the core elements of programming, we should stick with Scheme."
A single paragraph insulting a work does not a convincing argument make (perhaps the fact that it starts off very slow is good in introductory textbooks?). Nor does an assertion of how Scheme is "considerably less complicated and idiosyncratic than Python" convince me that all Python textbooks must, by necessity, be worse than Scheme textbooks.
I'm entirely willing to admit that SICP is better than Dive Into Python (well, I would be if I had a copy of it around so that I could verify this). I'm just saying that the article does little to convince me of that (and quoting parts of it at me does even less to convince me - if you think that I didn't read it thoroughly enough, just come out and say so).
> ...if you think that I didn't read it thoroughly enough, just come out and say so...
OK. I don't think you read it thoroughly enough. I wouldn't usually just come out and tell someone that, because it's likely to start a fight, and that won't help anybody. But, since you asked...
The post repeatedly makes the point that SICP primarily presents a language-agnostic approach to understanding how to solve problems in programming. The author even explains that they aren't objecting so much to Python specifically as they are to the fact that there isn't an SICP-type book which happens to include Python for its code examples. The author does make the claim that Python requires more focus on syntax than Scheme does, and exemplifies this with the "and-or trick", but that's not really central to their argument.
Their main argument is that programming should be taught as an approach to problem-solving, not as an introduction to a language, and that by removing SICP from the curricula, future programmers will lose some valuable skills.
SICP is a great book. Its abandonment is a sad reflexion of the gradual descent of programming teaching from principled discipline into an introduction to the process of trial and error. While most developers probably spend the majority of their time experimentally cobbling together applications from blackbox components, this they can and probably must learn on the job. What SICP tries to teach they cannot -- the most fundamental idea in programming:
The evaluator, which determines the meaning of expressions in a programming language, is just another program.
We are starting to embrace again more featureful languages and regrettably accepting that the majority of programmers will use multiple languages regularly. Therefore SICP seems more appropriate than ever!
It makes me so happy to see such an interesting and passionate article on hn, and at the top no less. So much more valuable than all the "what kind of socks to wear when launching a starup" type posts.
I'm not worried. Good programmers read SICP on their spare time if they don't have to do it in school. If they haven't heard of SICP, they will once they'll join the company of other good programmers and probably find it interesting. On the other hand you can't force material on people who reject it because they don't understand it.
It's just the question of where do we need universities at all when everything valuable is replaced with ever-easier material? Of course, the marginal number of people who actually want to become academics in CS will be needing universities, but that would amount to 1/10th or likely less of current CS student population.
I've always found SICP quite overrated (I'm saying this after reading it).
Given Python's learning curve, a much better curriculum would involve going through the codebase of a few well-chosen projects, sending in a few patches and perhaps writing a report on the high-level design of the piece of software or on how the project solves a particular problem (how does XYZ handle i18n? how does ABC stay stable even on a failing network?)
I can think of at least three conflicting approaches to teach programming:
- Start with a low-level language like C (or MMIX...), possibly on embedded devices, so that students know what is going on at the hardware level and don't think that primitives in high-level languages are free.
- Start with a functional language like Lisp, so that students know the theory and the elegance of functional programming.
- Start with an easy and practical language like Python, so that students get to write (crappy) code as soon as possible, tweak it until it works, and finally see their program work and do something impressive (to them).
SICP is an excellent book, and a very good choice for the second approach, but it is not the only sensible way to discover programming.
I did have SICP when I started undergrad, and I wish, and asked my professor why can't we use "something modern like python". He gave me some reasoning, and I wish I remember what it was. I think part of the problem is that there isn't enough of a "fun" or "excitement" component in SICP for a very many n00bs, which I was then. Python was cool. Perl was cool too. They're not terrible languages, but admittedly boggled down by syntax. Scheme had a "for education purposes rep" (many times propagated by professors themselves). And there was no "easy_install mechanize" or "easy_install pyqt" to start doing cool shit in Scheme (which I don't believe is true, but for whatever reason at that point it wasn't apparent this was even an option to me).
Overall, I had a lot more fun starting off with Python on my own time. I may have taken longer than most to come around and appreciate Scheme, and certainly find myself wishing JavaScript had less syntax. SICP is awesome though. In fact, I sold most of my books after I was done with university including that one. But maybe 3 or 4 years later, I ended up purchasing it again as I wanted to find classic Lisp literature. Only after it got delivered did I realize this was the same book. And this time around I did truly enjoy it. But I wish I remember what reasoning my professor gave for preferring Scheme over Python.
I don't know if someone has already cited this lengthy interview to Hal Abelson (co-author of SICP) about this change, but I think it is worthy to point it out:
The books that are beloved by practitioners in a field are not always the best choice in terms of pedagogy. Clearly, these professors think that another book choice will help their students really grok the material. If they're successful, great. If they're not, they'll probably recognize it and supplement with other material or switch to another text. It's certainly possible to be a competent programmer without ever having read SICP in the same way that it's possible to learn linear algebra and calculus without ever having read Strang. My CS program didn't use SICP and I don't feel like I really missed anything of critical importance. There are other very competent authors writing other very good textbooks, after all. I was still exposed to Assembly, Fortran, Pascal, C, C++, Java, Scheme, Lisp, and Prolog in my program and learned core concepts of computer science such as asymptotic complexity, recurrence relations, Boolean logic, countability, Turing machines, finite automata, parsers, interpreters, threads, data structures, grammars, Backus-Naur form, etc.
What I do not understand is that Python is seen as a good language to teach Computer Science. I would have thought that a requirement for such a language is that it is theoretically sound. Python has a broken scope concept. Also, I think that a "there is only one way to do it" philosophy, coupled with the crippling of several constructs, is not a good basis for forming an open mind.
The new 61a will still try to (roughly) follow the old 61a/SICP curriculum. Dive into Python will (I think) probably just be used in the beginning to introduce the language.
The assumption that college should prepare you for a career is a fallacy. You should be able to teach yourself programming well enough to program, and take a few classes on the side for kicks+extra progress. But going to a 4-year institution and expecting that to be your golden ticket to a career? Ludicrous.
I go to school to be exposed to things I wouldn't otherwise. I go there to meet people I wouldn't otherwise. I go there to figure out myself, and challenge myself. If I wanted to go into a career working with Spring MVC, I'd have been ready for that out of high school (less the degree many places require–the requirements are a separate issue).
The obvious solution: rewrite SICP to use Python rather than Scheme. It is CC attribution and non-commercial, so I don't see any legal barrier to outsider revision.
The beauty of Scheme is that it makes the underlying language mechanics transparent. The mental models I acquired from SICP for the process of computation have served me well across a dozen languages since.
No, I definitely agree with this. Scheme is a valuable pedagogical tool.
But that probably doesn't matter. So it's better, on the whole, to preserve what you can out of the current book by adapting it to Python than losing it completely.
Things will get lost in translation and substantive changes will have to be made. That's why writing textbooks is a creative endeavor rather than just updating the English used in older texts.
SCIP winds up making sure that you understand what is going on by writing Scheme interpreter in Scheme. How would your translation handle that material?
Writing a Scheme interpreter in Python would force people to learn all of that Scheme anyways, and it wouldn't feel like such a revelation that you understand what the interpreter is actually doing.
Writing a Python interpreter in Python would force people to learn a lot more about parsing techniques. That would add a lot more material, and the code would be substantially more complex, thereby obscuring the pedagogical point.
Why not write a python(subset) interpreter in scheme?
The point is once you scan,tokenize and parse you get an AST. You already got a language that works on AST. I don't think python's AST is gonna differ a lot from scheme's.
I think that the point was that the AST for a Scheme program isn't that different from the AST for a Python program, even though the code looks different.
Unfortunately that point is false as well. The AST for a Python program will generally involve a lot of message dispatches that won't exist in the AST for a similar Scheme program.
To get a sense of the difference, in Python if you yield, your code actually gets turned into a class with certain methods that get called repeatedly, and restart your method at the correct place with the correct state. By contrast equivalent code in Scheme will somewhere under the hood have call-with-current-continuation, which works by very different mechanics.
That is not possible or desirable. Scheme-specific constructions are woven throughout the text -- tail calls, closures, and more.
And the main value of SICP, at least for its fans, is the pedagogic value of the language. It starts off with pure functional programming and then introduces assignment much later, and discusses its tradeoffs.
How are tail calls and closures in any way Scheme-specific?
The "main value" cited also assumes "pure functional programming" is worthwhile. That is not an uncontroversial opinion, and does little to make the case for SICP to people not already convinced.
Scheme works great in SICP because it doesn't get in the way. After the first few pages, it doesn't feel like you're reading a programming language so much as reading the direct expression of concepts discussed in the text. The programming language learning hurdle is almost nonexistent.
That fact reduces cognitive load on the reader, freeing up mental resources that can be applied to the concepts presented.
Well, the question was about Python, which definitely doesn't have those things. If you want to me to justify Scheme, how about code-as-data, which is the entirety of chapter 4?
> That is not an uncontroversial opinion, and does little to make the case for SICP to people not already convinced.
That was not an unconsidered viewpoint, if you read what I wrote. I said "for its fans". I am not attempting to make the case for SICP; that book doesn't need my help.
CPython doesn't have built-in tail call optimization, but that's not a fundamental property of the language, just a limit of that particular implementation. One that can even be hacked around in Python with a decorator. A decorator, by the way, is a Python feature that depends on closures, which are themselves quite commonly used in Python.
You have some very strange ideas about Python that appear to have little relation to reality.
Python has things they call closures but they aren't what Scheme (or Lisp, or Perl, or Ruby, or Smalltalk, or JavaScript, or C#...) would call a closure. I think it's fair to say that Python is the odd language out here. The scoping rules are different unless you use the relatively recent "nonlocal" keyword.
Anyway, why are you getting offended? Python is a great language.
Some people just think Scheme teaches certain aspects of programming better for various reasons. For instance, in Scheme, the program listing is a representation of the parse tree. Python will construct a similar tree, but this is not revealed to the programmer as much. So if you learn Scheme you can imagine how what Python is really doing (and writing parsers is much simpler because you have an intuitive sense of how they work).
And the ability to manipulate code as data is exclusive to s-expression based languages. This enables (for instance) truly hygienic macros. You don't get that in Python.
On the other hand, object-oriented programming in Scheme is pretty terrible. The part in SICP where they try to simulate it in Scheme is a travesty. Although it is somewhat illustrative of what's "really" going on, without the syntactic support it just looks ridiculous. So that's a win for Python.
Similarly, whipping up a complex data structure takes far fewer keystrokes, and is more transparent, in Pythonic syntax. Just as Scheme benefits from having built-in lists, Python wins even bigger for having lists and dictionaries everywhere. And overall Python is objectively more practical, with its vast array of libraries and ease of use.
I honestly don't know if you're trolling or are just being partisan. Not all languages are the same and there isn't any one "winner" language.
Unusual scoping rules that are easily worked around do not make Python's closures not closures. And I'm not sure why you're bringing up lambda -- I don't know anyone who uses it much, and I consider it an obfuscation mechanism rather than a useful tool.
As for your personal attacks on me... I dispute statements you made that I consider to be utterly wrong, and you say I'm "getting offended" and "trolling"? Now I'm offended.
I look up and down the comments on here and I see all sorts of people making blanket statements about how great Scheme is, yet when I argue a couple specific points you brought up about Python, I'm being the partisan troll? WTF?
My impression is that a lot of the Python in such a book would be highly non-idiomatic and/or too clever to be considered "good Python practice", which is not a very good idea in a pedagogical setting
Good god. I took Sussman's course when SICP was still in the notes phase. I never would have predicted that it would have such a following almost 30 years later.
I took Sussman's course in '87 with a $30 used copy of SICP which still sits on my shelf, surviving many other books that have long since faded into obsolescence.
From the preface: "Our design of this introductory computer-science subject reflects two major concerns. First, we want to establish the idea that a computer language is not just a way of getting a computer to perform operations but rather that it is a novel formal medium for expressing ideas about methodology. Second, we believe that the essential material to be addressed by a subject at this level is not the syntax of particular programming-language constructs, nor clever algorithms for computing particular functions efficiently, not even the mathematical analysis of algorithms and the foundations of computing, but rather the techniques used to control the intellectual complexity of large software systems."
The merits of SICP have been debated many times. More interesting is the choice of "Dive Into Python." Is that really the best Python book for Berkeley CS?
That's why there should be a separate line of courses for people who are interested in practical programming rather than computer science, similar to the way many schools have separate "calculus for business" or "calculus for engineers" classes for those who aren't math majors.
Why on earth not? What's so bad about starting at a high level of abstraction and then progressively peeling the abstraction away to get to the core concepts?
Proof writing depends more on abstract reasoning than knowledge of arithmetics.
Of course, traditionally, it works that way. I would say, though, it's harmful a bit for the reason that the basic math curriculum is so boring, it puts off many brilliant minds.
Mandatory reference: TED Talk, Wolfram on Math Education. ;-)
I actually think that students could be exposed to proofs at an earlier level. At least, the ability to conceptualize a reasoned argument.
But I think to be able to do actual mathematical proofs, elementary school students may lack many of the tools and mechanisms that are necessary. Those tools being arithmetic and basic operations. By the same token, I think understanding basic CS principles and programming are necessary prior to understanding the theory.
Though it would be interesting for an Intro to CS course that used no actual language but was taught with only psuedocode. Teach basic concepts, hell even data structures, prior to tying the concepts to any one programming language.
Actually, i agree with him than SICP goes through a lot more important concepts than Dive Into Python, or any other book like this can do.
I also don't find it good that berkeley is abandonning it. But, i really think that it's not necessarily a good choice for an introductory course.
To sum up my position fast, i would say : "First teach how to program some silly things, by teaching the basis of a language (and python seems a very good choice for this). Then when students are addicted, show them some SICP"
This resonates with a lots of comments about SICP, where people who liked it are often quite experienced programmers, and not beginners (Not to say that SICP can't be appreciated by novices, but that it's probably a bit hard for an introductory course)
Although Python will be used to convey the material, I have been assured that much of the content from SICP will be preserved.
I recognize now that CS61A is a fusion of sorts: an exciting modern treatment of traditionally intellectual material. This change reflects concerns about the difficulty of SICP, the popularity of Python, and a general lack of interest on the part of students and teachers in Scheme. Fair enough. I think this is the best possible solution for an introductory course, but that's just my opinion.
I want to reiterate that I mean Berkeley or its professors no disrespect, and that I only raised this issue because I was concerned about a potentially drastic shift in the curriculum.
I can't begin to thank you all for your comments, criticism, emails, and interest. It's made a world of difference.
Why to make so much noise? Universities, even good ones, are about making money at first. So, if mediocre masses thinks that python is 'more practical' or that 'with Java they can always get a job' they have no choice, but to follow these stupid stereotypes.
Trying to convince mediocre masses that Scheme is really beautiful or SCIP is the greatest programming book ever (OK, together with the Man-month =) is not their job, their job is to get money from student's parents, good PR and grants from government or IBM.
Those who are smart enough and have a bit of taste will find out SCIP or discover beauty of Scheme (Python3/Ruby) and abandon Java or PHP themselves. ^_^
I don't know what, if anything, is going on at Berkeley, but Hal Abelson talked quite a bit about the switch from SICP to a different intro course at MIT when I interviewed him for Code Quarterly http://www.codequarterly.com/2011/hal-abelson/ and it wasn't about abandoning Scheme or "not teaching core computer science". (Well, maybe a bit less core computer science in the intro course but that was basically so that CS people could have more time later for CS without all that annoying EE stuff. And vice versa.)
Yeah, well, Hal has be diplomatic, he can't authoritatively state that the order came down from on high (perhaps above the department) that Scheme was to be totally purged from the base undergraduate curriculum, which to my knowledge was finished not long ago. That's what's behind his statement "And for random reasons we didn't [do the course in Scheme]."
That said, Hal himself does fully support the change from SICP/6.001 to 6.01 according to my sources.
And you're right that much less EE is required of of pure CS majors (6-3s), but I'm told that very few current students do that major, most do the combined EECS one....
To finish, while I don't have time right now to finish reading/skimming your very interesting interview (you do realize you are by far the best interviewer in our field?) as far as I can tell a lot of the deep stuff taught in SICP/6.001 has also been purged from the base undergraduate curriculum. Kinda reminds me of when the Boy Scouts of the USA changed their system in the '70s so that you could become an Eagle Scout without ever having camped outdoors, started a fire, etc.
(My response to that was to drop out of Boy Scouts; here, as a scientist by inclination who just happens to narrow interests in CS which are fairly EQ with SICP I don't exactly have a dog in this hunt (amusingly, my other big interest in this general field is pure software engineering, the fruits of starting out on an IBM 1130 and realizing there HAD to be a better way to do things :-). Although I do seriously wonder about the de-emphasis of functional programming at some of the top 4 in the multi-core future which is today).
Late to the party here, but over at the other SICP-related thread that's on the frontpage right now I've linked to an updated version of SICP where an enthusiast has created a pdf with greatly improved legibility, formulas set with tex and figures drawn with vector graphics.
For those who haven't read SICP: don't get the impression that it only deals with very easy stuff like the example in the post about turning a recursive definition into an iterative one. It actually touches on many of the bet ideas in CS. This post could have easily chosen a more interesting example.
The author makes the assumption that the only books people will ever read are those books that were assigned as part of a formal course. That may be true of some people, but it's certainly not true of the average programmer!
Even the average programmer must keep up with the changes in whatever systems and languages they use, long after completing formal education. Therefore they must read beyond what their formal education prescribed.
I am just curious on this as I don't know Scheme at all. Could a new SICP book be authored that used Python instead of Scheme? Thereby, teaching what SICP was meant to teach yet using Python a well used "field" language?
programmers who have a good understanding of scheme and SICP are likely to pick up programming in python (or equivalent such as C#, Java, etc.) anyway - either on their own, or through industry experience.
it is a shame that csci is shifting away from teaching fundamentals to teaching syntax. it would be like teaching art with color-by-numbers.
I'd been programming over 20 years when I read SICP. The book was interesting. It was interesting as an introduction to functional programming. But, in my opinion, a lot of the stuff in it that is held up to be clever or informative is just difficult because the reader is expected to figure out how to to imperative programming in a functional language.
A computer is an imperative device. It is a deterministic state machine. Teaching introductory programming with a functional language is teaching students wrong, i.e. it does them a disservice. This being ycombinator, and given pg's thoughts on the merits of FP, I may not have a popular view. We will just have to agree to disagree.
Once you figure out (i.e. immediately if you have done it before) that computers are imperative, not functional, many of the "truths" or "revelations" in SICP are like "well, duh" or worse, "why the fuck did you make me go to all that effort?"
A computer is an imperative device. It is a deterministic state machine. Teaching introductory programming with a functional language is teaching students wrong, i.e. it does them a disservice.
One could as easily argue that a computer is a tool, and if it helps us making better (according to some criteria) programs, why not abstract away the underlying architecture?
Because it would not be an abstraction of what is there. It would be the creation of an abstraction of something that isnt there: i.e. a simulation. And indeed, this is exactly the cause of my complaint.
Its like you have a machine that deals with squares. You're suggestion is to "abstract" the system into shapes, but then build a system using circles. A shape is an abstraction of both squares and circles. But a circle is not a square, and squares are what you have. FP languages and Imperative Languages are both specializations of the "programming language". But FP is not a generalization of IP. The computer is an IP machine.
When reading SICP there were several places where I had an uneasy feeling. Something was wrong and I didn't immediately know why. Then it clicked: I'm being asked to make rectilinear geometry out of circles. First time students aren't going to make it past the confusion.
And finally, if we're abstracting away the underlying architecture, why the focus on tail-recursion (an optimization), iteration vs recursion (an optimization), memoization (an optimization)... The complaint of the original article is that the alternative books are "How To Program In Language X", instead of "How to Program". However, SICP is most definitely "How to Program in Scheme".
In my country, we have Computer Science and Computer Engineering. CompSci is done in Science or Math faculties, while CompEng is done in engineering faculties.
CompSci is about abstract theory. It's more related to math then to engineering. To CompSci, computer languages are the building blocks. The fact that those language happen to run on computers is implementation detail. The fact that those computers are imperative is also implementation detail.
I'd say most CompSci students here don't care much about the inner workings of computers.
CompEng students are different. They couldn't care less about functional programming and care a lot about the underlying implementation.
Different people, different interests. I'd keep SICP for CompSci but not for CompEng.
I'll end with a quote:
Computer science is no more about computers than astronomy is about telescopes~Edsger Dijkstra
- The best way to make both ends meet is to tie a knot ;)
- SICP 2.0 - Why don't the nirvana hackers hack the SICP book and lay down stuff they have learnt since their enlightment, as a legacy for all the future CS students? :)
- It will be a OPEN book, highly reviewed and revered ;)
If you can understand the core concepts of programming, the individual languages begin to matter a lot less. Python is great. Java is great. C++ is great. But they are just tools for solving classes of problems; if you don't understand how to, as the author says by way of example, deconstruct problems and understand the advantages and disadvantages of various solutions, then the software you write will never be as efficient or as elegant as it could be.
There is a compelling argument that, in the age of nearly limitless computing resources, it doesn't matter anyway. You will in all likelihood be a glue programmer: you'll rely on APIs and libraries, most of which have been written by someone else, and you will simply string them together by applying the functions that most obviously address whatever problem you're trying to solve. Who cares, really, if you're using Quicksort or heap sort, you're just going to call sort() on your array (or map, or key-value store, or whatever), and define a callback function that will evaluate any two given values in the array to be sorted, and that's it. Who cares if one requires a little more memory than the other, or a little more time to execute?
Just knock it out, and then get back to arguing online about the One True Language, or the One True Framework.
But, I've been programming for about 25 years now, in dozens of languages, and I can't help but feel that this language-specific approach to programming is producing anemic programmers.
Programming can be a craft; in can be done well, and elegantly. I can hack together a decent, reasonably strong wooden workbench for my shop, but it doesn't possess the same craftsmanship as a dedicated wood worker. It does the job, but it is ugly and uninspiring, and nobody admires it.
So, I guess I think that programming is similar, and moving from SICP to teaching Python or Java is just another representative sample of a disappointing sea change away from what I've come to know and love about programming.