TITLE: The Development Arc of a Program and a Teaching Idea AUTHOR: Eugene Wallingford DATE: December 04, 2008 7:25 PM DESC: ----- BODY: While reading on-line this summer, I ran across a description of how keyless remote entry systems work. I can't find that page just now, but here is a nice description. I never knew how those things worked. Very cool indeed! As I was reading, the programmer in me soon was thinking, "I'd like to write that code". The teacher in me almost as quickly thought, "What a great example for for my programming languages course...": programs with state and shared data. A homework problem was waiting to be written! This week we got to the point in the course at which this is a perfect homework problem. I started thinking about it, but the week was busy... Finally, the night before I was to post the assignment, I sat down to write my solution. Within an hour I have less than a page of code that implements: While thinking before programming -- even agile programmers are allowed to do that -- I realized that "re-programming" a desynchronized transmitter/receiver pair would be beyond scope of my homework assignment and that multiple behaviors (say, unlock and lock, turning on an alarm, etc.) added complexity to the code but no interesting ideas. I also realized that there was no shared data in this problem, but two pieces of state held in common: identical random number generators and a key code. As I programmed, it slowly dawned on me that this problem, in its full form, was surely beyond the scope of my homework assignment. I had a couple of other tasks for them to do, and the keyless entry problem would require both a whole assignment to itself and fairly detailed guidance for the students on how to implement a solution. The interaction between the transmitter and the receiver means that the solution code has to be developed and tested in parallel, and there turned out more to be more layers of indirection in the solution than I had expected: a lambda wrapping a letrec wrapping a let wrapping a letrec wrapping a lambda wrapping one final lambda! That's more complexity than I care for my students to encounter in the context of this assignment. With more time and more of the assignment "real estate", I could perhaps leave design a solution to students and then guide them during the process. But this is a programming languages course, and I'm trying to keep the focus of the course on features of languages, not on the application of functional programming or Scheme. (I do love to have students see functional programming and Scheme applied to "real problems", because so often they view the programming language applications as, well, not real. This problem is especially cool for that purpose, because the ability to create a simple closure over two simple functions is so useful here.) Sigh. The opportunist in me, though, thought, "No problem. Perhaps can will demo the solving of this problem in class." And now I had a new problem: The only code I have is the final version of my program. I can still build a demo, designing a session around how I grew this program, but I will have to re-grow it in my mind and in my lecture notes. Unfortunately, the second time through a solution is never quite like the first for me, and in a way that effects the quality of result. The second implementation usually feels and looks a little too pat, a little too straightforward, too obvious. Most people don't learn much about how to build something by looking only at the final product, and when the final product looks inevitable at every turn, all hope is lost. The process of writing the code, and the decisions made along the way matter -- the insights and the false starts; the intermediate steps. All I have is my final version. If only I had developed this program under version control! At least then I'd have a sequence of intermediate solutions that could help me recover the sequence of decisions and insights and false starts. I know some people use version control for more than developing software; Martin Fowler has even wrote about putting his whole file system under Subversion. I may not want to go that far, but what about the particular case of developing code for a new demo, lecture, or presentation? This seems like one of those ideas someone has already had and profited from. I'm just now getting it. Do you ever do this for purposes of teaching or exposition? Oh, well. I had a lot of fun implementing this code, and that is always a welcome joy. I may yet show it off in class, if only as a finished product. We programmers are often like artists and other creators, and even like parents: we are so proud of our children that we simply must show everyone and brag on them! But turning this solution into a powerful class session about using state and mutually-referential functions must wait until I have more time. Maybe next time I'll try building my new idea code under version control and be able to move more quickly. Now that keyless remote entry is off the table as a homework problem, I am back to the drawing board for a couple of new problems to round out this assignment. Well, the random number generator is a nice stateful problem in its own right. And if I can just simplify the idea of the transmitter/receiver pair, maybe I can create a problem in the spirit of keyless entry systems -- only with security circa 1970 -- that salvages some of my initial excitement for this problem. Hmm.... ~~~~ Postscript.    I wrote the first draft of this entry last night, right after whipping up my solution and despairing. Current students of mine know that I did salvage the idea, because I have already set the homework problems in question before them! The simplification was easier to make than I had feared. The transmitter and receiver use a fixed code and can never be synched. That made all the difference in the complexity of the solution. I left the other parts for extra-credit... -----