CS Unplugged: Computer Science Without a Computer
csunplugged.org
csunplugged.org
I've found that a deck of cards and some patience can really help people understand the tiny step by tiny step thinking that is fundamental to computer science and programming. Things like sort this row of cards (following only these rules) and, yeah it's frustrating to do that over and over, lets group those together in a new rule called $X, and so on gets that thinking instilled better than any amount of explaining the programming language ever did. Later, introducing the computer in the mix actually seems easier once the student is accustomed to thinking like a computer.
It's this sort of introspection that's key to understanding computers. We abstract large chunks of computational thinking naturally. It's essential to be able to ask yourself, "How am I really doing this?" - and to come up with an answer.
edited slightly for grammar
It was something like this: http://csunplugged.org/sorting-networks/#Videos
More often than not, the computer facilitates a guess and check programming mentality that isn't just endemic to students, but to our profession in general. I'm certainly not immune to the temptation to fix problems by repeated runs with small tweaks: "Does it work? No... no... no... yes! Move on!" That's not computer science. It's data entry.
It's not that computers have no place in the curriculum. They can be immensely helpful in understanding of complex algorithms, much the same way performing an experiment can lead to a more thorough understanding of physics, or chemistry. However, no one would argue chemistry is about moving chemicals from one test tube to another.
Agreed, and sometimes it's surprisingly tricky to describe what's happening not in terms of the coding abstractions we all know and love, but just in plain English.
I remember I did a contract years ago for a PhD student which was basically doing some statistical analysis of a massive dataset. When I was doing progress reports she'd often drill down and ask, out of genuine curiosity (she was an academic, go figure :-) just how the computer was doing the things I was describing.
I couldn't use abstractions like 'well I just loop over this set and accumulate x and...' because that's gibberish to her - so I had to kind of break down what was actually going on in plain English (obviously with a degree of abstraction from the hardware etc). I did so very awkwardly because I was used to just 'thinking in code', but remember it was very helpful for me to be forced to do this because it really tested that I actually understood what my algorithms were doing.
But obviously there's a limit to the usefulness of this line of thinking. Abstractions are always present - ad adsurdium, we'd never talk about electrons flying around etc. It ceases (except in extremely rare exceptions) to be useful to describe what is actually happening in more detail than 'this black box does X, and I use it with another black box that does Y to achieve Z' right about the level where you're writing 'real' applications with frameworks and whatnot.
A lot of people in programming think of abstraction in terms of AbstractFactoryFactories or LifecycleConfigurators and then start to complain about architecture astronauts and leaky abstractions. But there are more basic abstractions that we use every day, which are perfectly precise, don't leak[1] and are near-indispensible.
[1] Except perhaps in terms of performance.
Absolutely. A coworker has a similar version of that line, which I've committed to memory:
"If you don't understand precisely what you need to do, what makes you think you can tell a computer how to do it?"
I also briefly taught programming, and that's a line I've used more often than I'd like. Another thing I've noticed is that IDEs tend to encourage beginners to perform much random fiddling of code that doesn't work, often creating a mess in the process.
You seem to be a fairly adept programmer. The concept of improvisational programming makes sense for you - you draw on years of experience and training (formal, or not) to feel out a concept when you have a goal in mind but no clear way to get there. You probably perform many small experiments to learn more about the intricacies of whatever you are working on. You can do all this because you've progressed past the beginning stages.
Most beginners simply aren't capable of this. There are too many blind alleys. Too many traps. It's not that I discourage self-directed learning, experimenting or researching - all are essential to learning computer science. Rather I've seen far too many students simply resort to guess and check methodology when face with a problem. This isn't the kind of guided exploration that comes with experience but: "Adding 1 to that index didn't work - I wonder if 2 will? 3? 4? 10? Oh! 12 works! Great - I'm done!"
Incidentally, I have done data entry. My first computer was an Apple II. I used to type in programs from magazines without really understand what they were doing. Even worse, I typed in raw hexadecimal program data. I know what it's like to type something in you don't understand, find out it's wrong, tweak it, and try again ad infinitum (or so it seemed). "Does A9 work? What about AA? AC? ...AF works! Great - I'm done!"
Quote from Alan Kay about Knuth:
When I was at Stanford with the AI project [in the late 1960s] one of the things we used to do every Thanksgiving is have a computer programming contest with people on research projects in the Bay area. The prize I think was a turkey.
[John] McCarthy used to make up the problems. The one year that Knuth entered this, he won both the fastest time getting the program running and he also won the fastest execution of the algorithm. He did it on the worst system with remote batch called the Wilbur system. And he basically beat the shit out of everyone.
And they asked him, "How could you possibly do this?" And he answered, "When I learned to program, you were lucky if you got five minutes with the machine a day. If you wanted to get the program going, it just had to be written right. So people just learned to program like it was carving stone. You sort of have to sidle up to it. That's how I learned to program." - [1]
[1] - http://www.quora.com/How-would-Donald-Knuth-fare-as-a-compet...
I'm unfortunately cursed that I have a lot of trouble starting a problem till I really really understand all it's details and the details of my solution. I basically write down exactly what I want and am going to do on paper
I find that my coworkers that start with a vague idea of what they want (without a complete understanding of the system) but work in quick hack->fix iterations produce results significantly faster.
I don't have a huge sample size, but that's simply what I've observed. The person that finishes first is the person that starts typing first. The one that mulls over everything in their head might have a more elegant solution and a clearer git repo.. but they always finish last
In reality, writing a program in longhand is something everybody could do -- but because nowadays programming is mostly plumbing, you have to empirically test everything.
Anyway, the custom OS ("Waits") made good use of the Data Disc graphics system: it had a built-in interactive line editor, so that when you were in the shell, you could edit your command line (control-d deletes a character, etc., etc.) and see the result in realtime. (This was years and years before Unix got similar features in tcsh and bash and the readline library). All programs inherited this functionality automatically, so Wait's full-screen editor ("E") was simply built on top of it. (Again, years and years before emacs and vi, and all on a system with a per-process address space of only 256K words (about 1Mb), split evenly between data and code.)
So, to finally answer your question: while Knuth did spend his early years programming on punched-card batch systems (where you pretty much had to write out code long-hand before keypunching it), by the time he had started working on TeX he had been exclusively using a full-screen editor on a graphical display for many years.
Doing them on paper, he'd get to a point where he had a good understanding of his solution and was extremely confident that they'd work on the day!
I've never programmed on paper to any real extent but doing crosswords in pen certainly made me better at crosswords.
Being adept at an interactive interpreter, for example, opens up the opportunity for fulfilling (or at least, less frustrating) interactive debugging...to me, being able to debug is at the core of understanding programming. And while that's not pure computer science, per se, it's a great way to not just understand and replicate CS concepts, but to fully test and explore them via immediate feedback. Sometimes I've found that I can only understand an algorithm by implementing it in code, and then tweaking/breaking it to test my assumptions...a computer makes it so that such exploration is not impossibly tedious.
I can always remeber back in 2008 when he gave a special lecture to COSC122-S208 with an early prototype of this program. It was obvious that I wasn't the only one left with a feeling of 'why didn't they just tell us that to start with?' after 10 weeks of battling beginner skills at java and trying to learn data structure concepts and algorithms at the same time.
Joking aside, this can be a very good exercise. I did interviews on the whiteboard, and it did teach me that I have come to rely a little too much on compiling and running to understand the logic I've written.
I'd be fine doing a coding interview with just Notepad.exe or vi or whatever. It takes me ~2 seconds to type a line of code, but more like 10 or 15 seconds to handwrite it [0], and my brain's just not used to that kind of latency. It trips me up.
Plus, on a whiteboard, the mechanics of "oops I need to insert a line... I guess I'll just write it down here and draw a big arrow... ok now I need to rename this variable, but now the name is really long and I can't fit it... wait, what was I doing?".
It just mucks up my process. I don't precisely conceive an entire subroutine before I put fingers to keyboard--my code evolves as I'm writing it. I edit, revise, rethink, and refactor constantly, long before anything's even compiled. Keys and screen facilitate that process a thousand times better than pencil and paper. Handwriting just isn't the best medium for code [1].
[0] And thank god I have a CS education, because if nothing else I at least learned how to write legible braces, brackets, ampersands, and at-signs by hand...
[1] OP is obviously a wonderful idea but that's because it's teaching aspects of CS that aren't code.
I think your use of the term "latency" is a very good way to describe some of the problems around whiteboard coding.
I'd even somewhat prefer a chalkboard.
There are also "programmers" who's entire method of work seems to be to copy+paste blocks of code from Stackoverflow, only changing the minimum amount to make something load and then move onto the next item in their hit list.
I always liked white boarding problems.
I’ve tweaked the exercise a bit though, so I’ll see if I can get those changes written up - the original author gave us permission to use the work as we saw fit back when I worked at the Dept of Comp.Sci. in Oxford.
Maybe what you need for teaching is a computer with a programming language in the firmware, which gives you that language's REPL (and nothing but that) within a fraction of a second of powering up.
I personally think this site is AMAZING and I plan to share it with many of my friends.
Perhaps this is because many of my friends, like my wife, are elementary school teachers and I've seen the kind of resources they usually have to work with.
As far as resources for elementary school kids, this site is far and away the best I've ever seen. They clearly took their time to do things well, knew their target audience, made a site that is super useful to teachers.
Funnily enough, during my first year of my Comp Sci degree I didn't have a computer... I used to print off Java Docs, go home, write a program using pen and paper, and go to uni the next day to write it up. Of course this was what people used to do back in the days of punchcards as well!
Not to say that you should go without a computer, but people in their bubbles seem to think that everyone has a computer, and this just isn't the case - not even in 2015.
Moving forward, our curriculum is going to build those skills up front and off-screen, then move to code. How we build those is a continuing work in progress, but CS Unplugged is a big part of that.
(Attributed to) Dijkstra.
"Computer science isn't a science and it isn't about computers"
(www.jonahkagan.me/projects/writing/cs-essay.html, but I think that isn't the original)
You can learn music without ever touching an instrument, but you can't learn playing an instrument that way.
Similarly, learning computer science is not the same thing as learning to program or learning software engineering.
Earliest use of this quote that I know of is from Abelson in his 1986 lecture teaching SICP: https://youtu.be/2Op3QLzMgSY?t=24
In fact, doing computer science or theory of programming without a computer was remarkably common due to scarce access to hardware, even as recently as the late 80s with people writing BASIC programs on paper before ever getting access to a PC. I'm sure it still happens.
I actually think that teaching CS and programming as hard pragmatic subjects based on doing real-world programming, is likely harmful. The impedance mismatch between contemporary, enormously complicated software systems with the theoretical essentials are too great and may lead to the risk of being unable to think sufficiently abstractly. That is to say, the risk of associating one implementation of a name with the actual first principles of the name in question. See: People being baffled by Plan 9 because they associate "file" as something more specific than a tree node, or generic representation of data.
This still has some effects today in department cultures even though hardware is readily accessible to all now.
In particular I love http://csunplugged.org/error-detection/ as it's a magic trick. I've used this at parties, and I find it funny that it's a computer science concept.
Tim Bell's also super nice, and it's fantastic that he developed this!
http://everyonecanprogram.com/
UK schools are teaching programming with marble runs.
Love this organization with the activities and activities with videos. Great presentation to me.
Ironic is when I take Computer Science Unplugged activities and then put them in a virtual world environment :-)