If not SICP, then what? Maybe HTDP?
stevenrosenberg.net
stevenrosenberg.net
There is actually surprisingly little mathematics in SICP. What is does have are mechanisms that are then analysed and modelled, after which the mental model is adapted so it can be turned into computational model that is a faithful representation.
Some of the presented mechanisms are mathematical in nature, but you don't need a mathematical background any more than you need an economics background to write, say, a banking application.
"make it hard for me to learn the actual programming."
Depends on if you see "actual programming" as the mental discipline of correctly representing a part of the real world into a computational model.
If you see "actual programming" as typing in characters on a screen until they compile, then ship them and get absurd amounts of money for it, then sure, SICP might not be for you.
"without going too deep into the quirks of a single programming language"
SICP is not about scheme, has never been about scheme, will never be about scheme.
You will not emerge a "God of the Lisps" from SICP. It might, however, clue you in about what's actually happening when programming, in any language of choice.
Now SICP was for EE doing software. I suggest to everyone to learn EE, even partially, it's surprisingly useful to learn designing anything. It's still system design, state changes, but in a different substrate, and personally I found it very helpful (gives you a new appreciation for crude language like C).
There is an old SMBC comic highlighting this general issue in STEM where for some mysterious reason, mathematical theories that took at least a few scientific generations to figure out, with lots of bitter fighting among the giants of science about which conclusion we should accept as correct, are now being taught as if they are trivial to reproduce and come up with for bachelor students.
As a physics drop-out, I felt really relieved when I read that, in a "oh so it's not just me"-sense
Sounds interesting. Would like to watch it. Got a link?
They don't review all of it, but you can get a few pages read
https://archive.org/search.php?query=maxwell%2C+james+clerk&...
The original author has to persuade people, and convince people who aren't familiar with them. The "pedagogical" author later is in a more clear position of authority and doesn't need to work as hard.
Or perhaps: The "pedagogical" author can assume that by the time of his writing, we live in a society where it is accepted that there is nothing mysterious about the material (e.g. imaginary numbers are nothing mysterious) and can concentrate on explaining the material in the best possible way.
The problem is that many students come from a background where they were taught a deeply anti-scientific attitude.
EDIT: To put it more concisely: It is a different job to convince someone of a scientific result (here the other side is distrusting) than to teach it (here the other side gives you credit of trust (but a lack of understanding) and you have to teach them so that they understand it). Unluckily many students who attend lectures have an attitude where they need to be convinced instead of taught.
Isn't this backwards? If you're just accepting the lecturer's word as dogma, I would argue you're not really gaining an education at all. The process of being convinced and having doubts about the material resolved improves critical thinking and improves understanding of the underlying material as well.
Maybe I think differently from you because I come from Germany. But I don't think this is backwards. I openly admit that I cannot stand "critical thinking" gospel.
Before you can start thinking critically, you have to understand the material that is there (that you want to criticize). Explaining the material so that you hopefully understand it is the role of the lecturer/teaching assistent. Why are you enrolled in the degree course if you are critical of it instead of wanting to learn the material? So one can assume that the students want to learn the material.
Maybe you want to learn why it is true?
Since Euclid, mathematics is about proof i.e. being convinced. If you really understand the material, you see it must be true - and need not blindly accept it.
What is taught in high school and many university courses is not mathematics, but how to use it. Like how to use Word, not how to write Word.
When you understand something, it becomes yours. You remember it longer, and can adjust and generalize it.
Unfortunately, it can be many times as much work to understand some mathematics, even some from early high school, and requires higher mathematics. So you can't understand til after you've understood it... It makes sense mathematics is taught the way it is... especially when most people are users, anyway.
But bad luck for those who need to understand and be convinced, which was so important to the developers of mathematics. i.e. mathematics filters out mathematicians.
> Since Euclid, mathematics is about proof i.e. being convinced. If you really understand the material, you see it must be true - and need not blindly accept it.
I agree. Learning mathematics means learning the proofs. This is pure learning and has nothing to do with critical thinking (at least to me and I am a mathematician).
To me, an essential part of a proof is checking that it is correct yourself... as opposed to "learning" it i.e. taking it on faith, believing it is correct because someone said it was. (Of course, in practice you can't verify everything yourself... but nonetheless that's the idea of mathematics, in theory).
Is that not the purest form of critical thinking?
OTOH I suppose when a proof uses a clever change in perspective, to show that it must be true (such as non-constructive proofs), it refutes many possible objections without ezplicitly considering them. So formulating those objections (or "criticisms") isn't needed.
Please keep in mind that you therefore have an inevitable non-zero amount of survivor bias there, and may have some trouble seeing why everyone else had trouble with the material.
Less than entirely helpful if you wanted to use it.
In a lot of ways it felt like solving crossword puzzles for a grade with a timer ticking down. Frequently I'd spend the most of the test with no idea what to do, and then about 20 minutes before time was up, I'd have an insight and I'd spend the last 15 minutes furiously racing to write it all down.
This worked out well and I ended up with a 4.0 program GPA, but I was a wreck every test day--I was always convinced that this was the day I'd fail to have that last minute epiphany.
I was always looking for a more systematic approach, but I never found one. In the end I still don't know if the problem was me or the tests.
Newton was something else, but still: he had acquired a vast amount of knowledge and insight upon which he built his new theorems.
Meanwhile, experts are notoriously good at forgetting what it is like to not understand something yet, so when explaining things they subconsciously presume more a priori knowledge than is appropriate.
I ended up being a programmer but I graduated with an Electrical Engineering degree.
What's interesting is that I generally don't recall fundamental physics or applied coursed having this attitude, i.e. nobody expects students to understand theories without proper context set up. Physics is generally taught from experiments.
I believe math is mostly guilty here :-) For some reason most of school math is taught as a bunch of soulless abstract sybmol manipulation. No proofs, no reasoning, pure memory-based excersises.
Then you come to a university and they just go on. Proofs-proofs-proofs, but with the same mechanical approach. No motivation, no context, just endless calculus variation.
Yes, this really showed how much information I can put into my memory. But I only started to get math many years and books later.
The Scheme aspect of SICP, and other decisions made by the authors, matter a lot because, contrary to what you seem to be claiming, there are many different approaches to and flavours of programming. There isn't a single core philosophy that, once imparted to students, "clues them in" to the essence of the cultures/styles/models deployed by Forth, Haskell, APL, Prologue, C etc.
One needs to learn how to take apart a problem and put it back together again in a way the computer understands - to get rid of all the ambiguities and phrase the solution in terms of conditionals and loops. When one starts to deal with bigger problems, one needs to learn the use of abstraction in order to deal with the added complexity.
This is the skill that makes somebody a real programmer, and it stays pretty much the same across languages. The differences between OOP, FP and all the rest pale in comparison to that first great lesson that needs to be learnt. (Having started off with Java, learning Lisp was a huge step for me that I really struggled with at first. But it still wasn't anywhere near as difficult as learning programming for the very first time.)
This is the skill that SICP tries to teach.
So far I have found that the Wizard Book always provides the required algorithm, or enough discussion to work it out.
Anyway, I absolutely agree SICP was never about Scheme per se, or even functional programming. Scheme is nice as a teaching tool because, as Sussman likes to say, you can teach everything you need students to know about the language in one lecture. (Not even all of Scheme, mind you, just what you'd use in a 1-semester course, which back when I took 6.001 meant R4RS minus macros and continuations.) There's certainly always been pressure to use more "practical" languages. But back in those days, there weren't the options there are now. Any derivative of C, especially C++, would end up being as much about the language as about programming concepts, if not more.
I think the thing about SICP is that while it makes some minimum demands about mathematical background, it makes a lot of demands about intellectual maturity. It took me years to appreciate many of the points it makes -- as I got more experience, different parts of the book start to resonate. On the other hand it's stayed relevant all these years, at least for me personally.
I'm reading the book now (and watching the lectures), and can't imagine trying to go through it as an undergrad.
All the famous CS people over say 60 started in physics or EE.
What? How can anyone do any meaningful engineering without calculus?
It strikes me that when someone says that, and my GSI said something very similar to that in section, it means that the book+course has failed to say what it is about, clearly, in a way the student will understand rather than misunderstand.
It's f'ing ineffable is not a good thing.
> we believe that the essential material to be addressed by a subject at this level is not the syntax of particular programming-language constructs...
The whole preface talks about how the aim of the book is to get students to think with a programmer's mindset. Scheme is only incidentally the language the consider best for the task, due to its near-absence of syntax.
https://mitpress.mit.edu/sites/default/files/sicp/full-text/...
Section 2.1 starts by building a data type of rational numbers, then extends it to interval arithmetic In section 2.4 this is extended to Complex numbers, which also adds the complication of multiple representations of a data type (rectangular vs polar). In section 2.5 these are unified with a generic arithmetic package. Which is finally extended to operate on symbolic polynomials, creating a symbolic algebra system.
So you can see, the authors complain about 'domain knowledge', but the example was surely chosen precisely because everyone already understands these relationships so well! It's a relatively nontrivial example, technically simple but structurally complex, that everyone already understands intuitively, so that you can get right to work thinking about data abstraction techniques - and in this example we go all the way from introducing the notion of an 'abstraction barrier' for the first time, to data-directed programming & message passing!
-----
The other mathematical section is 2.3, which is the infamous calculus section. Again the reaction is completely over the top - there's no 'deep dive', you don't need a 'solid foundation' in calculus, etc. The appearance of calculus is no more than implementing a couple of symbolic transformations of data, and all 4 of the rules are provided for you. You don't actually use calculus to do anything, so that if you don't know calculus, you can still write the program, it'll just be a bit more boring not knowing what it means. This section of the book is like 5 pages long, out of a 500 page book, but it's all we hear about...
Is that true for complex numbers?
Newton's method in the first chapter was a little rough for me, but after that it's much more about exploring ways of representing data. (At least so far... I'm almost through chapter 2).
I love physics but coding Newton-Raphson does not engage me.
(I had a similar reaction to particular Python book -- Roman numeral conversion? blah!)
Later on the Y-combinator is presented as computing the fixed point of an (finite) iteratively defined function - the fixed point returned is the full recursive function. Lastly when talking about programming languages, and interpreter computes a fixed point. The scheme language is the fixed point of the scheme meta-circular evaluator.
But it would be good to hint about it's relationship to later material.
Perhaps it's the timing/context; I had an very odd lecturer for numerical methods.
https://mitpress.mit.edu/sites/default/files/sicp/full-text/...
Unfortunately I couldn't find the material about interpreters - my memory of it is them discussing it in the lectures so perhaps it never actually made it in the book, or was only in the 1st edition. Those lectures are available on youtube if you want to find it.
When I say mathematical maturity, I mean the kind of basic “real” mathematics that is normally taught only at universities, specifically the idea of what a proof is, what one looks like, how to write one, how to read definitions, and some idea of how one might analyse a problem and work towards its solution.
For example, exercise 1.10 defines the Ackerman function and asks some questions about it. The Ackerman function does not fit the model of any function one might typically encounter in mathematics before this course, it’s definition is hard to reason about, and solving the exercise requires understanding certain cases of the Ackerman function (and not trying to figure it out all at once) and also having a good understanding of various mathematical operations (e.g. +, *, ^, which seems simple but spotting the pattern might not be so easy).
Exercise 1.13 is about proving a closed form for fib(n) which requires a reasonable amount of mathematics and no programming whatsoever. Thankfully the hint gives one some kind of clue as to how to solve it or I think many would find the mathematical bar too high.
Immediately following this is a chapter introducing orders of growth (big-O and friends) which is fine for anyone with a decent background in mathematics or computer science but one must remember that there is a difference between the abstract manipulation of symbols and vague graph-sketching one does in school (e.g. e^x is flat and then shoots up a bit past 0, x^2 shoots up either side of zero, x^3 goes up on the right and down on the left ...) and having a good understanding of how these functions behave and compare.
Exercise 1.19 essentially requires a careful and correct analysis of the Fibonacci sequence (thankfully there are lots of hints) to derive a logarithmic algorithm for computing fib(n). This is essentially the “matrix exponentiation method” except that the matrix is hidden in three variables. I think it is silly to say that all you need is to be able to understand arithmetic to solve these.
I think the book is fine for a course that happens after (or possibly concurrently with) a first course in real mathematics. It is probably less useful if one is lacking in the mathematical background required, and I think it is reasonable for people studying a “first course in computer science” to not have this mathematical background.
The closest thing I can find for good evidence is Fisler '14 [1], which did indeed suggest that HTDP teaches Functional Decomposition in such a way that CS1 students are better able to tackle short-but-complex problems by the end of their CS1. I find this work compelling, and I look forward to applying the ideas inherent to my own courses. However, in the decade-plus that HTDP has been around, I have not been able to find any long term studies that back up the slew of claims made about how we "should" teach CS1. Language and paradigm arguments in general have not really born out any evidence[2].
I'm not saying HTDP is bad or Python is good or C++ is ideal. I'm saying we don't know much about any of this stuff. Relying on theoretical arguments is dangerous when it comes to pedagogy. For every positive experience you can share about HTDP, I can share a negative experience. It's great if you found a curriculum that works for you. But be very, very careful about whether you believe that curriculum should work for everyone.
[1] https://dl.acm.org/citation.cfm?id=2632346
[2] https://www.researchgate.net/publication/329544316_Introduct...
Maybe it would be possible to determine which teaching approach works best for a student and individualize/personalize, rather than having a one-size-fits-all curriculum for everyone?
That was my takeaway from CS61A at Berkeley. I thought that Scheme was incredibly elegant and I was disappointed that we never used it again. The profs sure were pleased with themselves at the end of CS61A and I imagined later that they thought their preferred outcome would have been that we pursued a PhD using Jikes. SICP was the text which everyone bought and no one (that I knew) read and I tried. We had no assigned readings; it simply meant to be worshiped. It comes up on HN but never in conversation. No one quotes SICP.
I'll look at HTDP.
Those concepts were and remain a foundation for how I think about programming—at the level of elegant structure and short modular thinking. Software engineering and architecture is something different, and has its own class (CS169) which was far more valuable and important for those skills at that higher level.
I dunno. It was a good foundation. I've looked through SICP and I still recognize the concepts, the lectures matched it fairly well. But you're right—no one read the book.
> The curriculum is too artificial and disjoint from the rest of their CS degree
I would then argue the problem is the rest of the CS degree. Whether HTDP "works" or not, the principles espoused in the course are the same ones you'll encounter over and over again throughout your professional career. As far as I can tell, the only difference is the HTDP (and SICP) folks are introduced to them from day one while others learn through years of experience. And this is the problem about the CS101 course "working for everyone": does it work because you're only delaying the introduction to the difficult concepts endemic to software development? If a student can pass CS101 just by virtue of being able to string together a compilable C++ program, is that really for the best?
Anecdotally, I got a 2 on the CS AP test, which was enough to make me second-guess my major. Luckily, I went to an HTDP school where the professor assured me not to worry about it -- and sure enough, I aced the CS101 course and went on to have a successful career writing code.
I don't think that's really true. Yes, the HTDP community, and Felleisen in particular, write a lot about Pedagogy. But Mark and Mike have them beat handily. Thinking about the CS Ed blogs I read[1], I don't think any HTDP folks have that much compared to others.
I find SICP to be a mind-blowing book - a truly enlightening experience. But not, perhaps, entirely suited for beginners. I first started reading it four years ago, just over two years after I had started to teach myself programming in high school. Although I already found it interesting and its functional programming approach did have a lasting impact on my programming style, I recall finding it somewhat too challenging on the whole and didn't get very far. Half a year ago I started it again and have been blown away by the elegance and fundamental importance of the concepts it presents (although I'm still not done yet). For one thing, I understand the foundation of OOP a lot better now than I ever did from reading Java books...
So if the author is saying that SICP is a bad programming textbook because it doesn't include a "How to build a webapp in 12 easy steps", well, he rather missed the point. But if he is arguing that it perhaps isn't the most suitable textbook for a first year CS student fresh out of high school - that is a fair criticism.
That being said if I try to put myself back in 16 yo old me learning to code to write games for my calculator, I would've been incredibly frustrated by this book. The insights on the nature of programing constructs would've flown completely over my head and at the same time it wouldn't have given me the practical information I needed to get things done.
It's not too surprising that a book tailored to such a crowd's particular needs is not particularly suited to other students, whether less bright, less prepared, or simply true beginners to programming.
Then, PCs were not yet integrated in university teaching. It was still common for students to sketch out new software in pseudocode on paper before sitting down at a terminal they'd waited hours to get access to. And of course, editors were crude, IDEs nonexistent, and the compile-run-edit cycle often took 15 minutes or longer.
Programming was more deliberate, involving absolutely no cutting and pasteing. Coding then was much closer to writing a proof, which goes a long way to explaining why SICP put more emphasis in principles, formality, and derivation than we do today.
Supposedly those that did found SICP to be more challenging than those who didn't.
They may even come to the conclusion that programming is a
shallow activity and that what truly matters is an
understanding of domain knowledge
THE HORROR ;)In all seriousness, IMO we'd have much better programs if developers spent more time thinking about domain knowledge and less time believing that "programming" in isolation is the important part.
"The other side of this observation is that the professional never quite takes any problem as seriously as does the amateur. He has had bugs before, and he will have them again. This difference in attitude is a source of constant friction between the two types: the professional is very tired and a bit irritated by the unending stream of amateurs waving their printouts in his face and condemning the machine, the operator, the system, the keypuncher, the language, or the government. The amateur, on the other hand, can see that the professional does not even care that his means and standard deviations are not going to be ready in time for inclusion in the proceedings of the conference."
Gerald M. Weinberg, The Psychology of Computer Programming.
Some of the most horrendous, fragile, unmaintainable spaghetti code I've seen in my life was written by electronic engineers. And some of them were true masters of their crafts, it's not like they lacked the cognitive abilities to write good code, it's just that they didn't care at all, it just had to accomplish the function they needed. Meanwhile I'd see them spending a lot of time making sure things were routed nicely and PCBs looked nice.
As a software engineer, I find HtDP awesome. As a teacher, I found it lacking. I think the best way to teach programming is in the context of a domain of interest to the student. Problem is, you can't write an universally usable book like that.
I learned the downside to domain ignorance early in my career when a engineering manager confided to me, “It's eadier to teach an engineer to code, than teach a computer scientist engineering.” The same applies to biology, medicine, chemistry, culture, and many other domains where mastery of context is difficult yet essential.
And I've found those turn out to be the most interesting software jobs.
SICP is the foundation for people who want to be computer scientists. That’s not everyone.
But from what I’ve found, all the top CS schools create computer scientists, and the other CS schools create programmers. While it’s easy for a computer scientist to make the jump to programmer with just a little guidance, it’s much harder to go the other way.
The world mostly needs programmers though, with just a reletively few computer scientists to come up with the new innovations. So it seems like everything is working out ok.
Although I’m really glad I got to learn the fundamentals of computer science with a SICP based intro class.
I don't think it's actually that easy for a computer "scientist" to unlearn all the idealistic stuff that can actually be counter-productive in a real-world programming environment, particularly if they're enamored with languages like LISP or Haskell. These people easily get depressed in a "real" programming job.
Whether it's hard to go the other way doesn't really matter. There's no pressure to go the other way. The only healthy place for computer scientist types is academia, or maybe certain R&D positions. These are few and far between.
For actual jobs? I don't see any evidence for that.
Old joke: What do you call someone with a BS in archaeology?
A ditch digger.
I wonder how many people have actually sat down with a bunch of students and done a real experiment with textbooks. It's quite easy to think that a textbook is good when you already understand the material. Only by getting feedback from real students can you truly figure out whether a textbook is good. It'd be interesting to do a course with two different textbooks and the exact same professor and compare feedback/results. Perhaps they could even take the same final exam. Preferably at an average university. One problem with using textbooks written by MIT professors (such as Artin, Strang, etc.) is that MIT students are far stronger than average and can generally skip certain elided steps that other students cannot.
They are stronger at what?
Either they know things already or they don't. If they know things already then they can skip steps and if not then they can't or can use guesswork. And that's what any other human being will do.
(First google result, I didn’t verify further)
It is admittedly only a proxy, but the entrance SAT math scores for MIT students are 770 for the 25th percentile and 800 at the 75th percentile.
Put another way: the test that is a helpful differentiator of intellectual ability of the general college population is not a good differentiator for the MIT population because a large proportion max out the scale.
Lifting heavy books, of course.
That said though, let me say that for me personally SICP was mind-opening. I think about it a lot; it has had a major influence on me. An example is that I am working on a Theory of Computation book and I am trying to emulate some aspects of it (while keeping the presentation accessible). I certainly will admit, though, that when I read it I expect that I was in a different place than the post's author or than the typical student.
I also remember doing a course on functional programming (SML) when studying that did absolutely nothing for me.
You’re probably correct, you need to have mastered the mechanics of programming before having the brain capacity and experience to appreciate the finer details and subtleties of the craft.
I had a similar experience with karate training. When siting on the bench and watching my son train it looks rather straight forward, just remember to focus. Then after a term I decided to join the training and suddenly it feels like you have five arms to coordinate, and processing any verbal input from the sensei is just out of the question.
The problem is (also in my experience) that students often cannot grasp the depth of the textbook/topic when they here the lecture. I openly admit that I only could appreciate the depth of the topics taught in some math lectures 5-10 years later (but already at the time that I heard them, I loved hard lectures - in oppposite to many classmaters).
So if you want to get feedback, ask the students not before 5 to 10 years after they heard the lecture - otherwise the answers will in my opinion be meaningless.
Worst book ever. Ugh.
It's amazing anyone gets out alive.
This is the key!. I was about to say SICP was great then, yeah, I read it only when get interest in build compilers and after 20 years on the craft.
I think you need a progression on material:
1- Start with a highly practical book more alike build little experiments/programs
"Build a pacgam game" "Make a calculator", etc... ie, do a single pass for the minimal amount of info necessary to build a practical yet rewarding project.
2- Now the student have accomplished their first success, slowdown a little and put a small amount of theory here and there, but put focus on:
"Discipline and follow good practices" then re-do the projects right this time.
To build a analytic mindset move to:
3- How a computer think, using debuggers, disassembles, etc.
You get your hands dirty and see the magic behind the magic
And at the final step (is necessary to put some more steps before, just wanna get to the point):
4- Finish with a well round, deep and wide treaty about the field like SICP, so with some practique behind you can actually see what you have done and how it relate to the new info you are getting now.
Also, this will broad your horizons and open the appetite to get in the deep more.
----
I think is to be like how is learn to cook. You start doing simple yet good dishes, without worry to learn first the theory. You move to more challenge, learn techniques tools and tricks of the trade. Finally, move to see the theory behind, round your mental framework and challenge yourself in come with exotic, new dishes...
For example, I need like 5 different sources to finally have a grasp in how pattern match, and build a solution that later found in another paper.
"We show that building a compiler can be as easy as building an interpreter. The compiler we construct accepts a large subset of the Scheme programming language and produces assembly code for the Intel x86 architecture, the dominant architecture of personal computing. The development of the compiler is broken into many small incremental steps. Every step yields a fully working compiler for a progressively expanding subset of Scheme. Every compiler step produces real assembly code that can be assembled then executed directly by the hardware."
There is also a work-in-progress effort to write a more extensive textbook that follows the same approach to teaching compiler development, using Racket instead of R5RS Scheme: https://github.com/IUCompilerCourse/Essentials-of-Compilatio...
The main roadblock I'm having right now is typechecking. I've implemented Hindley Milner in Haskell and played around with Turnstile, but I still don't know enough theory to invent my own type rules for an imperative language. Something like "Type Theory for the Working Programmer" would be excellent. I just got a copy of TaPL, so maybe I'll just use that.
Now that I typed that out, I guess the thing about trying to come up with the one perfect teaching method is that students vary so widely in what experiences they bring to the table. There just isn't one method that could possibly work for everyone.
* The "main" book of the subject
* The Landau book about it
* The relevant chapters of The Feynman Lectures on Physics
* The Shaum's Outline book about it.
The idea is that you study from the main book, and use the Landau book as an auxiliary short version with only the important points. The Shaum book has a lot of exercises. [Some people don't like to recommend Shaum's book.]
After that, you can read the relevant chapters of the Feynman book. It's like a book with fairy tales for physicist [or physicist students] that you read before going to bed. Each chapter is amazing and you enjoy it a lot, but it is very difficult to study using it as the first read about the topic. It's very useful to have a deep understanding of a few difficult key topics, after you are familiar with the subject and the mathematical part.
[I really grok the difference between phase velocity and group velocity reading the Feynman. The definition of each velocity is easy so it's not so difficult to pass the exam, but understanding what they really mean took me a few years.]
Then we came across https://www.edx.org/course/how-code-simple-data-ubcx-htc1x - love it and does not need any help from me :) planning to move on to https://www.edx.org/course/how-code-complex-data-ubcx-htc2x after that!
edit: corrected typos
There are YouTube videos (I don't know how well they fit with the current course) and they are excellent.
Alternatively, the MITx 6.002 course on Computational Thinking is also for undergraduate students, but it had a greater focus on programming being integral to the sciences and other fields. I don't recall the the curriculum exactly, but even though the course is an introductory one I think some of the concepts might be a little daunting for a young teenager.
In addition to the UBC courses, another introductory treatment that won't overwhelm to a committed young learner is the DartmouthX C Programming with Linux. One of the instructors, Petra Bonfert-Taylor, taught a very accessible introductory complex analysis course on Coursera, and seems especially interested in first experiences students have with topics so that they are not discouraged. She has written a number of articles on teaching an introductions to new subjects.
I haven't done HtDP yet. I love The Little Schemer http://www.ccs.neu.edu/home/matthias/BTLS/ , but I can't recommend it unequivocally, mainly because I've found (somewhat to my surprise) that it's not accessible to all programming beginners without quite a lot of extra in-person tuition. (And I'm talking about the early chapters here, not chs. 7-10 or chs. 8-10.)
This is what everyone seems to be forgetting.
I know that at Caltech in the early '80s, a majority of incoming students had not had calculus in high school. I would expect MIT to be similar.
http://www.gigamonkeys.com/code-quarterly/2011/hal-abelson/ "There’s a tremendous amount (of math) in this 6.001 book. That’s partly because we were writing it for MIT. You want to talk about higher-order procedures, so the obvious thing you can do is you can express the idea of an integral. So that’s an obstacle for lots of places. Remember, at MIT the context we were writing in is every person who took the course had just had a semester of calculus.
We actually did some versions for the Humanities faculty, where we didn’t do that at all, and we effectively started with the data structure chapter and then talked about the ideas for how do you structure and manipulate data, and then do abstractions over that."
HtDP is similar to their other version, starting with data. Author of that book has a good talk about creating a compsci curriculum https://youtu.be/5c0BvOlR5gs
I get why readers don't do that. There is very little written so well that it deserves that trust. Generally we have to step back from something and ask "what does that mean? how do I reframe that into something I can understand?" Because the material's models are too poorly thought out to be useful or too poorly communicated to be discovered. Trying to adopt such models is futile.
But for me, SICP is one of those rare books where I am better off trying to absorb its frameworks, rather than constantly trying to reframe the material into something I understand.
When I step back and _think_ the way the book suggests, the problems solve very quickly. When I try to get a solution from some combination of my intuitions and known tricks, I thrash about endlessly.
It is a very carefully written presentation of profound and important ideas, and deserves to be approached differently than the vast majority of books.
1. SICP (Structure and Interpretation of Computer Programs)
2. HTDP (How to Design Programs) https://htdp.org
3. LiSP (Lisp in Small Pieces),
4. PAIP (Paradigms of Artificial Intelligence Programming) https://github.com/norvig/paip-lisp
SICP and HTDP are different but serve the same purpose. LiSP is about interpretation, semantics, and compilation. PAIP by Peter Norvig can seen as elementary programming book that uses classical AI as a subject. You learn both.
I don't know what to think about this, I haven't read it: SICM (Structure and Interpretation of Classical Mechanics)
Functional paradigm has two flavors:
1. Functions as first class objects in the language and enabling the functional style programming.
2. Pure functional programming. Not a style, its functional programming.
IMHO learning the first kind helps relatively little when you want to learn second kind and vice versa.
Lisp is multi-paradigm language or "Lisp paradigm" language family. Because functions are first class objects it facilitate functional programming of the first kind. Some Lisps are geared towards using functional style more than others.
I have only read Thompson's Haskell: The Craft of Functional Programming and some old ML books I can't name. I have no idea if it's a good compared to other FP books.
The experience of that alone might help you find the next book that works for you.
https://www.goodreads.com/book/show/1032517.The_Schematics_O...
Also in that league, but using a different language Mozart/Oz:
https://www.info.ucl.ac.be/~pvr/book.html
German: Schreibe Dein Programm
If you like the approach and want to learn more, like, for instance, how to extend it to OO design, I list below links to several courses (most, except for the last one, offer enough material to complete them on your own, but I couldn't find any videos) at the university where HtDP's main author, Matthias Felleisen, is tenured (North Eastern). The courses are listed in the order in which they should be taken, and the rationale is explained by the professor in the paper "Developing Developers" [3]:
* CS 2500 - Fundamentals I [https://course.ccs.neu.edu/cs2500/]
* CS 2510 - Fundamentals II - Introduction to Class-based Program Design [https://course.ccs.neu.edu/cs2510/index.html]
* CS 2800 - Logic and Computation [https://course.ccs.neu.edu/cs2800/index.html]
* CS 3500 - Object Oriented Design - Spring 2018 (scaling up the 3 previous courses) [https://course.ccs.neu.edu/cs3500/]
* CS 4500 - Software Development [http://www.ccs.neu.edu/home/matthias/4500-f18/index.html]
[1] https://www.edx.org/course/how-code-simple-data-ubcx-htc1x
[2] https://www.edx.org/course/how-code-complex-data-ubcx-htc2x
[3] http://felleisen.org/matthias/Thoughts/Developing_Developers...
Thank you for your effort. I am starting with these.
I can recommend "Concepts, Techniques, and Models of Computer Programming" (CTM or CTMCP).
Book's page: https://www.info.ucl.ac.be/~pvr/book.html
Quote from www.c2.com:
"Like SiCp, CTMCP is first and foremost a book on programming, not on Oz or Scheme or anything else. And if SiCp is the reigning king of such books, CTM is a worthy challenger to that particular throne."
> While SICP (yes, everybody uses the acronym) is considered a holy grail for serious computer scientists, it's hella hard to figure out. For me, programming "methods" that make me jump through intellectual hoops made of mathematics make it hard for me to learn the actual /programming/.
I started learning how to program in high school using whatever resources I could find (my school didn't have any programming courses beyond an introduction to 1980s BASIC, so independent study was the only option), initially following the very nuts and bolts-oriented instruction in C++ Primer Plus (I arbitrarily chose this as a good intro textbook based on my limited understanding of what constituted 'real' programming versus BASIC). I spent the better part of of 2 years making unremarkable C++ programs that were little more than basic math and control flow mashed together with the C++ standard input/output libraries.
At some point, I happened upon SICP, and learned more about computer science and programming in six weeks than I had in all of my previous self-study. I hold that it was, and still is, a remarkably succinct and understandable introduction to the fundamental concepts that underlie computer science. Yes, math was involved, but I didn't need to learn anything beyond my basic high school algebra education to understand how that math translated into programs: SICP did an excellent job of explaining how programming related to that math. Most importantly, it was /fun/: working through SICP made me feel like I was learning a new way of thinking, not just learning how to translate something I already knew into computer language.
Other descriptions of HTDP suggest that it combines my painful slog through the nuts and bolts of programming (albeit more succinctly and less painfully) with SICP's math/CS elements, so it's probably a better textbook for tackling both at once. However, it's crucial that it does both: to focus only on "actual programming" as the author suggests is probably a surefire recipe to convince students that computer science is a dull field consisting solely of writing instructions for computers, with no thought whatsoever into what instructions make sense or why.
> [SICP] set the curriculum for "beginning" computer science
> All [examples and exercises] use complex domain knowledge. ... Some early sections and the last two chapters cover topics from computer science ...
Why the square quotes around "beginning"? At the time the course, 6.001, was launched it was quite reasonable to assume that an MIT undergrad might arrive at the Institute never having previously used a computer, much less programmed one. This was truly an introductory class and while required for all EE and CS students, was intended for any undergraduate. The material in the examples all covered core subjects every student needs in oder to graduate, or else were computer science topics that should hardly shock someone taking a computer science class.
Some of the other criticism is reasonable in light of the authors' desire for a slightly different approach. 6.001 was and is the basic introductory class and a CS student will take other classes which will address different aspects of program design and application. Choosing a different time of introduction for different objectives is hardly unreasonable.
(And I don't know why object-oriented programming is somehow thought to be in opposition to the principles of SCIP; the latter's heart is abstraction and composition which are the whole point of object-oriented thinking, right?)
Praphrasing, it essentially boils down to the kind of applications developpers of today are writing. People are now mostly slinging libraries they have a superficial understanding of together in a black-box style. So for most proprammers there's a lot of prodding and tinkering and this isn't a skill that SICP teaches.
disclaimer: I don't think I've imagined reading this however didn't bother looking for the reference.
With such a mismatch of expectations, the resulting frustration on both sides is not surprising...
Gerald Sussman made some remarks about this during an unrelated roundtable discussion at the 2009 International Lisp Conference:
https://cemerick.com/2009/03/24/why-mit-now-uses-python-inst...
Note that Sussman did not actually state why the committee decided to change the curriculum. The remarks about studying software empirically were his opinion. I was in the audience, and while Sussman seemed sincere in his remarks, I still have a hard time believing he was serious. How can anyone state, without irony or sarcasm, that we should just give up, and start treating software programs, where all the "laws" are not only known, but made up, by us, as if they were natural systems, where our only way to understand them was to start "poking" (I may be wrong, but from what I remember this was the actual word Sussman used) at it and observing the results?
If you give up before you have even started on modularity, composition, etc., and start treating every program as if it was a million line COBOL hairball, the hairball part is just going to be a self-fulfilling prophecy.
My takeaway from Sussman's remarks was the opposite of his message - the ideas about applying mathematical principles to software design in SICP have become even more relevant as a way to prevent software hairballs.
I make good money doing the "poking," but if you are going to teach that, stop pretending that you are teaching a science at the university level - this kind of shrug-and-give-up empirical programming is to computer science and engineering what a trade college auto mechanic education is to a mechanical engineering degree.
I tried to read SICP after about 6 months to a year after learning my first language, and I couldn't get past the part where they turn a recursive function into a tail-call eliminated 'iterator' style recursive function. I understood what was going on, but I just couldn't grasp how to generalize it. Of course, I get it now; you just pass an extra variable in and use it like you would the `i` var in a for loop, but at the time I just couldn't grasp it.
I also had similar struggles with the early use of math problems as examples and other vaguely described algorithms.
Granted, my background is in Music, so I didn't have the domain knowledge that the author mentions, but programming is more about strategic and logical thinking, so I was perfectly able to do that even at an early stage.
I think MIT is right to think SICP is too much for a freshman. Hell, I was already graduated and applying for grad-school when I tried to read SICP and I still struggled.
Freely available here: https://papl.cs.brown.edu/2018/
More on the Pyret language here: https://www.pyret.org
It's used in the Bootstrap program that teaches it to middle schoolers. Probably pretty easy to learn.
Perhaps I should've read it as my first programming book, but that time's long past.
Anyone else had this problem? I'd gladly take tips on how to get over it, since I do honor classics and don't think I'm above them.
In a 4-year Computer Science curriculum, SICP is not a perfect fit for the role it was being asked to play. HTDP was written with the goal of being a better fit in that specific role.
If you are self-taught or otherwise learning in a non-4-year CS program, this distinction is not applicable to you. SICP is great. HTDP is great. They are both great.
Indeed, the course did upset people. I remember how people constantly complained how shitty this decision was, how "people in the 1st year engineering classes are doing real Java programming while we do this shit no employer asks for", some noted how the language was stupid, or in the best case just a toy, useless in "the real world". Thing got worse when some people realized that, contrary to their expectations, they did not know how to program, since they could not do eg. graph traversals once that was stripped of its OOP or Java-like envelope - "I will fail the year because of the bloody scheme!", they would say.
To me, instead, it was revelatory. We did indeed solve one problem per week, and although the problems were less sexy than the ones I was expecting (finding the max of a list is not the coolest thing in the world), promises were kept, and little by little I started appreciating how much you could express with so few lines or predefined functions, leveraging only on very few concepts (eg. recursion), it was different from the programming we had done in high school. It was also a big difference with the university classes of philosphy, where "assistant professors" (underpaid PhD [students]) will come to read you a book AND a comment to it, with very little intellectual work needed from either them or students. I quickly decided to follow only Computer Science. I became no black belt lisper or anything, but that style of programming, of looking at problems, software and the whole field certainly influenced me. I am currently enjoying my role at a FAANG company, and thinking about all of this made me want to write her an email to thank her, but the saddest thing is that I can't do it because right at the end of that academic year, Ms Busi actually died, unexpectedly, at the age of only 39. First year student of CS in Bologna now learn Python programming.
(this is her uni page if you are curious: http://www.cs.unibo.it/~busi/)
This is a perennial problem with computer science programs everywhere. The irony is that the department will have employers banging on the doors trying to hire graduates while the students complain no one will hire them because they're wasting their time on "toys"; no one seems to notice the relationship.
Hopefully, the problem will go away with the removal of things like SICP and the introduction of Python as you mention.
My introduction to computer science was also HtDP and your experience mirrors mine exactly. The people who were the most upset about it were people with exposure to Java and C from high school. Now that I’m in industry, I find I have a better grasp on things like recursion compared to many of my colleagues.
What mathematics? Now that many states have legalized cannabis, SICP should be read while high in the middle of the night. Its nonstop commentary is profoundly amusing. I love for example the passage that presents tail-recursion as the natural form of iteration, and notes about other languages:
"As a consequence, these languages can describe iterative processes only by resorting to special-purpose “looping constructs” such as do, repeat, until, for, and while."
Of course they're right, and yes that's a mathematical view, but they put it so well. All replacement texts are unreadably dry.
> "Instead of teaching some currently fashionable programming language" [...] > "The approach emphasizes the systematic design of programs. Experience shows that it works extremely well as a preparation for a course on object-oriented programming."
As someone who gradually transitioned from "object-oriented programming" (or "place-oriented programming in general") with mutable data into largely functional systems with immutable data structures, I find this quote mind-boggling, especially coming from educators.
Moving to functional programming and immutable data structures is what allowed me to build and maintain systems at least an order of magnitude larger than before.
For me is one of the most interesting lectures I ever watched. Requires effort because it makes you think, and this is one of the great things about it.
Not for beginners? Yeah, like structural engineering, physics, biology,chemistry, writing, or anything worth something in life you need to work on it, have interest and abilities doing that if you want to become a professional.
Some people want to make University so easy that the title becomes worthless, like happened with University titles inflation in the UK.
The instructor David Beazley very skillfully weeded out all the non-essential parts and added one amazing exercise where we implemented the lambda calculus and, funny enough, the ycombinator.
Highly recommend it for anyone who desires to learn this material, can't find the time, and is willing to pay $2500 for the experience.
BTW a very nice introduction to Racket is also "Realm of Racket".
I've been using racket for almost all of my recreational programming for the past few years but I don't do it with DrRacket.
2) it does not lie, gives a very nice structured way to think about data and processing it through simple cases (product and sum types without naming them)
3) it's quite small step read, nothing as extraordinary as SICP
I use it for continuing education at a company, the only complaint I've heard from people is that it's very deliberately paced.
I do wish there was an equivalent that used a statically typed language, because the actual approach is very fundamentally based on types. I've spoken with the authors about this, and the reasoning was twofold: 1. people are going to have to deal with unityped languages in industry; 2. existing error messages for static languages were bad. At this point, something like Elm might be a good fit, although you'd lose out on lispy things like quasiquote.
Not exactly an equivalent, but a very good book (that uses a statically typed language) is "Elements of ML Programming" by Ullmann.
I think the biggest win is that it's the first source I've found that incrementally teaches a pragmatic understanding of recursion[1]. But also why it works, with the structure of the code following the structure of the data definitions and downward. The videos classify natural, mutual, structural, and generative recursions and explain the who/why/what/etc of each. Gregor's video explanations were great, and the book similarly seems to anticipate many questions I have while working through the problems. At times, parts have been slow, probably due to some prior knowledge[2], but definitely worth the trek.
The first time I learned recursion was basically a "now draw the rest of the owl" trope. I was hoping for so much more in way of explanation and have always felt incapable whenever struggling to approach and solve recursive problems. And questions always just led to non-didactic Inception movie references.
I used to think maybe I was just bad at that type of problem. And maybe I am, but more and more, it feels like people generally - including those teaching - don't actually know the concepts here themselves. It's like the world has just collectively memorized a few examples and refuses to acknowledge the giant spaces between them.
In that sense HtDP has been incredibly refreshing.
[0] https://www.youtube.com/channel/UC7dEjIUwSxSNcW4PqNRQW8w They are the videos that go with the edx course mentioned elsewhere here.
[1] Although I've heard The [Little|Reasoned|etc.] [Schemer|Lisper] books may do similarly.
[2] I'm in my last semester of a CS degree and I have work experience programming
The authors do a good great job in promoting good software craftsmanship from the very beginning of the text. Like any good teachers they reinforce the importance of developing good habits that as a beginner you sometimes take for granted, such as writing unit tests for newly defined functions. Thinking through programming exercises is done methodically with HTDPs Design Recipe, which enforces the use a function signature, purpose statement (comments), a header, and functional examples - followed by a template to flesh out the basic structure of the code you will be using to define your function.
I've watched most of the SICP lectures by Sussman and Abelson and while brilliant, it becomes quite clear that even the professional programmers in the room have trouble keeping up with the pace of the lectures. As a beginner, I was acutely aware that I had bitten off more than I could chew and I will revisit them and SICP after completion of HTDP.
As a side note, I discovered small typo in one of the examples and emailed the lead author (Matthias Felleisen) and he responded to me same day very appreciative that I took the time to do so. If he or any of the other authors read this, thank you! I'm still diligently making my way through and enjoying your text!
And importantly, can you contrast why you chose the one you like over others you’ve worked through?
TAoCP should be enough for anybody
Now if the author is bummed by the "mathematics" of SICP he sure will have himself handled pretty roughly by TAoCP :)
disclaimer: I haven't read SICP but as others have pointed out I doubt there's any significant math in it. I presume the author was referring to a heavy dose of informal reasoning.
"Access denied. Your IP address is blacklisted. If you feel this is in error please contact your hosting provider's abuse department."
It could be my VPN, but still, not nice.
Supposedly all of these books assume (or at least allow for) no background in programming, but I think the reality is that taking SICP or even HtDP into the intro class at a non-elite university or a community college would be a complete non-starter and/or abject failure.
What I'm trying to say is that there is a place for both of these approaches: A deep look into computer science, and the nuts and bolts of basic "get it done" programming.
Should both of these things happen in a single class, or series of classes? I think the answer is yes. But how to do that and not leave non-elite students back on the road is another matter.
I believe that the HtDP authors think that the "domain-specific knowledge" required of SICP was a barrier.
And I also understand how advanced CS students think that a class focused on how to manipulate strings, use loops, deal with variables of various types, and work with basic logic in the context of a specific computer language is NOT computer science.
But in my view, most students -- and all average students -- need to crawl quite a way, then walk, before they can run.
Even Sedgewick's Computer Science, which focuses on Java and has a wealth of great questions/assignments all along the way, could really be a barrier to students who aren't steeped in math and science. I learned some math while going through the book, but I didn't learn so much programming. Liang's approach might be too basic for someone who has already done years and years of programming but is way more approachable for those who have not.
My guess is that many professors tried SICP and had a very poor rate of success. I fully support a selective class that says, "this is very hard, but you will learn a lot and look at the world in a different way, and if you really want to understand computer science, this is the class for you."
But there also needs to be more of a gateway class for future programmers (not necessarily graduate-school-bound CS majors) that eases them into the world of writing code. Offering the basics and sneaking in some CS seems better than doing it the other way around.
In a way, it's like the difference between carpentry and architecture. You can teach people who want to build houses how to design them, but at some point they're going to have to get out a saw, hammer and nails and make something happen.
If an "ivory tower" approach is working, I'm on board, but I bet more people get value out of SICP after they have a lot of classes and experience under their belt and not the other way around.
"If programming were just about numbers and arithmetic, it would be as boring as mathematics."
What's wrong with this author?