One of my friends just finished working through SICP (progress here - http://lawfulsamurai.blogspot.com/search/label/SICP, - the last few sections still have to be updated) and asked me for reccomendations for future work.
I thought of telling him to get really strong on algorithms etc (perhaps by working through Tardos/ Cormen et al, doing all the exercises like he did for SICP), but thought I'd tap the good folk of HN for better (or different) suggestions. Working through CTM for example is an option (another of my friends was doing this http://ctm-himanshu.blogspot.com/ but he didn't quite complete it).
(This has nothing to do with his day job which is java/python/Django. Just something for him to work through when he has a few hours and learn cool things.). Any suggestions gratefully accepted!
I just bought this book and have been reading it for a few days and it really is pretty good. The best thing about it are the numerous practical examples and the "War Stories" that show you how real people determined they really needed to use algorithm xyz.
If your friend wants to a) get really strong on algorithms, b) put in some hours, and c) actually do the exercises, I'd recommend Knuth. It's worth the effort.
From what I understand Knuth uses MIX assembly language to imlpement his algorithms. Contrast this to the Skiena book which uses C++. I found this to make it very practical.
Though to be fair, I don't think it offers near the depth of the Art of Computer Programming:)
It's actually a common misconception that Knuth uses MIX/MMIX to implement his algorithms. The vast majority of the algorithms are described in English, and the MMIX implementation is usually only given when there are relevant implementation details to be discussed. MMIX is just an idealized machine language, and it is trivial for a reader to implement the algorithms described in the programmer's language of choice. (This is assuming that the objective is to learn CS, not to have a cookbook of ready-to-run algorithms to pilfer....)
I'll also add that I usually recommend that newcomers begin with Volume 4, and turn to the earlier ones later. I think that for many people, skipping the preliminaries, and starting with an interesting and relevant topic (combinatorial algorithms) gives more immediate pleasure than beginning with the lower-level underpinnings.
Readers might also consider Knuth's "Concrete Mathematics" as a substitute for the more-or-less equivalent material in Volume 1, especially if a little more help is needed in understanding it.
For example the first algorithm in the book (found via google):
Algorithm E ( Euclid's algorithm). Given two positive integers m and n,
find their greatest common divisor, that is, the largest positive integer that
evenly divides both m and n.
E1 [Find remainder.] Divide m by n and let r be the remainder.
(We will have 0 ≤ r < n)
E2 [Is it zero?] If r=0, the algorithm terminates: n is the answer.
E3 [Reduce.] Set m← n, n← r, and go back to step E1.
It is a really enjoyable read and has a nice narrative that I think other algorithm books are lacking. CLR, for instance, just reads like a handbook to me. The goal Kleinberg/Tardos book, OTOH, is to teach you how to design and analyze algorithms. They will actually follow false starts on certain problems and uncover where they break.
The best book to follow up SICP is Essentials of Programming Languages, by Friedman, Wand, and Haynes. It uses Scheme to show how the fundamentals of programming languages are built, and both in its form and its content, it seems a direct continuation from SICP. After you've done with it, you'll have a much better understanding of Scheme, functional programming, programming languages, and programming in general.
I'm personally going to work through Programming Language Pragmatics. I want to have a better foundation in language paradigms, plus fill a hole in my education (no, zero, nada, real exposure to compiler design).
I'll also be learning more about Lisp concurrently.
Sadly, none of this has much bearing to my day job, but when I have an hour or two it seems like a nice way to spend it. At that pace, I plan to finish sometime in 2015 . . .
On the other hand if he wants to learn Lisp then I really enjoyed Lisp in Small Pieces though its not a quick read. It consumed almost all of 2005 for me:)
Did he enjoy sections 4 (Metalingustic Abstractions) and 5 (Register Machines)?
If so, he'd probably be interested in both these books. They are quite hefty, but seem to be goldmines (so far, I'm only just getting started on them myself).
Both books cover much of the same ground. The first one is heavier on theory, while the second one reads a LOT like SICP. Currently I'm working through the second one and using the first one when I want more in-depth info on a certain topic.
Lisp In Small Pieces (http://pagesperso-systeme.lip6.fr/Christian.Queinnec/WWW/LiS...) is sort of intermediate between SICP and the Peyton-Jones stuff; it still focuses on Lisp dialects that use dynamic typing and applicative-order evaluation, but it shows a whole bunch of different approaches to exploring that design space and implementing stuff in it.
I also enjoyed reading Pierce's Types and Programming Languages (http://www.cis.upenn.edu/~bcpierce/tapl/), although I was kind of nodding my head and going "yeah, whatever" during some of the proofs.
Both recommendations are little too high for someone just coming out of SICP. I recommend Essentials of Programming Languages as a stepping stone. Pierce's book is probably irrelevant to someone just interested in Lisp; type theory is best approached through an ML angle. And Quinnec's book is not for the faint of heart; you will need to have been well versed in lisp, compiler/runtime implementation techniques and have brushed against denotational semantics (through the Nielson and Nielson book, perhaps.)
[edit: denotational, not operational, semantics; OS can be learned in a fun-filled weekend. The "small-step" variety should appeal to both language hackers and (virtual) machine enthusiasts.]
He should write a lot of code for fun and try to incorporate what he's learned so far. I understand he codes at his day job, but that's not a place to take risks or to code things 5 different ways "just because".
Artificial Intelligence: A Modern Approach http://aima.cs.berkeley.edu/ -- has lots of broadly useful material and ought to be accessible to anyone who's completed SICP. One of the very best technical books I've read.
"Problems On Algorithms" (Parberry, Gasarch):
A slim volume containing ~700 exercises on proving various properties of algorithms. And it teaches you most of what is needed. Download it from: http://www.eng.unt.edu/ian/books/free/
"Elements of the Theory of Computation" (Papadimitriou): Classic text. Sure you've heard of Turing machines before, but what do you know about mu-recursive functions? It's very beautiful and if you have a person with whom to read the book and do the exercises, you will gain immensely.
It's certainly one worth having and the only book from my computer science education that I still reference frequently.
In fact, I'm tempted to say that it's the last computer science book that you have to read. After that you should be able to work directly from research papers, though a topical book can sometimes be useful in other areas with fairly wide breadth.