Why SICP Matters
cs.berkeley.edu
cs.berkeley.edu
`How to design programmes' (http://www.htdp.org/) leaves a better impression as a beginners' book for me.
If you can already programme then "Programming Languages: Application and Interpretation" (http://cs.brown.edu/courses/cs173/2012/book/) is a great follow-up.
C Programming Language by Kernighan and Ritchie
The Practice of Programming Kernighan and Pike
The Practice of Programming shows more signs of its age. It is a good read, but it could do with an update.
http://www.amazon.com/Thinking-Forth-Leo-Brodie/dp/097645870...
Is there another book that is like SICP in overall thematic content that uses Miranda? (Or I guess Haskell might be a more likely choice today?)
For the more advanced reader "Programming Languages: Application and Interpretation" has a similar focus like SICP on the workings of programming languages---not for an accident they both share `interpration' in the name. Read the book at http://cs.brown.edu/courses/cs173/2012/book/
I have also been impressed with Learn you a Haskell for Great Good (http://learnyouahaskell.com/), but it is not very much like SICP.
- the mathematician-programmers: the thinking in terms of "what is" extreme, or mathematical thinking inspired programming: people closer to this like to think in terms of types and usually dislike dynamic languages, they also like to be able to properly reason about all aspects of a program, to have defined "states" they can think about. These people tend to like MLs, Haskell, OCaml, F#. The "mathematical beauty of perfect code" is their ideal and favorite metaphor. And I think they are right that teaching a Lisp to a beginner pushes ones mind away from "what is" oriented programming.
- the Schemers: the thinking in terms of "what transformations to apply to something (it doesn't matter what "something" actually "is") to get something else or somewhere else" programmer: these people like to be able to transform everything, including code itself, they like homoiconicity or macros in general, they prefer thinking in terms of "how to compose/cahin transofrmations" instead of types, they tend either no know or not value category theory too much and they are ok with seeing code as an "organic entity" that can't always be reasoned about. These people tend to like Lisps, Smalltalk and dynamic languages. The "programming as magick", in the sense of "controlling the spirits (processes) inside computers" is their favorite metaphor. They also like to maintain a playful mood and their "it's ok that paying customers get shafted every now and then" may have had a reason for businesses' dislike for "schemer" types and "schemer" realted technologies. As an offside paradox, some "schemers" tend to also like OOP, though they understand it should not be overused (I consider Alan Kay, usually mentiones as the father of OOP to be a "schemer"). I think that exposing a young learner to Lisp pushes one mind towards this direction, and this is why I love SICP. If you are a competent engineer you surely have a serious amount of math knowledge, so you can easily switch your mind to what-is/math mode and see the mathematical beauty when there is one to be seen, but most "mathematician-programmers" never seem to be able to love this "ruleless organic beauty" of the "schemer way".
I consider myself a "schemer" and I am biased to this side, but I understand and appreciate the value and arguments of the other - I'd rather fly in a plane with the control systems coded by a "mathematician-programmer" than by a "schemer" like me :)
I prefer the "programming as magick" metaphor, and would say I have a playful mood regarding programming, but I still like static typing. Having said that, I love higher-order functions and macros as well.
Defining it as a continuum feels like I should be either on one end, or somewhere inbetween on the various traits, but I have rather strong attachment to some traits from each side.
I think you're right that a lot of the traits you mention tend to be clustered together in programmers though.
But I think that higher-order functions don't belong to one extreme or the other - anyone uses them, even weekend-coders that do javascript or have been exposed to php 5.4's new features end up using them - they are something so basic that any language has it in one form or another, even C has function pointers. Macros, otoh are a very different creature: they may seem similar to higher order functions in Haskell where you can use hof for what you'd use macros in Lisp, but they are a whole different ball game because you can't reason (formally, or informally but within the "what is" mindview) about code that transforms/generates code (or you can, but it's just TOO HARD), and I guess this is why so many developers are afraid of them and language-designers omitted them or added them as an extra feature and not as core language defining features from day 0 (for example Scala - I bet the language would've been very different if macros would've been there since version 0.1, been more "usable", and used to build more core language features on top of them...).
That quote describes me to a T.
The University of Minnesota taught a sophomore class on OO using SICP. At the time, C++ was hot (this was about 1991 or 1992) and I distinctly remember someone raising their hand and asking "Why are we learning this language that we will never use again? Why isn't an OO class taught in C++?" And I remember thinking to myself "Who cares what language it's in? I'm kind of excited about learning another language." And I truly was.
It wasn't until much later, after being in industry for a decade (currently starting my third decade now ;) )that I recall thinking to myself "You know, that book had a tremendous impact on how I write software and program in general, I need to pick that up again, what was it?" And I re-found it and am on my third reading of it as I write this, mostly just to refresh the ideas in my mind (since I mostly work in Java and JavaScript these days), but I have never truly finished the whole book. The class took us through chapter 3 and then sort of a mixed bag of topics from later in the book, so I've never truly read the whole book, but certainly enough of it to help me.
I didn't realize it was a famous book at the time, it was just our text book. I still didn't realize it was a famous book when I re-bought it a decade later. And now I know why it is a famous book, it is that good. And though the third re-read is very familiar, I still enjoy it and find it profound.
"...when some field is just getting started and you don't really understand it very well, it's very easy to confuse the essence of what you're doing with the tools that you use..."
"...Well, similarly, I think in the future people will look back and say, yes, those primitives in the 20th century were fiddling around with these gadgets called computers, but really what they were doing is starting to learn how to formalize intuitions about process, how to do things, starting to develop a way to talk precisely about how-to knowledge..."
So true of so many fields, namely photography. Can't tell you how much camera gear I bought before I finally sold it all and started taking photographs.
As it is with computers. Languages mean nothing, it's the concepts that matter.
I have only skimmed so far, but combined with the lectures I have to say that I really wish that had been my introduction to programming. Maybe it is just because of where I'm at, but it really feels like in the first 3 lectures some of the more elusive topics of programming are at least touched. Sure, you will need to seek out more, but it is not as hidden behind "but for this language, you have to do this" kind of crap.
Or as a pdf: https://github.com/sarabander/sicp-pdf
http://mitpress.mit.edu/books/structure-and-interpretation-c...
For the mind-blowing effect to occur, you must actually do the exercises. (-:
is a reading group just starting up now if anyone is interested
http://www.amazon.com/Structure-Interpretation-Computer-Prog...
These don't seem like very good reasons to choose one over the other; the choice probably came down to culture.
>CAML Light does not exist anymore
French classes prépa[1] have been using it in the CS course until this year (I have heard it would be dropped in favour of Python next September). So even though there hasn't been any development for the past 10 years[2] it still exists! And then there is OCaml which is still lively.
Even though a CS graduate may say that S-expressions are the simplest syntax possible - not that he's wrong - I'm happy I discovered functional programming through OCaml, whose syntax feels way more natural (to me at least).
1: http://en.wikipedia.org/wiki/Classe_pr%C3%A9paratoire_aux_gr...
2: at least according to http://caml.inria.fr/caml-light/release.fr.html
Might I argue that this is a huge advantage? No one knows scheme, and it's very obscure, and looks nothing like other programming languages. This means that you can teach concepts using it and pre-judgements about the language don't get in the way.
Then, I suppose the same could be said of CAML and its obscurity.
let rec fact = function | 0 -> 1 | n -> n * fact (n - 1);;
There is a little more syntax to learn in caml, but the suppression of 90% of the parenthesis makes the code far easier to read.
http://img1.imagilive.com/0413/scheme-fact.png
You could even simplify it a little by getting rid of the lambda:
http://img1.imagilive.com/0413/scheme-fact2.png
In any case, I find toy examples like this less than convincing. In real-world programs, issues of style, design, and documentation usually trump most anything else, as far as clarity is concerned.
Also, I personally find the penchant for one-letter variable names in the OCaml/SML/Haskell world to be very confusing and obfuscating.
The Scheme way is to be more verbose and explicit. For me, that results in much greater clarity -- especially when looking at unfamiliar code or code that you've stepped away from for a few months.
Of course, there also such a thing as being too verbose and explicit. But for me, Scheme is in the sweet spot between verbosity and terseness.
factorial n = product [1..n]Java, Python, Ruby, and Clojure will seem outdated just like C++ seems outdated now (not that it doesn't have its uses).
I have some professional experience in rewriting Python and Ruby programmes in Haskell. I make the same amount of stupid mistakes in Python as in Haskell. But whereas Python blows up at runtime / test time, in Haskell it's the compiler yelling at me. The nice thing: that's much faster to detect, and also saves me writing about half the tests.
Don't get me wrong, dynamic typing beats inane static typing like C's or Java's. But good static typing beats dynamic typing.
I like the final result of safety, and how whole classes of bugs are excluded once I get my OCaml program to compile. But the process of getting my program to compile in the first place is pretty painful and not fun.
Then again, writing endless unit tests in a dynamically typed language like Scheme is not much fun either. But I don't have to write the unit tests until I've written some functional portion of my program (or even the whole thing) and am satisfied with its design and how it works. Then I could add unit tests or even rewrite it in a safe language like OCaml, if I wanted to.
As I said elsewhere in this thread, for fast prototyping and sheer pleasure of programming, I find Scheme very hard to beat.
On the Scheme side of things, I've heard that the newish (4.8.0 and up) versions of Chicken can perform flow analysis to catch some type errors at compile time, and optimize based on types.
There's also Typed Racket, and Chicken has a contracts egg that allows procedures to have pre- and post- conditions.
For some years now, I've heard predictions that in the future languages will allow their users to "dial up" or "dial down" safety features on demand. I guess the above features of Scheme and Haskell are some early steps along that path. We live in interesting times.
-XTypeHoles will be in GHC 7.8: http://www.haskell.org/haskellwiki/GHC/TypeHoles
Static typing has its place in some people's hearts, and I respect that, but saying that dynamic typing has been outdated since the 80s is (1) trolling, and (2) happens to also just be, like, your opinion, man.
Oh, and please excuse my snarky tone. Your ancestor comment seemed to ask for it. Yes, they are, even now, languages around that are even worse. But better ways have been around for ages. A similar example is garbage collection: It, too, has been around since basically the dawn of programming languages, but only made serious inroads into the mainstream in the last decades.
The value of 3 / x changing depending on whether I pass 2 or 2.0 is the trade-off of the Python approach, and I honestly don't know which I prefer.
Additionally when doing big projects where the team does not care for unit testing, dynamic typing can turn out to be a big problem.
Having said this, it has its places, I do use dynamic languages a lot, just not in big enterprise projects.
I prefer Scheme by far to any other language I've ever used (which includes a whole bunch of languages not listed above).
For me, Scheme is much more fun to program in than OCaml, etc. With OCaml I found myself constantly wrestling with the compiler to get my program to compile, and had problems decyphring its obscure error messages, which seemed to require taking university-level courses on type theory in order to be understandable.
With Scheme, my programs mostly "just work", and I can program the way I think.
Some people have problems with Scheme's parenthesis, but I personally quickly learned to love them because they make scope explicit and obvious. Through long and bitter experience, I've learned to value explicitness and clarity in programs above almost everything else. Scheme is great for that.
True, Scheme might not be as safe as OCaml and friends, but for ease of programming, speed of development, and sheer pleasure, I find it very hard to beat.
https://curiousprogrammer.wordpress.com/2006/12/08/pattern-m...
http://www.javaist.com/blog/2008/11/12/pattern-matching-in-s...
http://wiki.call-cc.org/eggref/3/pmatch
http://wiki.call-cc.org/man/3/Pattern%20matching.html
http://www.ccs.neu.edu/home/samth/match-ifl-full.pdf
http://download.plt-scheme.org/doc/203/html/mzlib/mzlib-Z-H-...
To this day, this is why I value a good theoretical CS education, why I value university education, and why I continue to look back on and use my supposedly theoretical and impractical CS education with great respect.
This is so true: "learning another programming language isn't a big deal; it's a chore for a weekend. I tell my students, 'the language in which you'll spend most of your working life hasn't been invented yet, so we can't teach it to you. Instead we have to give you the skills you need to learn new languages as they appear.'" Can you imagine how valuable it was to be told that from the start?
He's right about scheme too: part of the value of using Scheme or Lisp is its inherent crazy unfamiliarity to the great majority of students. The first thing when you see all those parentheses and weird paradigms is "woah, this is unlike anything I've seen before." And that's perfect. You don't get lost in things you think you already know—you learn concepts fresh and the language, because it's so weird and wild and totally abstract and you can't imagine using it for any real project—is as malleable and temporary as modeling clay. You get to make things with it that teach you about art, and how to look at things, how to see infinity—not about the properties of the materials in your hands.
For this reason among others, it's profoundly disappointing to me that Berkeley has switched their introductory language to Python. As great as it is, it's no Scheme, if only for the fact that its popularity and usefulness as a language detracts from the underlying concepts. I have to think Brian Harvey fought this change, had he not retired and lost some influence.
"Every five years or so, someone on the faculty suggests that our first course should use language X instead; each time, I say "when someone writes the best computer science book in the world using language X, that'll be fine.'"
SICP was, in retrospect, a masterpiece of education. Someone sat down and thought about exactly these concepts and how best to elucidate them without getting in the way of the connections being made. The new trend toward applications-focused education feels to me like the wrong direction, and I don't think I would get as good an education today as I did learning abstract concepts theoretical computer science taught as the most important part.
Sure, it's fun and attractive to think about applying what you learn to the revolution at hand quickly, making mobile apps and designing robots and putting everything together into useful applications, but you can learn all that stuff after a couple semesters of awesome CS core theory anyway. And while you might get frustrated for those 2 years as an 18-year-old hotshot upstart startup-minded student, in 10 years you'll look back on it and think, "wow, that really was the most important part."
This is the type of approach that is more appropriate to a Technical College than a major University. This new approach almost seems like teaching civil engineers how to weld and rivet in order to build bridges, rather than deeply understanding the mathematical theory behind stress and vectors.
The intro courses, while in Python, still use many of the concepts and text of SICP, so it's not all gone. Many of the concepts translate well, and it's not the end of the world or even a slippery slope—I think that would be overreacting.
There's nothing fundamentally wrong with using a newer and more useful language to teach these concepts—after all, as Harvey always said, the language doesn't really matter. However, it's conceding to rationality just slightly, and you're right, a University, especially Berkeley in my mind, is a place where you're free to learn concepts and think theoretically without needing to find a real-world application for at least a couple years. They should keep that as a core value, and I certainly hope they do even as they use more modern languages.
Nowadays they're using Python.
I'm very disappointed I didn't have a chance to study that course. I read the book last year and did some exercises by my own. I never had so much fun with any CS book than I had with SICP.
No one cares about getting an education. They just want a job.
Most people are going to college hoping to get a job. They're learning because they're told they have to learn, so they do a bad job learning. In a field like civil engineering, you can't graduate unless you pass classes that are simply unpassable without learning some stuff. (I have a friend going through aerodynamics right now and I'm hearing about everything he's learning.)
This is kind of a microcosmic version of what we're seeing in general: we see people as workers first and human beings second. The universities and the kids are following suit.
Then we created secondary/"grammar" schools. The children who attended them surpassed their peers, who had only attended elementary school. Employers began to require a secondary-school education as a signal of competence. Eventually, being such a "universal good", secondary education became a public service of the state.
Then we created universities...
---
Although the inductive step is valid, there's a problem in the assumptions: we already had universities for thousands of years before the introduction of elementary or secondary education!
The traditional "liberal education" of The University, where the upper-class and the cunning go to cloister themselves with one-another and thus boost their mutual productivity in all sorts of status-signalling arts (sounds sort of like TED, doesn't it?) has come crashing head-first into the rising bar of minimum-expected human competence. Success in secondary school no longer tells you anything about a person's class or cunning, and that's forced employers to look for increasingly-lofty-and-meaningless trust-signals. So "everyone who's anyone" expects to go to university now, from the spoilt valley-girl to the farm bumpkin.
Perhaps, in the end, if we want to preserve the "usefulness" of university, we'll chop off the undergraduate portion of it and call that "tertiary school" or something. Everyone gets to go, it occurs at community colleges, probably most of the material comes from Khan Academy and the like. Then the rich and the cunning can go to The University after that.
I'm really not sure who you're addressing. No one is claiming these assumptions.
Internal vs. external motivation? Maybe some day, when programming is no more needed for anything useful, it can really flourish as an art. Like painting, when its principal real-world reason-to-be was supplanted by photographing. E.g. I don't understand the obsession of quest to invent always _more and more_ optimal algorithms, because often the less optimal ones are more interesting and elegant.
However, I recall that a little later some MIT graduate students started teaching their own version of the classic SICP-based course. I can't seem to find a link to it now, unfortunately. I wonder how that turned out, and if they're still teaching it now.
http://www-inst.eecs.berkeley.edu/~cs61a/sp13/projects/schem...
http://www.cs.uchicago.edu/courses/description/CMSC/10500/99...
On a personal note, I learned using SICP up at Northwestern, but I'd be hard-pressed to justify it to a non-engineering school. Much of the math used in it hits harder on the engineering-style calculus (compute all the things!) than a more discrete math-y style that would be more appropriate for CS programs with a closer affinity to a math department (or schools like the UofC, which does not have an engineering program at all).
Five years later or so, the great teacher that ran the CS intro course quit, someone else took over, and switched to Java. Typical. :-/
> a fairly normal dynamic language
You call this a "fairly normal dynamic language"?
0 == '' // true
0 == '0' // true
'' == '0' // false
Don't worry if the last few parts don't make too much sense.. I went back and forth between the two quite a lot
Maybe the humor was just lost on me...
Catering to the things that 18-year-olds want has never really gotten us far in society.
I like the language, but I'm simultaneously disgusted by it.
As an example, I don't think Python's “there's only one way to do it”-approach would have a chance of surviving if the language was as expressive as Scala.
In the end, as long as Scala stays simpler than Java 8 and vastly simpler than F#, C# and C++, it's good enough for me.
I believe this observation is a bit misleading. Indeed, Scala does offer some alternatives, but these are helpful in the transition from other languages with less powerful type systems. Idiomatic Scala is not really a hodge-podge of choices.
The ones prior to 2010~2011 used scheme, and it tracks SICP fairly closely.
http://webcast.berkeley.edu/playlist#c,s,Fall_2010,EC6D76F0C...
Take it slowly, don't be discouraged if it takes you hours to get something concept, and DO THE EXERCISES.
It's a timeless course.
"And, once there [writing only code that matters], you are able to achieve a very high degree of focus, such as you would when playing Go, or playing a musical instrument, or meditating. And then, as with those activities, there can be a feeling of elation that accompanies that mental state of focus."