Thursday, July 12, 2012

The Inherent Intelligence Principle

Figure it out on your own!


     There is a well-meaning tendency for technical and educational authors to over-explain certain details to the extreme that they actually obfuscate what would otherwise be a simplistic subject. This is an artifact of technical writing which comes from a sense of diligence and thoroughness. Any good technical writer knows that it is crucial to cover as many steps as possible in the explanation of complex instructions.

     However, a good technical writer also knows that the average reader is able to piece certain things together on her own, which saves the writer time and allows the student a little breathing room in what would otherwise be a stiflingly slow read. The problem then becomes, how do I know what material to cover and what to 'gloss-over'? Most writers just make intuitive guesses, for better or worse, and chalk it up to a 'hazard of the trade'.

     Thankfully, this is an unnecessary compromise. There is a shockingly simple and organic way to allow the reader to decide on her own. It requires a more modern way of thinking about technical text and the employment of an idea which is unique to the information age: the hyperlink. And no, you don't need a computer to implement this technique, although it certainly helps simplify the process.

     In many ways, the qualities that make a good technical writer are much the same as those that make a good parent. That is, a good parent shows her children the behaviour that she expects from them, instead of constantly telling them. For instance, if a good parent wants their child to be quiet in public places, then she herself will endeavor to be consistently quiet in public places. Contrast this to the parent who stomps around Walmart yelling at her children over the slightest of offenses and then subsequently yells at her children when they talk too loudly and generally make an embarrassing scene. Kids don't care half as much about what you tell them to do as what you yourself are doing. 

     With this analogy in mind, take the subject if an introduction to Haskell. One of the first (if not the first) things you learn in any programming class is basic IO. There are a number of logical reasons for this which extend beyond tradition; basic IO is essentially what all programs do, at some level or another. A program is an abstract computational device which takes data in from the outside world, processes it, and spits it back out. In order to begin programming (which is the only way to really learn a programming language), you need to understand IO. Once you do, you can create a nearly infinite selection of programs using only a basic understanding of that program's primitives.

     The problem is, Haskell was written by sadists who believe that basic IO is a second class function of computer programming. Don't get me wrong, I like Haskell quite a bit. But, how do you teach computer programming with a language which fervently resists the input and output of data at every turn? 

     What most writers have done so far with Haskell, is show you everything else you can do with Haskell first, and save basic IO for the intermediate stages of the course. This is a HUGE mistake. There simply aren't that many practical programs which can be built without some form of IO. As a result, most Intro to Haskell books have little to no assigned practice work. For instance, Learn You a Haskell, Real World Haskell, and the Intro to Haskell Wikibook: A Gentle Introduction to Programming with Haskell. This goes against all established educational theory concerning Computer Science. In order for a student to gain any thing more than anecdotal knowledge of a new programming language, they must spend more time coding it than reading it.* The reason why authors make this mistake is that explaining Haskell IO to the uninitiated is pretty difficult. However, you don't need to explain everything in order to give a Haskell newb a working knowledge; and therein lies the problem. 

     Humans have an innate understanding of language hard-wired into their gray matter. The main way in which we learn new human languages is through exposure and by differentiating context. That is, we learn multiple ways to say something and deduce the meanings of those slight differences in expression automatically. This natural process of deduction is the foundation of logic and lives in the same spot of gray matter as language itself.  Nobody tells a baby "This is the word 'Mommy': it means the person who feeds you." The baby would never learn if that were the case (due to the Primum Movens paradox). By this same mental process, you can present Haskell IO to Intro students from the get go.

     When they come to some irreducibly complex element of your explanation ( a 'roadblock' ) they can then either click a hyper-link featuring gradually more detailed explanations or flip to the correct page in your manual for elaboration on the sticky subject. 

Here's an example. We want to introduce the student to Haskell IO and assume that the student has no prior CS experience. This should be the only approach when teaching a new language, regardless of the student's level of indoctrination -- see my article on scaffolding**. Here's the didactic text:


     1) Let's display "Hello World" in your computer's terminal:

     Prelude> putStrLn "Hello World"
     Hello World

     1b) Now display a warm-fuzzy phrase of your choice in the terminal

     Prelude> putStrLn "I like Haskell!"
     I like Haskell!

     Here the student just learned that putStrLn is the command for displaying strings onscreen without  being told a thing about it or how it works or what a string is.

     2) Now let's get some information from the person sitting at the keyboard (you) and put it into ghci. Enter this phrase and type  your name at the following prompt.

     Prelude> getLine
     ryan
     "ryan"

     2b) Now get your age and print it onscreen.

     Prelude> getLine
     20
     "20"

   
     Yes these are over-simplifications (for your sake), but the principle is evident and it holds at all higher-levels. A reader doesn't need to be told anything at all about putStrLn, they can look at it, mentally elminate Hello World from their reasoning (because it is the message and thus not the method for displaying said message) and see then that the only remaining commands are putStrLn and "".

  • The user knows that quotations marks are used to display exactly what a person said or is being instructed to say. They will also see that the quotation marks do not appear in the onscreen output. They will have no choice but to deduce that quotation marks are expected when entering a command into putStrLn. So, they usually know to use quotation marks again in the 1b problem. If not, they can just click on the hyperlinked-word putStrLn and be presented with a note explaining this explicitly.
  • They also already know that capital letters are only used at the beginning of a new proper or formal word. So, they know that putStrLn has to be a concatenation of put+str+ln. Even if they don't know what str and ln mean, they know what put means. They will immediately connect put with the fact that they are currently trying to put some data onto the display before them. Since you showed them that this is indeed what putStrLn does, they know to use if for this. 9 times out of 10, they will correctly perform exercise 1b. The same goes for getLine and many more basic commands.
  • By using the same command on two different types of data (letters and numbers) the student now knows that getLine can be used for multiple things; not just for names. All this without mentioning a thing about 'types'.
 
      As I am slowly writing my own Intro to Haskell, you will see better examples of this principle later on. But for now, with a little imagination, you should see that it is also possible to leverage information that exists in every persons brain in order to explain difficult concepts. This is Vigotsky's principle of scaffolding and it's utility in CS should be apparent now. If not, check in from time to time. This is a theme I will be writing on often.

*For a good contrast to this recipe for didactic failure, check out MIT Open Course-Ware's Introduction to Computer Science using Python: Introduction to Computer Science and Programming

**That article is currently still pending.

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.