March 22, 2017 4:50 PM
Part of the Fun of Programming
As I got ready for class yesterday morning, I decided to refactor a piece of code. No big deal, right? It turned out to be a bigger deal than I expected. That's part of the fun of programming.
The function in question is a lexical addresser for a little language we use as a specimen in my Programming Languages course. My students had been working on a design, and it was time for us to build a solution as a group. Looking at my code from the previous semester, I thought that changing the order of two cases would make for a better story in class. The cases are independent, so I swapped them and ran my tests.
The change broke my code. It turns out that the old "else" clause had been serving as a convenient catch-all and was only working correctly due to an error in another function. Swapping the cases exposed the error.
Ordinarily, this wouldn't be a big deal, either. I would simply fix the code and give my students a correct solution. Unfortunately, I had less than an hour before class, so I now found myself in a scramble to find the bug, fix it, and make the changes to my lecture notes that had motivated the refactor in the first place. Making changes like this under time pressure is rarely a good idea... I was tempted to revert to the previous version, teach class, and make the change after class. But I am a programmer, dogged and often foolhardy, so I pressed on. With a few minutes to spare, I closed the editor on my lecture notes and synced the files to my teaching machine. I was tired and still had a little nervous energy coursing through me, but I felt great. That's part of the fun of programming.
I will say this: Boy, was I glad to have my test suite! It was incomplete, of course, because I found an error in my program. But the tests I did have helped me to know that my bug fix had not broken something else unexpectedly. The error I found led to several new tests that make the test suite stronger.
This experience was fresh in my mind this morning when I read "Physics Was Paradise", an interview with Melissa Franklin, a distinguished experimental particle physicist at Harvard. At one point, Franklin mentioned taking her first physics course in high school. The interviewer asked if physics immediately stood out as something she would dedicate her life to. Franklin responded:
Physics is interesting, but it didn't all of a sudden grab me because introductory physics doesn't automatically grab people. At that time, I was still interested in being a writer or a philosopher.
I took my first programming class in high school and, while I liked it very much, it did not cause me to change my longstanding intention to major in architecture. After starting in the architecture program, I began to sense that, while I liked architecture and had much to learn from it, computer science was where my future lay. Maybe somewhere deep in my mind was memory of an experience like the one I had yesterday, battling a piece of code and coming out with a sense of accomplishment and a desire to do battle again. I didn't feel the same way when working on problems in my architecture courses.
Intro CS, like intro physics, doesn't always snatch people away from their goals and dreams. But if you enjoy the fun of programming, eventually it sneaks up on you.
March 18, 2017 11:42 AM
Hidden Figures, Douglas Engelbart Edition
At one point in this SOHP interview, Douglas Engelbart describes his work at the Ames Research Center after graduating from college. He was an electrical engineer, building and maintaining wind tunnels, paging systems, and other special electronics. Looking to make a connection between this job and his future work, the interviewer asked, "Did they have big computers running the various operations?" Engelbart said:
I'll tell you what a computer was in those days. It was an underpaid woman sitting there with a hand calculator, and they'd have rooms full of them, that's how they got their computing done. So you'd say, "What's your job?" "I'm a computer."
Later in the interview, Engelbart talks about how his experience working with radar in the Navy contributed to his idea for a symbol-manipulating system that could help people deal with complexity and urgency. He viewed the numeric calculations done by the human computers at Ames as being something different. Still, I wonder how much this model of parallel computing contributed to his ideas, if only implcitly.
March 17, 2017 9:27 AM
What It Must Feel Like to be Ivan Sutherland
In The Victorian Internet, Tom Standage, says this about the unexpected challenge facing William Cooke and Samuel Morse, the inventors of the telegraph:
[They] had done the impossible and constructed working telegraphs. Surely the world would fall at their feet. Building the prototypes, however, turned out to be the easy part. Convincing people of their significance was far more of a challenge.
That must be what it feels like to be Ivan Sutherland. Or Alan Kay, for that matter.
March 16, 2017 8:50 AM
Studying Code Is More Like Natural Science Than Reading
A key passage from Peter Seibel's 2014 essay, Code Is Not Literature:
But then it hit me. Code is not literature and we are not readers. Rather, interesting pieces of code are specimens and we are naturalists. So instead of trying to pick out a piece of code and reading it and then discussing it like a bunch of Comp Lit. grad students, I think a better model is for one of us to play the role of a 19th century naturalist returning from a trip to some exotic island to present to the local scientific society a discussion of the crazy beetles they found: "Look at the antenna on this monster! They look incredibly ungainly but the male of the species can use these to kill small frogs in whose carcass the females lay their eggs."
The point of such a presentation is to take a piece of code that the presenter has understood deeply and for them to help the audience understand the core ideas by pointing them out amidst the layers of evolutionary detritus (a.k.a. kludges) that are also part of almost all code. One reasonable approach might be to show the real code and then to show a stripped down reimplementation of just the key bits, kind of like a biologist staining a specimen to make various features easier to discern.
My scientist friends often like to joke that CS isn't science, even as they admire the work that computer scientists and programmers do. I think Seibel's essay expresses nicely one way in which studying software really is like what natural scientists do. True, programs are created by people; they don't exist in the world as we find it. (At least programs in the sense of code written by humans to run on a computer.) But they are created under conditions that look a lot more like biological evolution than, say, civil engineering.
As Hal Abelson says in the essay, most real programs end up containing a lot of stuff just to make it work in the complex environments in which they operate. The extraneous stuff enables the program to connect to external APIs and plug into existing frameworks and function properly in various settings. But the extraneous stuff is not the core idea of the program.
When we study code, we have to slash our way through the brush to find this core. When dealing with complex programs, this is not easy. The evidence of adaptation and accretion obscures everything we see. Many people do what Seibel does when they approach a new, hairy piece of code: they refactor it, decoding the meaning of the program and re-coding it in a structure that communicates their understanding in terms that express how they understand it. Who knows; the original program may well have looked like this simple core once, before it evolved strange appendages in order to adapt to the condition in which it needed to live.
The folks who helped to build the software patterns community recognized this. They accepted that every big program "in the wild" is complex and full of cruft. But they also asserted that we can study such programs and identify the recurring structures that enable complex software both to function as intended and to be open to change and growth at the hands of programmers.
One of the holy grails of software engineering is to find a way to express the core of a system in a clear way, segregating the extraneous stuff into modules that capture the key roles that each piece of cruft plays. Alas, our programs usually end up more like the human body: a mass of kludges that intertwine to do some very cool stuff just well enough to succeed in a harsh world.
And so: when we read code, we really do need to bring the mindset and skills of a scientist to our task. It's not like reading People magazine.
March 10, 2017 2:51 PM
Reading Is A Profoundly Creative Act
This comes from Laura Miller, a book reviewers and essayist for Slate, in a Poets & Writers interview:
I also believe that reading is a profoundly creative act, that every act of reading is a collaboration between author and reader. I don't understand why more people aren't interested in this alchemy. It's such an act of grace to give someone else ten or fifteen hours out of your own irreplaceable life, and allow their voice, thoughts, and imaginings into your head.
I think this is true of all reading, whether fiction or nonfiction, literary or technical. I often hear CS profs tell their students to read "actively" by trying code out in an interpreter, asking continually what the author means, and otherwise engaging with the material. Students who do have a chance to experience what Miller describes: turning over a few hours of their irreplaceable lives to someone who understands a topic well, allow their voice, thoughts, and imaginings into their heads, and coming out on the other end of the experience with new thoughts -- and maybe even a new mind.
March 09, 2017 3:20 PM
The Disappearing Millions
Almost a decade ago, I last blogged about my library book version of Scott Hastings's million: leading the league, so to speak, in being the first person to check a particular book out of my university library. Since my first post of the subject twelve years ago, I have apparently mellowed... I'm no longer willing to claim that I lead the league in this stat. Other patrons certainly read more books than I do, and if they keep their eyes open for new acquisitions, they almost surely top me. But even the humbler me can't help but notice that many of the books I check out, whether CS books or literature, seem to be in mint condition. They are being read for the first time, by me.
These days, identifying millions is a more fallible task. The library long ago terminated the practice of stamping a book's due date on a slip inside the front cover. That's all handled electronically now (those infernal computers!), so only the library knows when a book was last checked out. On the long list of cultural experiences lost to changing culture and advancing technology, this one is rather minor, but it's one that a frequent user of libraries might notice feel wistful about. I sometimes do. I always liked seeing the long list of due dates in the books I borrowed; it bestowed on me a sense of kinship with the readers who came before. In the case of all those Asimov and Vonnegut books I re-read, one of the readers who came before was me!
I do think I have another million to my credit, though. A couple of weeks ago, I went over to library to look for some book -- a novel or literary criticism, I can't remember. I looked it over and decided not to check it out after all. I was in no hurry to get back to the office, so I indulged in a few minutes of wandering the stacks to see if anything struck my fancy. I hadn't done that in a while, and I missed it.
I ended up holding Cycling, the 2003 second novel of Greg Garrett. It was purchased long enough ago to have a Due Date slipped glued inside the front cover, but the slip was empty. The cover, pages, and corners gave every appearance of being brand new. Seeing no evidence to the contrary, I stake my claim. When you consider changes in library acquisitions, changes in my reading habits, and the uncertainty today of knowing which books have never been read, how many more times will I have the chance?
"Cycling" was a pretty good read, too, for what that's worth. It was another serendipitous find while wandering the stacks.
March 05, 2017 10:53 AM
"Flying by Instruments" and Learning a New Programming Style
Yesterday afternoon I listened to a story told by someone who had recently been a passenger in a small plane flown by a colleague. As they climbed to their cruising altitude, which was clear and beautiful, the plane passed through a couple thousand feet of heavy clouds. The pilot flew confidently, having both training and experience in instrument flight.
The passenger telling the story, however, was disoriented and a little scared by being in the clouds and not knowing where they were heading. The pilot kept him calm by explaining the process of "flying by instruments" and how he had learned it. Sometimes, learning something new can give us confidence. Other times, just listening to a story can distract us enough to get us through a period of fear.
This story reminded me of a session early in my programming languages course, when students are learning Racket and functional programming style. Racket is quite different from any other language they have learned. "Don't dip your toes in the water," I tell them. "Get wet."
For students who prefer their learning analogies not to involve potential drowning -- that is, after all, the sensation many of them report feeling as they learn to cope with all of Racket's parentheses for the first time -- I relate an Alan Kay story that talks about learning to fly an airplanes after already knowing how to drive a car. Imagine what the world be like if everyone refused to learn how to fly a plane because driving was so much more comfortable and didn't force them to bend their minds a bit? Sure, cars are great and serve us well, but planes completely change the world by bringing us all closer together.
I have lost track of where I had heard or read Kay telling that story, so when I wrote up the class notes, I went looking for a URL to cite. I never found one, but while searching I ran across a different use of airplanes in an analogy that I have since worked into my class. Here's the paragraph I use in my class notes, the paragraph I thought of while listening to the flying-by-instruments story yesterday:
The truth is that bicycles and motorcycles operate quite differently than wheeled vehicles that keep three or more wheels on the ground. For one thing, you steer by leaning, not with the handlebars or steering wheel. Learning to fly an airplane gives even stronger examples of having to learn that your instincts are wrong, and that you have to train yourself to "instinctively" know not only that you turn by banking rather than with the rudder, but that you control altitude primarily with the throttle, not the elevators, speed primarily with the elevators not the throttle, and so forth.
Learning to program in a new style, whether object-oriented, functional, or concatenative, usually requires us to overcome deeply-ingrained design instincts and to develop new instincts that feel uncomfortable while we are learning. Developing new instincts takes some getting used to, but it's worth the effort, even if we choose not to program much in the new style after we learn it.
Now I find myself thinking about what it means to "fly by instruments" when we program. Is our unit testing framework one of the instruments we come to rely on? What about a code smell detector such as Reek? If you have thoughts on this idea, or pointers to what others have already written, I would love to hear from you.
Postscript. I originally found the passage quoted above in a long-ish article about Ruby and Smalltalk, but that link has been dead for a while. I see that the article was reposted in a Ruby Buzz Forum message called On Ceremony and Training Wheels.
Oh, and if you know where I can find the Alan Kay story I went looking for online, I will greatly appreciate any pointers you can offer!
February 28, 2017 3:47 PM
Comments on Comments
Over the last couple of days, a thread on the SIGCSE mailing list has been revisiting the well-tilled ground of comments in code. As I told my students at the beginning of class this semester, some of my colleagues consider me a heretic for not preaching the Gospel of Comments in Code. Every context seems to have its own need for, and expectations of, comments. Wherever students end up working, both while in school and after graduation, their employers will set a standard and expect them to follow. They will figure it out.
In most of my courses, I define a few minimal standard, try to set a good example in the code I give my students, and otherwise don't worry much about comments. Part of my example is that different files I give them are commented differently, depending on the context. A demo of an idea, a library to be reused in the course, and an application are different enough that they call for different kinds of comments. In a course such as compiler development, I require more documentation, both in and out of the code. Students live with that code for a semester and come to value some of their own comments many weeks later.
Anyway, the SIGCSE thread included two ideas that I liked, though they came from competing sides of the argument. One asserted that comments are harmful, because:
They're something the human reader can see but the computer can't, and therefore are a source of misunderstanding.
I love the idea of thinking in terms of misunderstandings between humans and the computer.
The other responded to another poster's suggestion that students be encouraged to write comments with themselves in mind: What would you like to know if you open this code six months from now? The respondent pointed out that this is unreasonable: Answering that question requires...
... a skill that is at least on par with good programming skills. Certainly new CS students are unable to make this kind of decision.
The thread has been a lot of fun to read. I remain mostly of the view that:
- It's better to write code that says what it means and thus needs as few comments as possible. This is a skill students can and should work on all the time time.
- If the code is likely to conflict with the expectations of the people most likely to read your code, then add a comment. This part depends a lot on context and experience. Students are just now earning their experience, and the context in which they work changes from course to course and job to job.
February 23, 2017 4:08 PM
Surrounding Yourself with Beginners
This comment at the close of a recent Dan Meyer post struck close to home:
I haven't found a way to generate these kinds of insights about math without surrounding myself with people learning math for the first time.
I've learned a lot about programming from teaching college students. Insights can come at all levels, from working with seniors who are writing compilers as their first big project, through midstream students who are learning OOP or functional programming as a second or third style, right down to beginners who are seeing variables and loops and functions for the first time.
Sometimes an insight comes when a student asks a new question, or an old question at the right time. I had a couple of students in my compiler course last fall who occasionally asked the most basic questions, especially about code generation. Listening to their questions and creating new examples to illustrate my answers helped me think differently about the run-time system.
Other times, they come while listening to students talk among themselves. One student's answer to another student's question can trigger an entirely new way for me to think about a concept I think I understand pretty well. I don't have any recent personal examples in mind, but this sort of experience seems to be part of what triggered Meyer's post.
People are always telling us to "be the least experienced person in the room", to surround ourselves with "smarter" or more experienced people and learn from them. But there is a lot to be learned from programmers who are just starting out. College profs have that opportunity all the time, if they are willing to listen and learn.
February 19, 2017 10:42 AM
Bret Victor's Advice for Reading Alan Kay
In Links 2013, Bret Victor offers these bits of advice for how to read Alan Kay's writings and listen to his talks:
As you read and watch Alan Kay, try not to think about computational technology, but about a society that is fluent in thinking and debating in the dimensions opened up by the computational medium.
Don't think about "coding" (that's ink and metal type, already obsolete), and don't think about "software developers" (medieval scribes only make sense in an illiterate society).
I have always been inspired and challenged by Kay's work. One of second-order challenges I face is to remember that his vision is not ultimately about people like me writing programs. It's about a culture in which every person can use computational media the way we all use backs of envelopes, sketch books, newspapers, and books today. Computation can change the way we think and exchange ideas.
Then again, it's hard enough to teach CS students to program. That is a sign that we still have work to do in understanding programming better, and also in thinking about the kind of tools we build and use. In terms of Douglas Engelbart's work, also prominently featured among Victor's 2013 influences -- we need to build tools to improve how we program before we can build tools to "improve the improving".
Links 2013 could be the reading list for an amazing seminar. There are no softballs there.