Suppose I were to tell you to close your eyes, and then ask if you have a nose. You’re likely to think that’s a very silly question.
“Couldn’t he see I have a nose? It’s in plain sight.” you might say to yourself.
But let me interrupt you right there – that’s not what I’m asking. I want to know if you know whether you have a nose.
Now you’re thinking that question is even stranger. Or perhaps that I’m losing it. Of course you know that you have a nose, yes?
“It’s as plain as, well, the nose on my face” is probably what you’re thinking.
But wait – I persist – I want to know how you know it.
And now you start thinking, “Ah… there must be something to this game. How do I know I have a nose?”
Let’s take a brief detour now and look at the issue using an analogy. Since we’re students of Computer Science, let’s look at a CS analogy: In class, we mostly program using an IDE, typically Xcode, Visual Studio or Eclipse. Now back in the day when I learned to program as a kid, we’d write our programs using plain text editors (no luxury of an IDE, I’m afraid) and manually invoke the compiler to turn the programs into machine code. The compilation of even simple programs often took a few minutes, and so it was important to try and write correct programs from the get-go. Every time a syntax error was found by the compiler meant a rather unbearable additional delay before you could see the fruits of your effort. At least an IDE helps us by reducing the delay to our gratification (Does it really?).
The cool thing about modern IDEs, especially for beginners is, as I’m fond of reiterating in class, that it has our back. It is the first line of defence the system has before we can touch it’s CPU. As a result it’s possible to get a great deal of work done by focusing on the logic of solving the problem at hand, rather than constantly worrying about whether we’ve made a syntax error that the compiler will barf at or written some code that would fry the monitor.
Now, the compiler – which the IDE invokes at some stage of processing your code – is yet another line of defense before your logic hits the CPU. It will reject code that has somehow managed to squeak past the IDE but is syntactically incorrect. Often, a compiler is even invoked in such a way as to look out for potentially dangerous lines of code that you’ll end up shooting yourself in the foot with. This would be code that is syntactically correct, but has unintended adverse effects, like leaking memory. The fact that the IDE and compiler look out for us like this buys us a great deal of relief as we can safely relegate simple safety concerns to them. We’re able to program with the reassurance that our code will be compiled into proper executable instructions and be interpreted and run by the CPU.
But sometimes, after we’ve mastered the language sufficiently, we want to knowingly break a few rules because we find ourselves being held back. We’ll know our goal, and the precise sequence of steps that will lead to it most efficiently, but we’ll also know that the compiler just won’t let us get there because the language syntax explicitly forbids some of what we want to get done. We want the freedom of unbridled assembly language (or even binary machine code as von Neumann is supposed to have liked to program in). We want to talk to the machine at its core with no mediator. We want to speak directly to the CPU.
For programmers who know exactly what they’re doing there are ways to do this. Once you’ve mastered the language to the level where you know its ins and outs, its features and shortcomings, and understand the risks of your actions and how precisely to avoid (or embrace) them, you can write code that escapes the attention of the compiler and the IDE. You can include assembler code fragments in your programs. You can link in modules written entirely in assembler. Such modules would have been impossible to write in any high level language because, for your own safety and in the interests of being productive, an IDE and the compiler function as code filters. They filter out bad code so that the CPU never even gets to see certain harmful instructions. If your program is correct, as far as the CPU is concerned, the executable it steps through is clean. Its image of you is of a flawless programmer who knows how to write executable instructions. And everything works out wonderfully.
So it is with the human mind. You see, the brain is a fantastically fine-tuned filter. Every moment of every day, including moments when you are asleep, the brain is bombarded with millions of data items. If you were consciously aware of each of these sensations, you could accomplish precious little in your life. The brain does a marvelous job of filtering out most of the sensations it’s fed by handling them in sub-conscious layers. What enters your conscious mind is simply a miniscule subset of sensations that reach you, which is what makes it possible to function at a high level in our daily lives.
To be continued…