This book should really be called "How to Design Functions" -- not "Programs" -- because it sidesteps the most difficult and interesting topics in making software programs, namely the work of a) separating a task into simpler subtasks and then b) composing smaller functions into a program that performs the task. IIRC the most complicated example in this book pertains to calculating the optimal price of movie tickets. There is merit in some of the book's recommendations. But overall this material could be condensed into the 25-page intro of a much more interesting programming textbook. As it stands, HTDP is a buzzkiller.
Speaking of which, here's a 2010 blog post about how Georgia Tech stopped using HTDP, featuring an argument in the comments between the author of HTDP and Alan Kay.
I wonder which edition of HtDP you read? Your comments are somewhat true of the first edition (especially so in terms of the exercises provided), and as far as I know, the authors were aware of such criticsms. In any case, since then, Racket has been enriched with various HtDP student libraries, including a functional I/O framework called Universe [0], and the second edition of HtDP/2e utilizes these libraries for a number of relatively complex beginner projects, including a one-line text editor, a Tetris clone, an MP3 database, and a (very simple) interpreter. There are quite a few more. All of this material guides students to an appropriate first understanding of your points A and B.
Also, there are quite a few sibling courses now in what I sometimes call the "How to Design Programs extended universe", and some of these are a bit more project-focused. In particular, there is Marco Morazan's Animated Program Design [1], which iteratively develops a multiplayer Space Invaders-type game called Aliens Attack through multiple sections over the course of the book. The main pedagogic aims of the Universe framework are to introduce students to both event-driven programming and distributed programming, and as far as I'm aware, the Aliens Attack program is the most complex tutorial treatment of an HtDP-style program that combines both aspects. Unfortunately, the book is quite expensive.
Personally, I didn't find HtDP to be a buzzkiller, but rather the textbook that helped me understand that programming could potentially be a joyful activity rather than drudgery. As a former music teacher, I loved its insistence on practice and process. But I was also a beginner who had tried and failed to learn to code a few times over the 15 years before I read HtDP/2e. A more experienced programmer surely might not have the same experience.
Worth mentioning that there is a Space Invaders project included in the first section of HtDP.
Personally, I wouldn't give Morazan's Animated Problem Solving a big recommend for someone trying to self-teach CS1, especially not when HtDP and How to Code are free. In my opinion, APS is a bit over-stuffed (it has a tendency to throw relatively advanced terms, like property-based testing, at the beginning student without much context or follow-through) and it can sometimes make exercises (including the Aliens Attack ones) overly complex and tedious.
I don't think HtDP is without criticism, but if you can get through the somewhat slow-going first section, it's a great textbook. Alternatively, you can work through UBC's How to Code (H2C), which has a brisker pace. I found the first section of HtDP a bit tough-going myself, so I ended up working through H2C first. I only came back to HtDP because I found some of H2C's explanations of later material shallow, but more importantly, I felt that its exercises were generally lacking in challenge. Nonetheless, I can't recommend H2C enough. Gregor is a friendly, patient teacher, and the H2C presentation of the design recipe somehow seems more fine-grained than HtDP's version but without feeling overly complicated.
Note that you can actually access the edX version of H2C for UBC students at the CS110 course page [0], just click on the link to enroll in the "edX Edge course". It appears to be an updated version of the original MOOC course with some small additions.
I agree, programs are files, not functions
If you want to show me how to design programs you need to show me how
to break my analysis of the requirement, into modules, components and files
And then how to build and assemble those pieces into the running file (the executable)
When you open a Github project you are greeted with a file tree, not a function tree
we still program to disk not to a database, where functions exist in an abstract space
This book supported the curriculum of my introductory computer science course at Tufts University back in 2013. It was hard but amazingly valuable. By the end of the semester, we were doing natural language classification using binary search trees and higher-order functions [1]. I think learning a Lisp-based language first gave me some very powerful foundational problem solving skills that have made me a successful software engineer today.
I read the abstraction chapter, but I really have a hard time translating those concepts to different languages like Rust. Seems like this book is very specific to this Racket-based teaching language?
The racket-based teaching language is actually a series of languages that progress in complexity. The beginner version is very simplified, which makes it perfect for students working on assignments since they won’t be distracted by advanced language features.
The specific concepts in the book translate to other functional programming languages, and almost not at all to imperative programming.
The general thesis of the book, that you should follow a design recipe, is a universal one. It teaches you how to design your functions and write the documentation before you begin the implementation. This is also the part that students are the worst at, in my experience (as a TA for a first year course based on this book, twice).
> This is also the part that students are the worst at
isn't everyone?
as some one that worked for years as a trainer at a tech commercial training company, i eventually came up with two sort of realisations:
a) teaching HOW to program is really, really hard. i was never at all good at it, though i could teach programming languages and system architectures rather well.
b) when you start out, you cannot write too many functions.
i'm not sure that the book in question would entirely agree with this. any course using it for teaching would need lots of input from the physical human instructor.
a) teaching HOW to program is really, really hard. i was never at all good at it, though i could teach programming languages and system architectures rather well.
It really is a way of thinking. It takes deliberate practice to develop. Students are often uninterested in developing this kind of soft skill set because it doesn’t provide immediate returns when it comes to finishing assignments.
It’s a real shame. In the long run it pays huge dividends.
yes, of course it does. but can you teach it??? for me, when presented with a problem, the tech solution normally pops into my brain, like the lightbulb in cartoons, if it doesn't, it's (not always) often an early-warning that i have misunderstood the problem, or that it is too difficult for me. you can't teach this stuff.
As a functional language (or family of languages in this case), Racket should translate very easily into other languages with the ability to create and call functions. Not having some form of polymorphism will make it hard to follow many of the examples and exercises though, so perhaps
I actually think the materials in HtDP complements learning Rust pretty well. What makes Rust interesting exists almosy
Yes. one of the things rust sacrifices for high performance is modularity. Rust is a better language for safety and high performance, however it is not the best language in terms of modularity.
Haskell takes the crown for modularity and safety but as a result it is less performant then rust.
Move by default is not modular. Why? Because it is a mutation. The state of your program changes after a move and your program must be structured around that.
That variable that was moved can no longer be reused in the same context so your program is less modular as a result as the definition of modularity is high reusability of modules.
Clone just means pass by copy. Make a copy and then pass the value. Pass by immutable reference works too. Just keep everything immutable for maximum modularity. But if you want to mutate things and keep things relatively modular then pass by copy (aka clone) is the best alternative.
All in all rust is typically harder to program for and harder to make elegant because of all the anti-modularity features used to increase performance and safety.
Though Haskell's module system is somewhat a wart of the language, and I say this as someone who loves Haskell. "Hierarchical" modules in Haskell2010 are literally just modules with periods in the name, and it lacks the power of ML and Agda's parameterized modules. The other major wart with Haskell to me is the record types.
That has been a draft for over ten years. I studied out of it in print out form in 2009. I wonder why it’s never finished. Maybe the authors aren’t satisfied with it?
There is another book that is usually mentioned when comparing these two. Concepts, Techniques and Models of Computer Programming. I don't know how they all compare to each other, I just mention it for completeness sake.
Years ago, the author taught a MOOC covering parts of the book[0]. The course is archived on edX, and the videos are on YouTube[1]. It was fun starting from a super simple functional language and building to a dataflow functional language by the end.
Speaking of which, here's a 2010 blog post about how Georgia Tech stopped using HTDP, featuring an argument in the comments between the author of HTDP and Alan Kay.
https://computinged.wordpress.com/2010/05/11/playing-the-car...