There are already several websites which publish a “roadmap” of how to teach yourself programming (University keve) using freely available courses and textbooks.

Here is my 2 cents.

First of all, SICP is an advanced textbook. It is by no means suited for teaching freshmans, unless you are a MIT student, who is math-lover and a “slow thinker”.

Brian Harvey, the great, managed to teach the CS61A at Berkeley – a SICP-based course which goes at a slow pace. He gave exceptional, state-of-the-art lectures, along with printed lecture notes. This is the only good start.

Second, OOP is nothing special’ and definitely not “the best way to program”. Whole OOP (so to speak) has been implemented in CommonLisp and later Ocaml just as embedded DSL without any special language suppost. Yes, Smalltalk is cool, but the thing about Smalltalk is message-passing between objects and uniformity (everything is an object in single hierarchy), not OOP per se.

So, know more than one paradigm and understand the Whys and the underlying principles (which is the mos important understanding)

The other exceptionally good courses are:

Scheme based courses

There are some “problems” with Scheme based coursers. While the Scheme culture at MIT is absolutely wonderful and unique, it takes some understanding to see some shortcomings.

  • lack of emphasis on modules and separated units of compilation (CLU and B.Liskov emphasized this)
  • types are described loosely – one has to be very attentive to understand the domain and range for each Scheme procedure.
  • not teaching structs, which are fundamental (yes, yes, a heterogeneous list is an ultimate struct)
  • no Algebraic data types (no ML-like sum-types, sorry)
  • basically, they do not teach techniques for “programming at large” (can’t fit in one’s head, lots of people) the 3110 Ocaml course does.

In short, the ML-family languages are more strict (statically typed, homogeneous aggregates) and “more” modular.

Anyway, Scheme is based on the Lambda Calculus, and this is all you need.

((lambda (x) (* x x)) 2)

;; bindings (define is a special form)
(define square (lambda (x) (* x x)))

;; let is a special form and
;; conceptually it is just a lambda with an in-place invocation
(let ((x 2)) (+ x 1))
((lambda (x) (+ 1 x)) 2)

;; unary identity
((lambda (x) x) (lambda x x))

;; list
((lambda x x) 1 2 3 4)

;; special forms
;; notice how let and cond sytax are similar in shape

;; recursion
(define map (lambda (f xs)
              (cond ((null? xs) '())
                    (else (cons (f (car xs)) (map f (cdr xs)))))))

Scheme is strongly-typed, but the types are implicit and usually very generic (due to built-in pairs and lists and the proper Numeric Tower).

So, the books (SICP) teaches generalized advanced concepts but uses a language with almost no types (and almost no syntax, which is good).

The point is that after some fist Scheme course one has to take an ML course. Nowadays the Cornell CS 3110 is absolutely the best.

At Berkeley they rewrote the classic Brian Harvey’s CS61A in Python with a new textbook. It is on par with 3110, but it is Python.