
Teach Yourself Computer Science - rspivak
https://teachyourselfcs.com/
======
dan-robertson
I don’t really like the recommendation for SICP. The book expects a certain
level of mathematical maturity from the reader and I think this level is
significantly greater than the level that might be expected from the targets
of this website. Mathematical maturity in this case can be broken into two
parts:

1\. Understanding what a proof is, what is required to prove some proposition,
how to figure out and write a proof, how to cope with struggling to prove
something, and how to carefully read definitions.

2\. Just knowing what “basic” things are. In the case of SICP these include
calculus in one variable, lots of elementary algebra, an understanding of
polynomials and exponentials, vectors and linear transformations (roughly the
level of geometry required for basic classical mechanics (c.f. SICM although
this is a slightly more advanced way of doing mechanics))

It is easy to see this requirement by looking at the exercises from the book.
They start with calculus themed exercises (e.g. Newton’s method), move on
towards more algebra flavoured problems and then vectors/geometry. Later
exercises are not on mathematics but require one to apply a reasonable amount
of mathematical sophistication to get the answer. Throughout are exercises
which rely on the reader carefully applying their careful reading of carefully
written definitions for things like models of evaluation.

I have another issue which is with the following:

 _CS is basically a runaway branch of applied math, so learning math will give
you a competitive advantage._

I basically disagree with this entirely. I would say that computer science is
basically a branch of pure mathematics with applications to engineering
practice with real-life computers. I’m not sure I would describe it as runaway
but some branches of computer science (eg operating systems) are, I think, not
really branches of mathematics.

~~~
clumsysmurf
Do you think How to Design Programs (TtDP) is a good alternative to SICP? It
seems gentler, but if one were to go the HtDP route, what would come after?
SICP or something else?

[http://www.htdp.org/](http://www.htdp.org/)

~~~
dan-robertson
Well I don’t really know anything about it but it seems ok. The programming
environment is easier to set up than in SICP which removes a barrier to entry.

I’m not really convinced that scheme is the be all and end all of teaching
languages. It has some nice qualities and some that can make programming more
difficult. For example I think the kind of interaction is good but often in
that interaction one is essentially repeatedly refactoring a small part of the
program and TNT’s language does not offer much to ensure that these
refactoring are correct for any definition of correct. I think a ML style
language could be good for teaching too although often the errors that are
produced can be quite unhelpful.

The book seems like it covers some nice introductory things (like splitting up
programs into small functions) and some harder things to get to grips with
like quoting. But I haven’t had a very thorough look.

The thing I really like about SICP is the idea of building up a model of how
programs are interpreted and evaluated. The book produces plausible models for
evaluation and demonstrates how one can test between the two and where they
are wrong. I like this for two reasons:

1\. It really feels like science, coming up with ideas, testing them, seeing
when you are wrong. This feels especially useful when one considers mordern
systems built out of so many individually large things that it is hard to keep
track of things perfectly. It is useful in real life to build up models for
what’s going on and think about how you might test them and where you might be
wrong. I like that the book reminds you that computer systems may be tested in
the same scientific way that the real world might.

2\. (Because these evaluation models are implemented in code) it makes the
process of compilation and evaluation seem much more understandable and less
like magic. One can have an ok understanding of machine code and how a machine
roughly works without ever having to write any.

On the other hand maybe these reasons are wushu-washy and no one really needs
such concepts for computer science.

------
squarefoot
My theoretical knowledge of computer science can be approximated to zero, as
is my knowledge of math, but for some time I worked as a programmer with good
results; in my best days I could write about two hundred lines of C or Pascal
in a few hours, then go home without testing them because the machine wasn't
available and be complimented the following day because they compiled and
worked without any errors. I still felt I was lacking something so I tried to
improve reading some books but all of them required high math skills I never
had, so I quickly gave up. (Niklaus Wirth algorithms book probably is the only
exception here) I can perfectly figure in my head registers loading data and
shifting them around, logic gates changing and combining values, stacks
pushing and popping words, electrons flowing through components etc, and for
example can diagnose problems in analog circuits due to say bad decoupling,
ground loops etc. Figuring them is easy from experience but the math behind
that is way harder; anything beyond simple equations is like alien language to
me, and the very few times I grasped something beyond that I quickly forgot
for lack of continuous exercise. Did anyone else encounter the same
discouraging level of difficulty? So my question would rather be: are there
any good algorithms book for nearly complete math illiterates like me that
would help to learn both in the process (and possibly not hate them :)?

~~~
westoncb
> Figuring them is easy from experience but the math behind that is way
> harder; anything beyond simple equations is like alien language to me ...

It took me a long (and often frustrating) time to figure out that the
perception of difficulty is largely because of how _implicit_ most everything
is in mathematics. It's not like programming where eventually there is a
compiler with a definite structure that's going to make your program behave in
some exact specific way.

Even worse, is the way we're typically taught mathematics, it's always kinda
starting in the middle (as opposed to the beginning). We aren't taught about
what it is our how it works, so it's really hard to situate particular
mathematical concepts we're taught into a larger coherent framework.

The way I interpret mathematical works changed so much (and for the better),
once I realized that any significant bit of math you're using is the result of
something a human was trying to accomplish. In the same way you can point to a
piece of code and ask it's developer what the motivation was for some
abstraction or algorithm, there are always reasons behind the development of
mathematical systems. Once I understood that, rather than mathematical systems
being these disconnected things that materialized out of nowhere, I started
seeing commonalities and considering the reasoning behind them, and seeing
more of the network that relates them. It became a lot more enjoyable. I'd
recommend checking out some history of mathematics if you'd like to get a
better sense of that (my personal intro recommendation: "Men of Mathematics"
by E.T. Bell or maybe "Mathematics and the Imagination," which isn't history
so much, but serves a similar goal).

If you're looking for something on algorithms specifically the book
recommended by the author ("The Algorithm Design Manual") is a pretty friendly
read and largely non-mathematical, while still containing all the useful bits
(unless you're looking for a reference work on computational complexities or
something).

~~~
finaliteration
> We aren't taught about what it is our (sic) how it works

My biggest frustration learning math when I was younger was not knowing -why-
I was doing something a certain way or how it worked. It was incredibly
discouraging because it didn’t just “click” like it seemed to with my peers.

~~~
joshvm
There is a certain danger in trying to learn maths with this mindset though. A
lot of topics seem intuitively easy, but the proofs only come somewhere near
the end of a degree level course.

It's a very healthy mindset to have, but it's a blessing and a curse. Some
people are just very good at just abstracting away the details and getting on
with things; what seems like "clicking" is not always the same as intuition.
Probably it's good to operate in both modes. It's a really really useful skill
to know when you need to care about the internals and when you can safely
ignore them.

~~~
finaliteration
I’ve definitely learned that now after 10 years of development experience. But
as a curious kid who didn’t just want to memorize and regurgitate it was quite
a challenge. I’ve debated restarting mathematics all the way from basic
algebra and geometry to see if I’d do any better these days.

~~~
ficklepickle
I noticed my high school math(s) teachers were very bad at explaining why and
what we were doing.

Arbitrary example:

One teacher kept saying "f(x)" but couldn't explain what a function is. He
just said "it's anything", then "don't worry about it". If he had even said "a
function is like a machine that takes number(s) as input, changes them with a
formula and outputs the new number(s)", I think it would have helped us grok.

I think he understood math(s) so well that he couldn't relate to someone who
didn't know what a function was.

~~~
diffeomorphism
> If he had even said "a function is like a machine that takes number(s) as
> input, changes them with a formula and outputs the new number(s)", I think
> it would have helped us grok.

Helpful but not quite right and one of the common misconceptions students seem
to carry over from high school.

A function is something that takes inputs out of a set (its domain, e.g.
people in this class) and gives you exactly one output with a prescribed data
type (e.g. a date. The function than for instance being person -> birthdate).
Neither numbers nor a formula are needed.

> I think he understood math(s) so well that he couldn't relate to someone who
> didn't know what a function was.

I think he probably could, but the syllabus said explicitly not discuss this
("too abstract") and there is time pressure. High school maths mostly is
somewhat handwavy and stringing "definitions" together by examples. So you
would mostly see lots of examples of functions and the "definition" of
'function' is then simply "things like that".

------
yters
I have many degrees in computer science, and have used almost none of the
knowledge in programming jobs. So, the content is fairly useless, practically
speaking. I've also found the more I focus on theoretical elements while at
work, the more useless I become. The actually useful elements are big picture,
and can probably be taught in one or two classes. Much more useful than
technical knowledge are the abilities to reason about systems and solve
problems. In my opinion, the CS classes seem to be almost purposefully obtuse.

~~~
agumonkey
Anyone else concur with yters experience ?

~~~
skylark
It really depends on what kind of development you're doing.

The majority of software engineers are application developers making CRUD
websites or mobile apps, so that perspective is the one to come up most often.
I also happen to be one of those developers.

The challenges of application development are related to transforming data,
handling asynchronous operations, managing state, and picking elegant
abstractions that solve your problems. The intuition for these things is
mostly picked up through hours of professional development, seeing good code,
and shooting yourself in the foot a couple of times.

While there are some harder problems in app dev which do require deeper
computer science understanding, they're extremely rare. I suspect this is
different for people doing things like video game development, although I
don't have any experience there so I can't speak to that.

~~~
hobls
Even most of video game development is simply using features of the existing
engine. Some basic 3D math is required, but nothing crazy. You do find some
gnarly problems in engine development though. (And some of the sub-disciplines
like the network and graphics programmers.)

~~~
agumonkey
So CS should get a job at tooling companies because that's where deep things
are done ?

~~~
hobls
I don’t think it’s nearly that simple. Some teams are product teams, and they
operate higher in the stack. Some teams are straight engineering teams, and
they operate much lower in the stack. Lower does not always equal more
technical though. A product team dealing with incredible scale can still
require deep CS knowledge.

My experience is that teams that act as a platform (and I’m using this term
very loosely) tend to have lower level problems to solve. Think of AWS teams
vs. large companies. A large company might be dealing with high scale;
something like 100k+ transactions per second. An AWS team can have many large
companies as their customers, so their scale gets ridiculous; much higher than
any single company. This can require more traditional CS knowledge.

Some individual engineers love shipping products though — they like writing a
LOT of code and getting things out the door. Some engineers like very
carefully working on MASSIVE systems, but they end up releasing way less code.
Other engineers like working on very low level embedded systems or whatever.

There are a lot of problems to solve, and none of them are necessarily
strictly harder than each other. Some people who can support systems at
incredible scale simply cannot cope with the speed of back to back product
launches, and vice versa. There are tons of types of talent.

------
mlpinit
This seems like a thought out list of recommendations. I have enjoyed going
through some of those books myself. However, the persuasive argument seems
rather biased and somewhat toxic. There are many software developers out
there, without a strong CS background, who write useful tools used by other
developers. Does anybody here use Homebrew? The author admits that Homebrew is
not the perfect software, but I think we can all agree that it's highly
successful and helps many developers every day.

The field of computer science can be rather punishing if you don't grow up
with a STEM mentality. I don't think there's a need to put any more pressure
on developers and tell them they are not on a path to make enough money, that
they will not work on interesting problems and that they have to spend another
900 to 1800 hours before they are worthy.

We should instead foster a mentality of inclusion and promote learning by
getting people excited about spending 100 hours on a particular subject and
not persuade people to learn based on the fear of missing out. And we're not
addressing the really big elephant in the room. So many bright people spend
900 to 1800 hours developing their CS skills and end up working on trivial
things that could just as easily be tackled by somebody with a bootcamp
background.

[https://www.quora.com/Whats-the-logic-behind-Google-
rejectin...](https://www.quora.com/Whats-the-logic-behind-Google-rejecting-
Max-Howell-the-author-of-Homebrew-for-not-being-able-to-invert-a-binary-tree)

------
Waterluvian
There aren't two types of software engineers. It's a spectrum, possibly
multidimensional. The attraction to declaring two types of any kind of person
is that you can bin all the desirable and undesirable traits together.

------
bogardon
My personal experience is that I got bored with frontend and pushing pixels,
and when I tried to switch into infra work I found my incomplete picture of CS
made it hard for me to grasp concepts other seem to take for granted. Maybe
you don't have to have a CS degree, but even having a survey knowledge of
major CS topics will at least give you more confidence.

~~~
Waterluvian
I'd love to know what kinds of concepts you struggled with.

I do maybe 30% front end, then a whole bunch of everything else and often
wonder what entire categories I'm blind of.

~~~
bogardon
Just like OS concepts like sockets/files/pipes and how clang/ld/dyld actually
works.

------
lainon
previous discussion, 237 comments:

[https://news.ycombinator.com/item?id=13862284](https://news.ycombinator.com/item?id=13862284)

------
jokoon
Of course if you read every available online course, buy books, you can teach
yourself CS.

I'm always more interested in reading quality material, that teaches things
quickly and efficiently, with practice and not just long theory, without going
into dark details. Those material are more rare. It's also often more
interesting to learn about subjects you're interested into, instead of just
"learning CS".

I have an allergy to academic materials, and reading books that teach theory
without explaining their application. Math is important, but it's a mean to an
end, and to me it's better to teach CS with code. You cannot teach the proper
math to everybody. The finality of computers is to use them by writing code
and algorithms that perform well or better. Analyzing computability and other
theory seems like applied math, so it's not really applied to computers
science in my mind.

Being able to pick up machine learning is great, but there won't be many
individuals using that sweet math to do CS research. I used to believe
programming was always a field of research in a way. It's not. You don't see
random developers building ground breaking algorithms that change the world.
That doesn't happen. Programming is about engineering and tinkering. You don't
need to teach yourself computer science, you need to teach yourself more math,
or learn programming, or learn electronics.

------
hackermailman
I didn't really get algorithm analysis, beyond the standard sequential
analysis of this simple operation maps to X complexity, until I did some
complexity theory then it all sort of came together
[https://functionalcs.github.io/curriculum/#sec-12-1](https://functionalcs.github.io/curriculum/#sec-12-1)

------
noetic_techy
Does this even matter given that Apple is developing a new screen technology?

[https://www.bloomberg.com/news/articles/2018-03-19/apple-
is-...](https://www.bloomberg.com/news/articles/2018-03-19/apple-is-said-to-
develop-displays-to-replace-samsung-screens)

------
blackrock
I think the problem with Computer Science is that the focus has been on the C
and C++ programming languages.

It goes back to the 1970s. C was created to have all these cute little tricks
that you could do to manipulate your data in memory. This led to pointers and
all the fancy pointer arithmetics, that allowed your program to run a few
clock cycles more efficiently. But, the cost is that you shoot yourself in the
foot, once in a while.

Fast forward to now, and squeezing a few extra clock cycles here and there,
and memory usage conservancy is largely irrelevant, except for a few edge
cases.

C is just a bad programming language. And C++ just inherited all its defects,
just to bring in Objects. But the objects were a poorly designed idea, and was
terribly executed.

In C and C++, instead of just focusing on your problem, you have to manage the
language, and its built in defects.

Then came Java. And it was the opposite reaction to C++. No more pointer
arithmetics, everything is now a reference. Ok, good. But, it created another
problem. The framework monstrosity. Learning the language itself is simple
enough. But having to work with someone else's poorly designed framework, that
makes no logical sense, is just unbearable. In Java, you now have to manage
the framework.

I like Python for its brevity and conciseness. And especially for its
flexibility with functions. It allows you to program in a pure functional
style. It's a breath of fresh air. I can build out my code like lego blocks,
stress test each function, and then connect it all together. And the results
work flawlessly. Except for one catch, it runs a little slower.

I'm hoping this move into Functional Programming will be the next true wave to
come into the computer industry.

------
_t94r
How does it compare to OSSU ([https://github.com/ossu/computer-
science/blob/dev/README.md](https://github.com/ossu/computer-
science/blob/dev/README.md)) ?

~~~
gruglife
At the bottom of the website, the authors compare the two and freeCodeCamp.

How does this compare to Open Source Society or freeCodeCamp curricula?

The OSS guide has too many subjects, suggests inferior resources for many of
them, and provides no rationale or guidance around why or what aspects of
particular courses are valuable. We strove to limit our list of courses to
those which you really should know as a software engineer, irrespective of
your specialty, and to help you understand why each course is included.

freeCodeCamp is focused mostly on programming, not computer science. For why
you might want to learn computer science, see above.

~~~
karimdag
I was on mobile so didn't get to scroll to the bottom of it. Thanks!

------
l39
I think adding a concrete language (most probably C) and a course for OOP to
the list might prove useful.

~~~
furo
When you say "concrete language (most probably C)" are you referring to using
one language throughout each subject?

~~~
l39
Not one language per subject. A separate subject to have basics strong. I feel
learning C as a subject and getting concepts like pointers right might prove
useful while learning datastructures and algorithms. The article assumes
learning a language is very easy. But for a self taught programmer its easy to
fall into the trap of straightaway going to high level language like
dynamically typed languages. It would be more appropriate to learn C followed
by datastructures followed by compiler design in that order.

~~~
furo
Late reply, but looks like C is covered in the Computer Architecture section.
How deep does it go into C? That I don't know.

