Saturday, March 17, 2007

Pragmatism in Programing

A book called "The Pragmatic Programmer: From Journeyman to Master" by Andrew Hunt and David Thomas promises to "cut through the increasing specialization and technicalities of modern software development to examine the core process--taking a requirement and producing working, maintainable code that delights its users."

Pragmatism is a school of epistemology. Most of the thinkers who describe themselves as pragmatists consider practical consequences or real effects to be vital components of both meaning and truth. In ordinary usage, pragmatism refers to behavior which temporarily sets aside one ideal to pursue a lesser, more achievable ideal. It is difficult to determine what ideal the authors are setting aside in order to achieve their programming goals, however their list of tips (sample shown below) looks interesting. The Stroop effect is also kind of neat. See also Jon Aquino's blog post for his explanation of the benefits of reading code aloud.

Extracted From The Pragmatic Programmer
by Andrew Hunt and David Thomas.
Copyright 2000, Addison Wesley.
  1. Care About Your Craft. Why spend your life developing software unless you care about doing it well?
  2. Always Use Source Code Control. Source code control is a time machine for your work---you can go back.
  3. Use Blackboards to Coordinate Workflow. Use blackboards to coordinate disparate facts and agents, while maintaining independence and isolation among participants.
  4. Estimate the Order of Your Algorithms. Get a feel for how long things are likely to take before you write code.
  5. Some Things Are Better Done than Described. Don't fall into the specification spiral---at some point you need to start coding.
  6. Costly Tools Don't Produce Better Designs. Beware of vendor hype, industry dogma, and the aura of the price tag. Judge tools on their merits.
  7. Invest Regularly in Your Knowledge Portfolio. Make learning a habit.
  8. Separate Views from Models. Gain flexibility at low cost by designing your application in terms of models and views.
  9. Work with a User to Think Like a User. It's the best way to gain insight into how the system will really be used.
  10. Don't Be a Slave to Formal Methods. Don't blindly adopt any technique without putting it into the context of your development practices and capabilities.
  11. Sign Your Work. Craftsmen of an earlier age were proud to sign their work. You should be, too.

Perpetual Motion and Lossless Infiinite Compression

Once a master was walking with a student.
The student exclaimed, "I have an idea for a new data compression scheme. I'll use a lossless compressor and pipe the output back into the input, looping until the desired size is achieved."
The master considered mentioning Shannon and his Limit,
but instead bought a balloon from a street vendor and releasing the knot, he deflating the balloon and handed it to the student saying,
"Remove the air from this balloon."
At that moment the student was enlightened.

Stepwise Refinement

Khan's Koan

In the days when Khan was studying at ETH,
he was hacking at a terminal when Wirth happened by.
"What are you doing?" Wirth asked him.
"I'm teaching the computer to think," Khan replied.
Wirth reached behind the terminal and unplugged it.
He placed a large blank sheet of paper in front of Kahn,
saying, "First teach the paper to think."
At that moment Khan was enlightened.

Here are a couple of excerpts and links from articles by the master.

Program Development by Stepwise Refinement by Nicklaus Wirth

Programming is usually taught by examples. Experience shows that the success of a programming course critically depends on the choice of these examples. Unfortunately, they are too often selected with the prime intent to demonstrate what a computer can do. Instead, a main criterion for selection should be their suitability to exhibit certain widely applicable techniques. Furthermore, examples of programs are commonly presented as finished "products" followed by explanations of their purpose and their linguistic details. But active programming consists of the design of new programs, rather than contemplation of old programs. As a consequence of these teaching methods, the student obtains the impression that programming consists mainly of mastering a language (with all the peculiarities and intricacies so abundant in modern PL's) and relying on one's intuition to somehow transform ideas into finished programs. Clearly, programming courses should teach methods of design and construction, and the selected examples should be such that a gradual development can be nicely demonstrated.

Computing Science Education: The Road not Taken by Nicklaus Wirth

As computing professionals, it is our duty to speak up against a culture that equates computer literacy with mastering the intricacies of a production programming language.

This reminds me of E. W. Dijkstra’s tale of his worst night after reading the specifications of the new programming language PL/1 in 1965. He said he had the painful vision that in the future programming will be equated with learning PL/1, and computer science with mastering OS/360 JCL. Replace PL/1 by C++ or Java, and JCL by Windows or Linux, and you are miraculously transposed into the present time.

Wednesday, March 14, 2007

Zen and Tic Tac Toe (Part 1)

AI Koan: Sussman attains enlightment

In the days when Sussman was a novice, Minsky once came to him as he sat hacking at the PDP-6.
What are you doing?", asked Minsky.
"I am training a randomly wired neural net to play Tic-Tac-Toe.", Sussman replied.
"Why is the net wired randomly?", asked Minsky.
"I do not want it to have any preconceptions of how to play", Sussman said.
Minsky shut his eyes.
"Why do you close your eyes?", Sussman asked his teacher.
"So that the room will be empty."
At that moment, Sussman was enlightened.

Tic-Tac-Toe is my current favorite in the search for the perfect task to demonstrate good programming practices. I believe it can be used to demonstrate the vast range of solutions that are available for many similar problems, and it should also be a good example of the range of quality in solutions.

Tic-Tac-Toe has a special personal significance to me as it figured in the first piece of hardware that I ever designed in 1969, and it was the first program that I ever wrote using my first personal computer in 1978.

In 1969, I was a sophomore in high school trying to come up with a decent entry for a science fair. I had recently learned to make electric relays using wire, nails, and tin cans, and I decided that it might be possible to wire up nine of these relays to switches and lights in such a way as to play a fair game of Tic-Tac-Toe. I worked for months on the wiring diagram until I came up with what I thought was a solution. Unfortunately, the relays kept sticking and I could never get the thing to work. I never learned whether my solution would have worked if I had access to better hardware.

Later, in 1978, I had bought a Radio Shack TRS-80 microcomputer that had an excellent chess program that I liked. Unfortunately, or perhaps fortunately, the game cassette tape deteriorated after a few months and I was left with no use for the computer. I decided that I would have to learn to program chess myself, so I got out the manual and, quickly getting over my delusions of grandeur, I settled for programming Tic-Tac-Toe. Hundreds of lines of code and about ten hours later, I had a working version of the game that met all of my requirements. I was hooked on programming, but obviously had a lot to learn, since the program was incredibly more complex than my teenage relay machine.

All of these years later, I have decided to revisit the problem of the Tic-Tac-Toe machine with 9 relays and determine if it is indeed possible to construct such an elegant solution to the problem. I will also endeavor to discover if the solution will carry over to software implementation as well, or if it is only possible in dedicated hardware.