6 ms·
Over the last three years I've personally taught hundreds of developers how to program, either directly on indirectly. I've written curriculum at all levels.
by jfarmer 12y ago
Over the last three years I've personally taught hundreds of developers how to program, either directly on indirectly. I've written curriculum at all levels. I co-founded Dev Bootcamp (http://devbootcamp.com http://devbootcamp.com) and am currently working on CodeUnion (http://codeunion.io http://codeunion.io). I also am a board member and instructor at Mission Bit (http://missionbit.com http://missionbit.com).
I'm pointing this out because I have strong opinions about how to teach beginners backed up by a non-trivial amount of success.
I disagree with Evan's conclusions, although I agree with the spirit of most of it. I don't know how much experience Evan has teaching or what opinions he has about how teaching/learning works, but where and how he misses the mark are what I'd expect from someone who is a very experienced engineer but has limited experience teaching a wide range of people how to program.
Here's my summary of Evan's article.
To be a good programmer it's necessary to have a mental model of how computers actually do their work. Languages like Python, Ruby, JavaScript, etc. make it difficult (if not impossible) for beginners to develop an accurate model. C, however, forces the programmer to build an accurate mental model of what their computer is actually doing. What's more, it isn't too difficult for ("smart") beginners to learn as their first language. Therefore, we ought to teach more beginners C.
I think his claim is actually a little stronger than that — he's almost saying that teaching something other than C is a disservice to students — but I don't want to be unfair.
I agree that students need a mental model of how computers actually do their work in order to be a good programmer. I also agree that among all the languages we have out there, C is the one that most closely approximate's the computer's internal model of how it does its work. On Quora, someone asked me what are the 5 language one should learn. At the top of the list was C. I said: "Learn C. C is the best language to learn if you want to get a visceral feeling for computation from a computer's perspective. " ()
I also recommended:
- Ruby or Python
- Scheme or Clojure
- Haskell
- Erlang or another "oddball" language like Forth, APL, or Prolog.
Link: https://www.quora.com/Knowing-what-you-know-now-what-are-the-top-5-computer-languages-to-learn/answer/Jesse-Farmer https://www.quora.com/Knowing-what-you-know-now-what-are-the...
More generally, you want students to have an accurate mental model of _computation_, not just how computers work. There are many perspectives and one doesn't really "see" the overall picture until one has adopted, compared, and related many different perspectives.
While I'll agree that Python or Ruby might not give a student an accurate mental model of how a computer works on the inside, you won't be able to convince me that they don't give students _one_ accurate mental model of _computation_.
For a beginner, we're going from a place of no model of computation to some model of computation. C's perspective on the matter is one perspective. Haskell's is another. Smalltalk's is yet a third.
As a teacher, these are my goals:
- Give a student _some_ accurate model of computation
- Give them the tools to refine that model over time
- Develop a sense of consistent forward momentum
- Set them up to do all of the above without being in my presence
IMO, whatever language we teach first should be chosen with these goals in mind. A beginner's first language is a beachhead. If we do our jobs correctly, students will synthesize other perspectives as they develop as programmers.
I think Evan's rebuttal to this is encapsulated in this quote:
> So Python programmers, as a rule, never get around to learning C.
Well, maybe that's the problem! Maybe we should be teaching students in a way where the _need_ to learn C is obvious to the student, where the student sees a C-shaped hole in their programming knowledge (so to speak).
At CodeUnion, we're absolutely not shy about diving into the Ruby interpreter's internals, for example. Want to know what a Ruby method does? Let's look at the source code! It won't bite.
The problem isn't that students aren't eating their spinach. The problem is that students aren't being exposed to situations where they see the lack of spinach is the problem.
The same is true of more abstract concepts like data structures, by the way. We can teach binary trees all day long, but it's not going to "click" for a student until they have a binary-tree-shaped hole in their life.
Focus on getting them to that place and they'll be _begging_ you to teach them C, data structures, functional programming, or whatever else you think is the really important stuff.
- lightcatcher 12y agoI hugely agree with this. I first learned Java in a year long high school class. As soon as the class was over, I knew I liked programming and wanted to become a better programmer, but I also had the feeling that there had to be something less painful that Java to program with. This lead me to Python, which I used for everything over the next two years. From Python, I also learned web programming with Django and Flask. Eventually I decided to try to write an IRC bot in Python. During this effort, I realized I knew nothing about networking, concurrency (how does gevent work?), operating systems, and how to do non-trivial IO. Similarly, I also ran into performance and memory problems with some numpy code, and I started to wonder how does this stuff work and why is numpy so much faster than anything I can write in pure Python? These were my "C shaped holes". Around the time I discovered I had these "C shaped holes" is when I started college, which was a good place for me to take low-level programming classes and fill the holes. Besides getting a student motivated, maybe the hard part of education is having students realize that they have these holes.
- e12e 12y agoThis turned into a bit of a rant, but hopefully it does add something to the discussion. You make some interesting points, but in my (limited) anecdotal experience, C is a pretty awful language. Of all the languages I half-way know, I think I'm still least comfortable with C. Why not start out by teaching assembler? Especially post 32bit x86, assembler (intel syntax) is rather pleasant. It allows highlighting lots of things that are commonly hidden in C: calling conventions, different types of strings (eg: C vs Pascal) etc. C is obviously very useful as a "real-world" language. If you need to add a driver you need to Linux, or patch a bug in your shell (or shell utility) etc -- knowing at least enough C to be dangerous can be very helpful. You'll likely be able to put C to good use re-implementing critical sections of python/ruby/whatever code. But IMNHO C still remains a rather awful language. For some reason, I feel that pointers are easy in Pascal (and assembler) and hard to grasp in C -- as far as I can tell this is entirely a syntactical issue for me. In the future (post rust 1.0), perhaps I'd recommend assembler, rust and some other high-level language (or two...). I find it hard to recommend Pascal -- while compilers exist, it is a little too much of a "teaching language" -- and a little too far on the outside of everything. Ada might be an interesting option. Perhaps assembler > C > python. Or assembler > SBCL (Steel bank common lisp) -- because it integrates well with assembler, allowing the user to easily "peek under the covers". C is awfully low level -- and yet also surprisingly high-level. There's no sane, canonical way to handle text (that is utf8/unicode -- not merely ascii). I'm not entirely sure C++ is much better in this regard, but I still think Storstroup's contrast between "beginner C" and "beginner C++" from 1998 is interesting[1]. I'd be curious what kind of production level code a beginning C programmer produces, and for what kind of problems. Fundamentally though, I'm not sure there is a good "one way fits all". A lot of people will be served fine with only Python or Ruby (or Julia). Thinking too much about how the computer works can also be a hindrance, I think. Getting actual work done, does seem to hinge on joining together proven, useful tools. Be that tool Berkley DB, SQlite, Postgres, levledb, Riak, redis -- or text files (for example). Or protobuf or json or xml. Etc. At any rate, I fail to see, from the point of "understanding how the computer works" -- it helps very much to learn (just) C. Without assembler, I think most of the useful lessons are lost -- and I'm not convinced the number of lesson most obvious in C -- but not covered by assembler on one end, and a high level language on the other -- are that many? [1] http://www.stroustrup.com/new_learning.pdf http://www.stroustrup.com/new_learning.pdf