I took 6.001 in 1999 (I think). Hal Abelson taught it along with a professor who took off his sweatshirt to reveal a Microsoft tee at his final lecture (he went to Microsoft).
What was great about Scheme (Lisp) is that most programs are basically words from your vocabulary, parentheses, and cars and cdrs. With procedural languages, there is always a sense that the language provides all the tools, and the magic happens somewhere underneath the hood. But with Scheme it feels as if it's happening right before you. It makes you feel like a wizard, and not a monkey. And it requires knowing all the spells. It requires knowing how to make magic happen. Or not. Once you know none of it's magic. But that's the point!
Python is arguably easier and more practical for both science and work. It's already popular on the web server, and is used everywhere else -- unlike Scheme.
But the recent resurgence of functional programming is super exciting with Elixir and Elm and the like.
I'm looking forward to building my next project using Elixir.
My favorite thing having finally taken a dive into lisp and SICP, is not that it is very friendly to functional. It is that it is very friendly to showing how it all works.
My favorite section is where they go over making a constraint based system that will either calculate degrees F or degrees C. Or validate that the two given values are accurate. All depending on what you have entered. And this is done from the ground up. No hidden magic of the system has to support you, by and large. (Not strictly true, as this does make use of GC and such throughout.)
I think there's a tension between two imperatives in teaching new programmers:
1) Learning must be applied learning. Give people problems to solve and they will come to you for data structures and algorithms, O notation, etc. If they don't, they should do something else
2) A lot of what's out there in programming languages are cargo cults, and newbies need to be prepared for this. For instance, virtual function inheritance isn't a thing. It's a weird call chain pipeline system glued into your vtable, which C++/Java teaching also won't bother to tell you exists. Make people start from assembly, graduate to C, then write their OWN vtable, so it's demystified. Now you've reduced the ability of software designers to piss on your leg and tell you it's raining.
So ideally I'd want students (at first) to be doing something either close to the machine or in the functional model. As they say though, the imperative of 1) means getting people to actually produce something, which is easier in Python.
My problem with this sort of bottom-up approach to learning how to program is that what seems "fundamental" from one point of view always turns out to be an abstraction built on an even lower-level foundation.
So, virtual functions aren't real because they're just vtables implemented in C. But C isn't real because it's just fancy assembly language. But assembly language isn't real because it's just fancy machine language. But machine language isn't real because it's just 0's and 1's zipping around the hardware. So I have to learn how integrated circuits work before learning how to program? No.
Bottom-up knowledge is important for understanding performance and other trade-offs. However, there's also a lot of benefit in learning how to program in a formal system without knowing much about how that system is implemented under the covers. If I was teaching an intro programming course to undergrads in 2017, I'd be strongly inclined to teach them a clean functional language first (e.g. Elixir, F#, etc.), and only introduce gory details like pointers and memory allocation later on.
While I think that most CS people should learn assembly and computer internals basics, it would be an absolute disaster to start students off in assembly as CS 101.
Python is a fairly decent language for starting people off:
* It doesn't have a lot of boilerplate, so no magic "I'll teach you what this means in three weeks" steps
* Output for debugging is fairly easy, since print accepts a lot of stuff without needing to muck with formatting strings
* Assignment is a statement, not an expression. You can't say "if x = 3" by accident
* Python is one of the major programming languages, so you're teaching students something that is pretty much guaranteed to be useful for them.
Another approach is to introduce newcomers to programming with a single course that: 1) uses Python to teach general programming, 2) uses JS to show how to write code that runs in a browser, and 3) demonstrates low-level programming patterns using C.
This is essentially what CS50 at Harvard does, and it seems to work well. Once a student has been exposed to these 3 languages, subsequent courses can explain how a computer works and introduce new paradigms (FP, LP).
I'm not sure new programmers need to worry about how virtual function inheritance is implemented via the viable. Are there even standards for that? Or is that an implementation detail which seems popular across multiple compilers?
There's time for them to learn the details, but just learning that the functionality exists and knowing how to use it is a good start.
One of the key things about SICP in Scheme was that the language used so few intrinsic keywords and structures (I think it was something like 7 intrinsic keywords that could be used for just about everything you needed to do) that you could move on from learning about the language really quickly.
It kept the focus on the underlying principles (every programming language is a set of primitives, a means of combination and a means of abstraction; recursion; interpreters; etc) that were powerful enough to let you pick up any other language without getting bogged down in the details. An opinionated language like Python seems like the wrong choice to teach fundamental structure (it WAS Structure and Interpretation of Computer Programs), but if they aren't approaching it from that angle and are looking more at application development then that's probably ok.
You can pick up enough of any language or framework from the manual, and google/stackoverflow/o'reilly will give you fine points/quirks, but that fundamental base that allows you to look at ANY program in ANY language and be able to reduce it to first principles is (IMO) a necessary component of any computer scientist's toolkit and the best insurance against the continuous rise of packaged software that is continuously burning the short grass in most software development.
I remember reading somewhere that focusing on application development is like training blacksmiths: you end up with people skilled at specific techniques but extremely vulnerable to "industrial" software that replicates the techniques and eliminates the need for custom development.
There are not that many blacksmiths left, and the truth is in 50 years there won't be that many application developers left either.
Berkeley made the same switch at around the same time, and it made me sad.
Having done the intro course in Scheme, I'd say it helped me understand functional programming far more than I ever could have with Python, and it opened me up to different ways of thinking.
Even though I never again used any Lisp variant, I'm still really glad I learned it and feel that what I learned using Lisp has informed my future decisions.
The switch occurred while I was at Berkeley and it also made me sad. I loved that course so much I decided to TA for the self-paced version which kept SICP and Scheme.
Brian Harvey explained the decision to switch here:
"But, as I keep saying, the choice of programming language isn't the main point. I get upset when students, even the students who like 61A, refer to it as "the Scheme course." It's not a course about Scheme! It's a course about programming paradigms. MIT, where SICP was written, no longer includes that course in its lower division core sequence, not because they wanted to change programming languages, but because they changed the entire sequence from courses organized around big groups of ideas to courses organized around application areas: first "let's build and program a robot" and then "let's build and program a cell phone." That's a brave and thoroughgoing attempt to, among other things, attract non-nerds to computer science. To say, as some people do here, "MIT switched from Scheme to Python" completely misses the point of what MIT did; nobody is proposing any change half as profound at Berkeley." [1]
61A gave me my entire background to programming and computer science. I had never programmed a computer before, and I think I was better for it.
The common phrase was that you should be made to take 61A as your first class and as your last. You really dont fully comprehend it until you get wider exposure, but you need that initial exposure so your brain can begin to knit things together as you see them.
I liked Sussman's answer. There is a huge difference in learning things deeply from the bottom up vs. 'get stuff done' approaches using lots of black box libraries, etc.
I have been using Ruby, Java, Scala, Python, and Haskell mostly for years now. But just recently I started working on the 4th edition of my old Common Lisp book and some preparatory work on a new Scheme book. I have been enjoying the Lisp-way of bottom up interactive development a lot.
Both general approaches have value. When doing machine learning it is great to have the universe of useful libraries for Python but for green field work that is more algorithmic, doing bottom up development in languages like Scheme or Haskell is also great.
At UBC CS a few years ago they made a switch in the opposite direction, from Java to Racket for their intro course. I think this was a very good decision because it allowed them to spend less time teaching syntax (which in racket is very simple) and more time focusing on fundamental topics such as graphs, recursion, functional programming, and test driven development. Compared to the equivalent intro programming course that was taught to engineers in C I think students in CS learned a lot more than the engineers whos most complicated curriculum involved arrays and procedure calls. What's interesting is that I believe the inspiration for teaching functional programming as an introduction came from MIT.
The sheer amount of nonsensical boilerplate required in any Java program, even trivial ones, makes it a terrible language for teaching Computer Science.
Think about trying to teach the meaning of "public class Foo { public static void main(String[] args) { ... }}" to a complete novice. Class-based design, inheritance, visibility, return types, arrays, etc. all right off the bat. It's too much.
Scheme and Python both are much better choices for this alone.
One point of learning these is to learn the ability to learn new languages on your own.
I would have a semester teaching several "toy" languages in different paradigms: perhaps some kind of lisp, some kind of prolog, and some procedural language, followed by a second semester where students choose the language they want to learn, and they learn it by themselves.
"And why Python, then? Well, said Sussman, it probably just had a library already implemented for the robotics interface, that was all."
That, right there, is the reason why I end up using Python so often.
As dynamic languages go, Python is not the best for anything, but it's good enough for almost everything, and there's probably already a library implemented for it.
Well, that tells us something about you. But it doesn't exactly get to the heart of why people like writing libraries for Python.
My theory: it was the first language to take a human factors approach to language design. Not the best, but the first. This design philosophy has the simple consequence that Python programs are by and large incredibly easy to read, understand, and modify, compared to its contemporaries. "Network effects" did the rest.
For all those fondly recalling learning Scheme first, allow me to provide the opposite perspective (kind of).
Learning Scheme as my first language scared me away from programming for years. Yes, solutions to problems were often elegant and puzzle-like, but accordingly, the tools and patterns often felt constrained and roundabout. For example, consider recursive patterns vs conventional looping patterns.
In that class I often felt I wasn't learning a 'real' production programming language, but rather a language designed to teach me programming concepts.
To that point, I think Python offers a much more robust and straight forward tool set, while also being friendly enough for the young developer to sink their teeth into.
However, in retrospect I was just a bratty kid, who was learning a lot of valuable fundamentals. I'd like to think some of those have stuck with me to this day, esp. as functional patterns have come into vogue.
Eh. If you stick to software development you have the rest of your life to poke at non-ideal systems. I still have fond memories of learning Scheme and realizing that programming (specifically computationally dissecting a problem) could be a ton of fun.
this was posted here a few weeks ago but for posterity [1][2] is an HTML5 and EPUB3 version of SICP with 'SVGs, mathematical markup with MathML and MathJax, embedded web fonts, and syntax highlighting'. there's a PDF version[3] from the same author with decent typesetting.
additionally I came across [4], SICP in an interactive textbook form with editable code fragments.
Could it be, however, that there is a need for introductory courses at university for those not quite at the level for SICP yet? I've worked as a web developer for years and can barely follow most of that text. If intro CS courses are provided in a more accessible format, more people will get interested and stick with it in the first place. There's always room for more advanced courses. I think that should be the goal of most universities.
We used scheme in my programming languages course (which was one of my last course before graduation). at first I hated it, but then once I got it, it was fun! functional programming forces you to think in a way that is much more conducive to understanding programming on a deeper level and thinking creatively to problem solve. Imperative programming, while easier, is more of a blunt instrument. Efficient, but blunt.
Functional programming is an attempt to pretend that Von Neumann machines are abstract, mystical mathematical engines, rather than a bunch of registers that read in values from an electronic grid, mutate them, and write out new values back to the grid.
Berkeley EECS is MIT-lite and its 61A used SICP/Scheme. They even wanted us to use emacs (which for me, so wasn't gonna happen). So pretty much everything in this article applies to Berkeley EECS as well. They've also shifted from SICP/Scheme to Composing Programs/Python.
The last time I used Scheme was in 61A. I like Scheme; it was elegant. I probably would have continued to use it but Instructional Computing had a bastardized variation. I'm pretty sure that students of 61A will continue to use Python since they're using Python 3.
Funny, I was present when this conversation took place. Hearing Gerry Sussman talk was truly inspiring. However, I would somewhat disagree. For sure, the way we program in day to day work has changed, and the curriculum should also touch that. However I think, learning the very fundamentals of computation is essential for a proper system understanding. SICP provides a great way of doing that and the choice of scheme as a minimal, yet powerful language fits to that. I can only recommend everyone to at least read through this great book.
Pretty sad honestly. We used SICP and Scheme in the first computer science class I ever took and that is the most fun that I ever had programming. I remember I couldn't wait for new homework assignments to be released so that I could solve the fun puzzles.
This book(http://composingprograms.com/) is in Python and is based on SICP. I found it interesting enough to include it in my ever-growing to-read list, worth checking out.
I hope they take a look a pyret, language designed by a team of CS teachers from Brown. They have many good points on the value of pyret above scheme. Somehow a more formal view on programming (recursive ADT, tests), their students are learning fast with it.
I think SISP is an awesome book, but I don't see why it has to be Scheme, at least for the first half of the book. Let's not be too dogmatic about our shovels. A shovel is a shovel.
BTW, since this site isn't super mobile-friendly, I made a modible friendly version a while back: http://ivanistheone.github.io/SICPapp/ (only first two chapters)
The Metacircular Evaluator should be a prime example of why Scheme matters. It completely loses focus into a mess of parsing and loses the idea that code and data are the same thing. Also that whole tail-recursion thing is kind of important.
[+] [-] unabst|9 years ago|reply
What was great about Scheme (Lisp) is that most programs are basically words from your vocabulary, parentheses, and cars and cdrs. With procedural languages, there is always a sense that the language provides all the tools, and the magic happens somewhere underneath the hood. But with Scheme it feels as if it's happening right before you. It makes you feel like a wizard, and not a monkey. And it requires knowing all the spells. It requires knowing how to make magic happen. Or not. Once you know none of it's magic. But that's the point!
Python is arguably easier and more practical for both science and work. It's already popular on the web server, and is used everywhere else -- unlike Scheme.
But the recent resurgence of functional programming is super exciting with Elixir and Elm and the like.
I'm looking forward to building my next project using Elixir.
Here is the classic course: https://ocw.mit.edu/courses/electrical-engineering-and-compu...
Original video lecture on YouTube (linked from above): https://www.youtube.com/watch?v=2Op3QLzMgSY
[+] [-] taeric|9 years ago|reply
My favorite section is where they go over making a constraint based system that will either calculate degrees F or degrees C. Or validate that the two given values are accurate. All depending on what you have entered. And this is done from the ground up. No hidden magic of the system has to support you, by and large. (Not strictly true, as this does make use of GC and such throughout.)
If you hadn't seen it, https://www.infoq.com/presentations/We-Really-Dont-Know-How-... is a great video showing Sussman's style. He also showcases a program they wrote that could solve circuits based on this general idea.
[+] [-] kough|9 years ago|reply
By far the most rewarding class I've taken at MIT. Check out the psets, they're pretty fun.
[+] [-] brians|9 years ago|reply
[+] [-] evdev|9 years ago|reply
1) Learning must be applied learning. Give people problems to solve and they will come to you for data structures and algorithms, O notation, etc. If they don't, they should do something else
2) A lot of what's out there in programming languages are cargo cults, and newbies need to be prepared for this. For instance, virtual function inheritance isn't a thing. It's a weird call chain pipeline system glued into your vtable, which C++/Java teaching also won't bother to tell you exists. Make people start from assembly, graduate to C, then write their OWN vtable, so it's demystified. Now you've reduced the ability of software designers to piss on your leg and tell you it's raining.
So ideally I'd want students (at first) to be doing something either close to the machine or in the functional model. As they say though, the imperative of 1) means getting people to actually produce something, which is easier in Python.
[+] [-] brianberns|9 years ago|reply
So, virtual functions aren't real because they're just vtables implemented in C. But C isn't real because it's just fancy assembly language. But assembly language isn't real because it's just fancy machine language. But machine language isn't real because it's just 0's and 1's zipping around the hardware. So I have to learn how integrated circuits work before learning how to program? No.
Bottom-up knowledge is important for understanding performance and other trade-offs. However, there's also a lot of benefit in learning how to program in a formal system without knowing much about how that system is implemented under the covers. If I was teaching an intro programming course to undergrads in 2017, I'd be strongly inclined to teach them a clean functional language first (e.g. Elixir, F#, etc.), and only introduce gory details like pointers and memory allocation later on.
[+] [-] jcranmer|9 years ago|reply
Python is a fairly decent language for starting people off:
* It doesn't have a lot of boilerplate, so no magic "I'll teach you what this means in three weeks" steps
* Output for debugging is fairly easy, since print accepts a lot of stuff without needing to muck with formatting strings
* Assignment is a statement, not an expression. You can't say "if x = 3" by accident
* Python is one of the major programming languages, so you're teaching students something that is pretty much guaranteed to be useful for them.
[+] [-] Cyph0n|9 years ago|reply
This is essentially what CS50 at Harvard does, and it seems to work well. Once a student has been exposed to these 3 languages, subsequent courses can explain how a computer works and introduce new paradigms (FP, LP).
[+] [-] metaobject|9 years ago|reply
There's time for them to learn the details, but just learning that the functionality exists and knowing how to use it is a good start.
[+] [-] agumonkey|9 years ago|reply
Inductive logic and the functional paradigm maps onto all of these. And allows for more diverse abstractions without lying either.
[+] [-] fomojola|9 years ago|reply
It kept the focus on the underlying principles (every programming language is a set of primitives, a means of combination and a means of abstraction; recursion; interpreters; etc) that were powerful enough to let you pick up any other language without getting bogged down in the details. An opinionated language like Python seems like the wrong choice to teach fundamental structure (it WAS Structure and Interpretation of Computer Programs), but if they aren't approaching it from that angle and are looking more at application development then that's probably ok.
You can pick up enough of any language or framework from the manual, and google/stackoverflow/o'reilly will give you fine points/quirks, but that fundamental base that allows you to look at ANY program in ANY language and be able to reduce it to first principles is (IMO) a necessary component of any computer scientist's toolkit and the best insurance against the continuous rise of packaged software that is continuously burning the short grass in most software development.
I remember reading somewhere that focusing on application development is like training blacksmiths: you end up with people skilled at specific techniques but extremely vulnerable to "industrial" software that replicates the techniques and eliminates the need for custom development.
There are not that many blacksmiths left, and the truth is in 50 years there won't be that many application developers left either.
[+] [-] wuschel|9 years ago|reply
I like your comment, but the crystal ball statement in the last sentence is a bit too much.
[+] [-] jedberg|9 years ago|reply
Having done the intro course in Scheme, I'd say it helped me understand functional programming far more than I ever could have with Python, and it opened me up to different ways of thinking.
Even though I never again used any Lisp variant, I'm still really glad I learned it and feel that what I learned using Lisp has informed my future decisions.
[+] [-] tmccrmck|9 years ago|reply
Brian Harvey explained the decision to switch here:
"But, as I keep saying, the choice of programming language isn't the main point. I get upset when students, even the students who like 61A, refer to it as "the Scheme course." It's not a course about Scheme! It's a course about programming paradigms. MIT, where SICP was written, no longer includes that course in its lower division core sequence, not because they wanted to change programming languages, but because they changed the entire sequence from courses organized around big groups of ideas to courses organized around application areas: first "let's build and program a robot" and then "let's build and program a cell phone." That's a brave and thoroughgoing attempt to, among other things, attract non-nerds to computer science. To say, as some people do here, "MIT switched from Scheme to Python" completely misses the point of what MIT did; nobody is proposing any change half as profound at Berkeley." [1]
[1] https://people.eecs.berkeley.edu/~bh/61a.html
[+] [-] QML|9 years ago|reply
[1] http://cs61a.org/proj/scheme/
[+] [-] jnordwick|9 years ago|reply
The common phrase was that you should be made to take 61A as your first class and as your last. You really dont fully comprehend it until you get wider exposure, but you need that initial exposure so your brain can begin to knit things together as you see them.
Meta-Circular Evaluator RIP. You will be missed.
[+] [-] mark_l_watson|9 years ago|reply
I have been using Ruby, Java, Scala, Python, and Haskell mostly for years now. But just recently I started working on the 4th edition of my old Common Lisp book and some preparatory work on a new Scheme book. I have been enjoying the Lisp-way of bottom up interactive development a lot.
Both general approaches have value. When doing machine learning it is great to have the universe of useful libraries for Python but for green field work that is more algorithmic, doing bottom up development in languages like Scheme or Haskell is also great.
[+] [-] hiyou102|9 years ago|reply
[+] [-] wffurr|9 years ago|reply
Think about trying to teach the meaning of "public class Foo { public static void main(String[] args) { ... }}" to a complete novice. Class-based design, inheritance, visibility, return types, arrays, etc. all right off the bat. It's too much.
Scheme and Python both are much better choices for this alone.
[+] [-] jonnycomputer|9 years ago|reply
I would have a semester teaching several "toy" languages in different paradigms: perhaps some kind of lisp, some kind of prolog, and some procedural language, followed by a second semester where students choose the language they want to learn, and they learn it by themselves.
[+] [-] __Duncan__|9 years ago|reply
[+] [-] cs702|9 years ago|reply
That, right there, is the reason why I end up using Python so often.
As dynamic languages go, Python is not the best for anything, but it's good enough for almost everything, and there's probably already a library implemented for it.
[+] [-] dTal|9 years ago|reply
My theory: it was the first language to take a human factors approach to language design. Not the best, but the first. This design philosophy has the simple consequence that Python programs are by and large incredibly easy to read, understand, and modify, compared to its contemporaries. "Network effects" did the rest.
[+] [-] zumu|9 years ago|reply
Learning Scheme as my first language scared me away from programming for years. Yes, solutions to problems were often elegant and puzzle-like, but accordingly, the tools and patterns often felt constrained and roundabout. For example, consider recursive patterns vs conventional looping patterns.
In that class I often felt I wasn't learning a 'real' production programming language, but rather a language designed to teach me programming concepts.
To that point, I think Python offers a much more robust and straight forward tool set, while also being friendly enough for the young developer to sink their teeth into.
However, in retrospect I was just a bratty kid, who was learning a lot of valuable fundamentals. I'd like to think some of those have stuck with me to this day, esp. as functional patterns have come into vogue.
[+] [-] ng12|9 years ago|reply
[+] [-] ironchief|9 years ago|reply
"The wizard book" is a great read and I recently starting flipping through it again.
PDF https://mitpress.mit.edu/sites/default/files/6515.pdf
HTML https://mitpress.mit.edu/sicp/full-text/book/book.html
[+] [-] irfansharif|9 years ago|reply
[1]: https://github.com/sarabander/sicp
[2]: http://sarabander.github.io/sicp/
[3]: https://github.com/sarabander/sicp-pdf
[4]: https://github.com/zodiac/isicp
[+] [-] aphextron|9 years ago|reply
[+] [-] teddyh|9 years ago|reply
http://www.neilvandyke.org/sicp-texi/
[+] [-] abecedarius|9 years ago|reply
[+] [-] alistproducer2|9 years ago|reply
[+] [-] charles-salvia|9 years ago|reply
[+] [-] CalChris|9 years ago|reply
http://cs61a.org/articles/about.html
The last time I used Scheme was in 61A. I like Scheme; it was elegant. I probably would have continued to use it but Instructional Computing had a bastardized variation. I'm pretty sure that students of 61A will continue to use Python since they're using Python 3.
[+] [-] _ph_|9 years ago|reply
[+] [-] nickbauman|9 years ago|reply
https://github.com/nickbauman/sicp/blob/master/src/section2_...
I loved the process. Scales fell from my eyes. I didn't get this with Python, even though I love that language too.
[+] [-] wolfgke|9 years ago|reply
> https://cemerick.com/2009/03/24/why-mit-now-uses-python-inst...
[+] [-] tpallarino|9 years ago|reply
[+] [-] abhirag|9 years ago|reply
[+] [-] agumonkey|9 years ago|reply
[+] [-] ivansavz|9 years ago|reply
For example, here is SICP with examples using the JavaScript shovel: https://www.comp.nus.edu.sg/~cs1101s/sicp/
BTW, since this site isn't super mobile-friendly, I made a modible friendly version a while back: http://ivanistheone.github.io/SICPapp/ (only first two chapters)
[+] [-] jnordwick|9 years ago|reply