4 ms·
I like your point about C, and I have a related point: When beginners see something that looks or reads like natural language, it activates the wrong part of t
by dkarl 16y ago
I like your point about C, and I have a related point: When beginners see something that looks or reads like natural language, it activates the wrong part of their brain, and they start to wonder why the computer doesn't "understand" what they're telling it. The idea of a logical machine mindlessly executing symbolic instructions comes pretty naturally for some people, but for others, it's the first Big Idea in programming that they have to spend a lot of time getting used to. Every time they read a line of Ruby code that sounds kind of like stilted English, it causes a little regression in their brain back towards the mental model of the computer as something intelligent that understands the natural-language meanings of keywords and variable names.
Say what you want about BASIC, but programs like "10 ? "HELLO" 20 GOTO 10" never let you forget you were dealing with a brainless, inflexible automaton. Same thing with C.
With C, students are encouraged to ask the question, "What's really happening inside the machine?" There are simple, concrete answers based on a simplified view of the hardware. With Ruby, the answer to that question would be more complicated, and more importantly, it would be less concrete -- it's a long, long way to the hardware. C programmers start out grounded, at least grounded in a simplified model of the machine that is consistent and often helpful. How can beginners develop the habit of looking both up and down the ladder of abstraction, if they're looking down from the mountaintop into a shapeless gray cloudbank?
- xentronium 16y agoAbsolutely agreed. Being the ruby fan myself, I got to admit, that Ruby is so sweet and so abstract that the student starting with ruby is not probably going to lower level language by his own will. People still start programming with pascal in Russia and it's a good thing, imho.
- Xurinos 16y agoOne thing I took away from my SICP experience was the idea that it is languages/abstractions all the way down. You can play in a super high level language like Lisp, or you can mold silicon. Somewhere you have to choose your level of abstraction. If I am teaching somebody how to think about an algorithm like sorting an array, worrying about memory allocations is tangential, an inconvenient burden C delivers unto us. If I want to teach them about working with memory, pointers, and so forth, C is an excellent language for the job. A crazy thing is happening here when we look down upon beginners who want something that feels like a natural language. Why CAN'T we simply say, "I want an app that opens two windows: one with a list of my music files, and the other with cassette controls. Make it so."? Someone could develop a language that does this; AppleTalk, for example, has some crazy high-level stuff similar to this. We have been mentally shackled by our languages. We think in them. It is hubris to suggest that this the canonical way to think when programming, that, for example, "i = i + 1" is the idiom for incrementing a variable. I do believe, to be truly effective in our line of work, that our beginners must eventually come to an understanding of the platform upon which they develop. They must understand memory concepts. They must understand timing concepts. They must understand multiprocessing concepts. But there is no reason to ram C down some poor soul's throat as a first experience. What a terrible language for teaching beginners, full of syntax and slopped-together features. And what a great language to teach somebody in order to prepare them for the industry.
- dkarl 16y agoRuby doesn't encourage you think in multiple layers of abstraction. The next step down from C is a simple machine model with instructions, a CPU, and memory, which is actually kind of helpful for writing code and understanding performance. That layer is visible in the design of C. (It's an oversimplification with no concept of caches, buses, instruction reordering, etc., but those can be added to your mental model when desired.) What's the next layer of abstraction down from Ruby? A byte machine and a garbage collector, neither of which are evident in the language design (to a beginner) and neither of which especially helpful to think about while writing Ruby code. As an abstraction, Ruby just isn't leaky enough. It's too good. It provides no necessity and no reward for thinking about the next layer down. (Plus the next layer down is pretty sophisticated, and pretty abstract from the beginner's point of view. A beginner should know his computer has a CPU and memory and machine instructions, but byte machines and garbage collectors? They will be a mystery until later in the student's development.) A crazy thing is happening here when we look down upon beginners who want something that feels like a natural language. Why CAN'T we simply say, "I want an app that opens two windows: one with a list of my music files, and the other with cassette controls. Make it so."? Someone could develop a language that does this; AppleTalk, for example, has some crazy high-level stuff similar to this. Natural language promises are a lie. When you understand the rigid logical nature of a machine, it's fine. There's no disappointment or confusion when the natural language model breaks; you just fall back from your natural language mental model to your mental model of the machine as a logical computing machine. You can do that because you already have that model of the computer as a mindless, mechanical machine. What happens if you don't already have that mental model? What if your closest familiar model for writing a program is writing instructions for another person? When you don't yet understand the nature of the machine and the nature of programming, natural language-like functionality intentionally misleads you. It tries to hide the nature of the machine from you. It will occasionally fail, and the cumulative effect of dealing with the occasional failures may be that you come to understand that the rigid, uncomprehending behavior that peeks through is the true nature of the machine, but why force a beginner to deal with this now-you-see-it, now-you-don't approach to learning how computers work? Even worse, a beginner might continue to base his model of the computer on the "normal" humanistic behavior and just write the "failures" off as mysterious, uncharacteristic aberrations. When that happens, a programming language that mimics natural languages is actually much worse for beginners than it is for experienced programmers, because it encourages beginners to stick with a mental model by which the machine will always be mysterious and inscrutable. Ruby isn't that close to natural language, of course, but I think it's close enough to occasionally revive a beginner's dominant, inappropriate mental model and hold back their learning. I see that phenomenon in myself with the "loop" macro in Common Lisp; lacking a precise understanding of loop, my first impulse is to say things that sound right, write them as code, and then see what happens. I would never actually get it right that way, of course -- it would just be an exercise in random frustration unless I strictly copied a known example -- but somehow it feels like the right thing to do, instead of developing a valid understanding. When syntax has no pretension to correspond to natural language syntax, it encourages a more appropriate mindset.