March 27, 2020 2:31 PM

Going Online

It's been a long time since I've written here. In fits and starts over a couple of weeks, we went from "Wow, coronavirus is in the news a lot" to "all teaching is online through the end of summer, and Eugene has a lot of work to do". The new work included rearranging faculty candidates who were not allowed to fly to campus, looking to cover courses for a faculty who would be taking leave before the end of the semester, and -- of course -- moving my own course online.

This is new territory for me. I've never taught online, and I've never made videos for my students before. One bit of good news is that I have a lot of textual material online already: detailed lecture notes, exercises, homework assignments, every line of code we write or examine in class, all my exams, and a surprising amount of bonus material and extra reading. (Few students take advantage of the extra stuff, but I can't bring myself not provide links to it for the few who do.)

Over break, I made my first video, walking through a problem from our last homework assignment before break. I recorded three takes before having something I was willing to show students. It is rough and wordy, but not too bad for a first effort (well, v 1.03).

We now have a week of classes in the books. This is an unusual week in my course even under typical conditions. It consists a two-day in-class exercise on which students worked in groups of two or three to write a lexical addresser for a little language. With students segregated in their own apartments and hometowns, the intended group collaboration disappeared. Most of our students are still adjusting to the new learning conditions and figuring out how to take all of their courses online at home.

On Tuesday, I made one short video to review briefly the ideas about variable declarations and references that we had studied before break. After they watched the video, I turned them loose with my usual session notes, modified so that hints I would typically offer in class and document in a web page for later review hidden away on their own web pages. This way, students could work on the problem and only click on a hint when they needed a nudge. A few students showed up in a Zoom room and worked during the assigned class time, so I was able to interact with them in real time and answer questions. On Thursday, we re-oriented ourselves to the problem, and I live-coded a solution to the problem. I recorded the session for students to watch later, at their leisure.

I've already learned a bit, only one week in. The temptation to write a long piece of code and talk through the process is great. The students who braved Thursday's session let me know that they tuned out after a while, only to bring their attention back later, somewhat out of synch with my presentation. That's not much different from what happens in a long lecture, of course, but when I'm standing in a room with the students, I'm more likely to notice their boredom or distraction and step out of the lecture sooner. Talking to a few students in Zoom, especially when they have their video off, made it too easy to talk and talk without a break. Over many years of teaching face-to-face, I've learned how to mix class up a bit and not get into long ruts. I'll have to be more consciously aware of those lessons as I do demos over Zoom.

I'm still a little nervous about the rest of the semester, but also a little excited. In what ways can going online, even for only a month and a half, improve my course and materials? Putting session notes up over the years has already forced me to be more careful in how I write explanations and more detailed in the code I post. Now, with little or no face-to-face interaction (most students will come to a session after it ends), how will I need to improve my presentation and the materials I provide? How much will my inexperience making videos limit the level of quality I can achieve over six weeks?

For now, I plan to keep things as simple as possible. I'm not sure what technology my students have available to them at home, or the conditions under which they must work. I am still using email and my course website (a very simple static site that would feel at home in 2000) as my main ways to present material, and have added Zoom as a to interact with students in lieu of regular class time. I will make a few short video to demonstrate ideas, to augment the written material and give students another sensory input with which to learn. I don't expect the videos to be great, or even good, but I hope they help my students. I also hope that, with practice, I get better at making them.

Sadly, I won't be in a classroom with this group of students again this year. I'll miss that. They are good people, and I enjoy working with them. This is a strange way to end a school year, and a reminder of how fortunate I am to get to teach.


Posted by Eugene Wallingford | Permalink | Categories: Teaching and Learning

March 15, 2020 9:35 AM

Things I've Been Reading

This was a weird week. It started with preparations for spring break and an eye on the news. It turned almost immediately into preparations for at least two weeks of online courses and a campus on partial hiatus. Of course, we don't know how the COVID-19 outbreak will develop over the next three weeks, so we may be facing the remaining seven weeks of spring semester online, with students at a distance.

Here are three pieces that helped me get through the week.

Even If You Believe

From When Bloom Filters Don't Bloom:

Advanced data structures are very interesting, but beware. Modern computers require cache-optimized algorithms. When working with large datasets that do not fit in L3, prefer optimizing for a reduced number of loads over optimizing the amount of memory used.

I've always liked the Bloom filter. It seems such an elegant idea. But then I've never used one in a setting where performance mattered. It still surprises me how well current architectures and compilers optimize performance for us in ways that our own efforts can only frustrate. The article is also worth reading for its link to a nice visualization of the interplay among the parameters of a Bloom Filter. That will make a good project in a future class.

Even If You Don't Believe

From one of Tyler Cowen's long interviews:

Niels Bohr had a horseshoe at his country house across the entrance door, a superstitious item, and a friend asked him, "Why do you have it there? Aren't you a scientist? Do you believe in it?" You know what was Bohr's answer? "Of course I don't believe in it, but I have it there because I was told that it works, even if you don't believe in it."

You don't have to believe in good luck to have good luck.

You Gotta Believe

From Larry Tesler's annotated manual for the PUB document compiler:

In 1970, I became disillusioned with the slow pace of artificial intelligence research.

The commentary on the manual is like a mini-memoir. Tesler writes that he went back to the Stanford AI lab in the spring of 1971. John McCarthy sent him to work with Les Earnest, the lab's chief administrator, who had an idea for a "document compiler", a lá RUNOFF, for technical manuals. Tesler had bigger ideas, but he implemented PUB as a learning exercise. Soon PUB had users, who identified shortcomings that were in sync with Tesler's own ideas.

The solution I favored was what we would now call a WYSIWYG interactive text editing and page layout system. I felt that, if the effect of any change was immediately apparent, users would feel more in control. I soon left Stanford to pursue my dream at Xerox PARC (1973-80) and Apple Computer (1980-1997).

Thus began the shift to desktop publishing. And here I sit, in 2020, editing this post using emacs.


Posted by Eugene Wallingford | Permalink | Categories: Computing, General

February 29, 2020 11:19 AM

Programming Healthily

... or at least differently. From Inside Google's Efforts to Engineer Its Food for Healthiness:

So, instead of merely changing the food, Bakker changed the foodscape, ensuring that nearly every option at Google is healthy -- or at least healthyish -- and that the options that weren't stayed out of sight and out of mind.

This is how I've been thinking lately about teaching functional programming to my students, who have experience in procedural Python and object-oriented Java. As with deciding what we eat, how we think about problems and programs is mostly unconscious, a mixture of habit and culture. It is also something intimate and individual, perhaps especially for relative beginners who have only recently begun to know a language well enough to solve problems with some facility. But even for us old hands, the languages and mental tools we use to write programs can become personal. That makes change, and growth, hard.

In my last few offerings of our programming languages course, in which students learn Racket and functional style, I've been trying to change the programming landscape my students see in small ways whenever I can. Here are a few things I've done:

  • I've shrunk the set of primitive functions that we use in the first few weeks. A larger set of tools offers more power and reach, but it also can distract. I'm hoping that students can more quickly master the small set of tools than the larger set and thus begin to feel more accomplished sooner.

  • We work for the first few weeks on problems with less need for the tools we've moved out of sight, such as local variables and counter variables. If a program doesn't really benefit from a local variable, students will be less likely to reach for one. Instead, perhaps, they will reach for a function that can help them get closer to their goal.

  • In a similar vein, I've tried to make explicit connections between specific triggers ("We're processing a list of data, so we'll need a loop.") with new responses ("map can help us here."). We then follow up these connections with immediate and frequent practice.

By keeping functional tools closer at hand, I'm trying to make it easier for these tools to become the new habit. I've also noticed how the way I speak about problems and problem solving can subtly shape how students approach problems, so I'm trying to change a few of my own habits, too.

It's hard for me to do all these things, but it's harder still when I'm not thinking about them. This feels like progress.

So far students seem to be responding well, but it will be a while before I feel confident that these changes in the course are really helping students. I don't want to displace procedural or object-oriented thinking from their minds, but rather to give them a new tool set they can bring out when they need or want to.


Posted by Eugene Wallingford | Permalink | Categories: Patterns, Software Development, Teaching and Learning

February 23, 2020 1:14 PM

One Way I'm Like Tom Waits

At one point in this conversation between Elvis Costello and Tom Waits, the two songwriters discuss some of the difficulties they face in the creative process. Costello remarks that he sometimes writes notes that he can't sing, only to be disappoint himself when he gets into the studio. Waits commiserates:

Anything that has to travel all the way down from your cerebellum to your fingertips, there's a lot of things that can happen on the journey. Sometimes I'll listen to records, my own stuff, and I think god, the original idea for this was so much better than the mutation that we arrived at. What I'm trying to do now is get what comes and keep it alive. It's like carrying water in your hands. I want to keep it all, and sometimes by the time you get to the studio you have nothing.

This is something I notice all the time when I'm teaching. I'll have an idea for class somewhere: walking home, riding the exercise bike, reading something. My brain dives into the process of making the idea real: telling a story, writing code, explaining an idea in relation to things we've done in class before. Then comes deployment. We get into the classroom and... it feels flat. On rare occasions the new ideas bombs, but most often it just seems not quite right. It doesn't feel like what I had in my mind when I first had the idea, and I'm not sure how we ended up feeling the way we feel in class. The idea was so perfect.

Teaching ideas are abstraction. Teaching is concrete. It involves other humans. Their learning is what's important, and sometimes the idea doesn't make the connection intended by the teacher. The classroom is where reality sets in.

There is good news. Sometimes a disappointing or failed idea can be salvaged by analyzing the experience and redesigning the session. But most of the time it never feels as perfect as it did in my head at the moment of conception. Part of the art of becoming a teaching is making friends with this fact and moving forward.


Posted by Eugene Wallingford | Permalink | Categories: Teaching and Learning

February 18, 2020 4:00 PM

Programming Feels Like Home

I saw Robin Sloan's An App Can Be a Home-Cooked Meal floating around Twitter a few days back. It really is quite good; give it a read if you haven't already. This passage captures a lot of the essay's spirit in only a few words:

The exhortation "learn to code!" has its foundations in market value. "Learn to code" is suggested as a way up, a way out. "Learn to code" offers economic leverage, a squirt of power. "Learn to code" goes on your resume.
But let's substitute a different phrase: "learn to cook." People don't only learn to cook so they can become chefs. Some do! But far more people learn to cook so they can eat better, or more affordably, or in a specific way. Or because they want to carry on a tradition. Sometimes they learn just because they're bored! Or even because -- get this -- they love spending time with the person who's teaching them.

Sloan expresses better than I ever have an idea that I blog about every so often. Why should people learn to program? Certainly it offers a path to economic gain, and that's why a lot of students study computer science in college, whether as a major, a minor, or a high-leverage class or two. There is nothing wrong with that. It is for many a way up, a way out.

But for some of us, there is more than money in programming. It gives you a certain power over the data and tools you use. I write here occasionally about how a small script or a relatively small program makes my life so much easier, and I feel bad for colleagues who are stuck doing drudge work that I jump past. Occasionally I'll try to share my code, to lighten someone else's burden, but most of the time there is such a mismatch between the worlds we live in that they are happier to keep plugging along. I can't say that I blame them. Still, if only they could program and used tools that enabled them to improve their work environments...

But... There is more still. From the early days of this blog, I've been open with you all:

Here's the thing. I like to write code.

One of the things that students like about my classes is that I love what I do, and they are welcome to join me on the journey. Just today a student in my Programming Languages drifted back to my office with me after class , where we ended up talking for half an hour and sketching code on a whiteboard as we deconstructed a vocabulary choice he made on our latest homework assignment. I could sense this student's own love of programming, and it raised my spirits. It makes me more excited for the rest of the semester.

I've had people come up to me at conferences to say that the reason they read my blog is because they like to see someone enjoying programming as much as they do. many of them share links with their students as if to say, "See, we are not alone." I look forward to days when I will be able to write in this vein more often.

Sloan reminds us that programming can be -- is -- more than a line on a resume. It is something that everyone can do, and want to do, for a lot of different reasons. It would be great if programming "were marbled deeply into domesticity and comfort, nerdiness and curiosity, health and love" in the way that cooking is. That is what makes Computing for All really worth doing.


Posted by Eugene Wallingford | Permalink | Categories: Computing, Personal, Software Development, Teaching and Learning

February 10, 2020 2:37 PM

Some Things I Read Recently

Campaign Security is a Wood Chipper for Your Hopes and Dreams

Practical campaign security is a wood chipper for your hopes and dreams. It sits at the intersection of 19 kinds of status quo, each more odious than the last. You have to accept the fact that computers are broken, software is terrible, campaign finance is evil, the political parties are inept, the DCCC exists, politics is full of parasites, tech companies are run by arrogant man-children, and so on.

This piece from last year has some good advice, plenty of sarcastic humor from Maciej, and one remark that was especially timely for the past week:

You will fare especially badly if you have written an app to fix politics. Put the app away and never speak of it again.

Know the Difference Between Neurosis and Process

In a conversation between Tom Waits and Elvis Costello from the late 1980s, Waits talks about tinkering too long with a song:

TOM: "You have to know the difference between neurosis and actual process, 'cause if you're left with it in your hands for too long, you may unravel everything. You may end up with absolutely nothing."

In software, when we keep code in our hands for too long, we usually end up with an over-engineered, over-abstracted boat anchor. Let the tests tell you when you are done, then stop.

Sometimes, Work is Work

People say, "if you love what you do you'll never work a day in your life." I think good work can be painful--I think sometimes it feels exactly like work.

Some weeks more than others. Trust me. That's okay. You can still love what you do.


Posted by Eugene Wallingford | Permalink | Categories: Computing, General, Software Development

January 26, 2020 10:23 AM

The Narrative Impulse

Maybe people don't tell stories only to make sense of the world, but rather sometimes to deceive themselves?

It was an interesting idea, I said, that the narrative impulse might spring from the desire to avoid guilt, rather than from the need -- as was generally assumed -- to connect things together in a meaningful way; that it was a strategy calculated, in other words, to disburden ourselves of responsibility.

This is from Kudos, by Rachel Cusk. Kudos is the third book in an unconventional trilogy, following Outline and Transit. I blogged on a passage from Transit last semester, about making something that is part of who you are.

I have wanted to recommend Cusk and these books, but I do not feel up to the task of describing how or why I think so highly of them. They are unorthodox narratives about narrative. To me, Cusk is a mesmerizing story-teller who intertwines stories about people and their lives with the fabric of story-telling itself. She seems to value the stories we tell about ourselves, and yet see through them, to some overarching truth.

As for my own narrative impulse, I think of myself as writing posts for this blog in order to make connections among the many things I learn -- or at least that is I tell myself. Cusk has me taking seriously the idea that some of the stories I tell may come from somewhere else.


Posted by Eugene Wallingford | Permalink | Categories: General, Personal

January 22, 2020 3:54 PM

The Roots of TDD -- from 1957

In 1957, Dan McCracken published Digital Computer Programming, perhaps the first book on the new art of programming. His book shows that the roots of extreme programming run deep. In this passage, McCracken encourages both the writing of tests before the writing of code and the involvement of the customer in the software development process:

The first attack on the checkout problem may be made before coding is begun. In order to fully ascertain the accuracy of the answers, it is necessary to have a hand-calculated check case with which to compare the answers which will later be calculated by the machine. This means that stored program machines are never used for a true one-shot problem. There must always be an element of iteration to make it pay. The hand calculations can be done at any point during programming. Frequently, however, computers are operated by computing experts to prepare the problems as a service for engineers or scientists. In these cases it is highly desirable that the "customer" prepare the check case, largely because logical errors and misunderstandings between the programmer and customer may be pointed out by such procedure. If the customer is to prepare the test solution is best for him to start well in advance of actual checkout, since for any sizable problem it will take several days or weeks to calculate the test.

I don't have a copy of this book, but I've read a couple of other early books by McCracken, including one of his Fortran books for engineers and scientists. He was a good writer and teacher.

I had the great fortune to meet Dan at an NSF workshop in Clemson, South Carolina, back in the mid-1990s. We spent many hours in the evening talking shop and watching basketball on TV. (Dan was cheering his New York Knicks on in the NBA finals, and he was happy to learn that I had been a Knicks and Walt Frazier fan in the 1970s.) He was a pioneer of programming and programming education who was willing to share his experience with a young CS prof who was trying to figure out how to teach. We kept in touch by email thereafter. It was honor to call him a friend.

You can find the above quotation in A History of Test-Driven Development (TDD), as Told in Quotes, by Rob Myers. That post includes several good quotes that Myers had to cut from his upcoming book on TDD. "Of course. How else could you program?"


Posted by Eugene Wallingford | Permalink | Categories: Computing, Software Development, Teaching and Learning

January 10, 2020 2:25 PM

Questions

I recently read an interview with documentary filmmaker Errol Morris, who has unorthodox opinions about documentaries and how to make them. In particular, he prefers to build his films out of extended interviews with a single subject. These interviews give him all the source material he needs, because they aren't about questions and answers. They are about stories:

First of all, I think all questions are more or less rhetorical questions. No one wants their questions answered. They just want to state their question. And, in answering the question, the person never wants to answer the question. They just want to talk.

Morris isn't asking questions; he is stating them. His subjects are not answering questions; they are simply talking.

(Think about this the next time your listening to an interview with a politician or candidate for office...)

At first, I was attracted to the sentiment in this paragraph. Then I became disillusioned with what I took to be its cynicism. Now, though, after a week or so, I am again enamored with its insight. How many of the questions I ask of software clients and professional colleagues are really statements of a position? How many of their answers are disconnected from the essential element of my questions? Even when these responses are disconnected, they communicate a lot to me, if only I listen. My clients and colleagues are often telling me exactly what they want me to know. This dynamic is present surprisingly often when I work with students at the university, too. I need to listen carefully when students don't seem to be answering my question. Sometimes it's because they have misinterpreted the question, and I need to ask differently. Sometimes it's because they are telling me what they want me to know, irrespective of the question.

And when my questions aren't really questions, but statements or some other speech act... well, I know I have some work to do.

In case you find Morris's view on interviews cynical and would prefer to ponder the new year with greater hope, I'll leave you with a more ambiguous quote about questions:

There are years that ask questions, and years that answer.

That's from Their Eyes Were Watching God, by Zora Neale Hurston. In hindsight, it may be true or false for any given year. As a way to frame the coming months, though, it may be useful.

I hope that 2020 brings you the answers you seek, or the questions.


Posted by Eugene Wallingford | Permalink | Categories: Software Development, Teaching and Learning

January 06, 2020 3:13 PM

A Writing Game

I recently started reading posts in the archives of Jason Zweig's blog. He writes about finance for a living but blogs more widely, including quite a bit about writing itself. An article called On Writing Better: Sharpening Your Tools challenges writers to look at each word they write as "an alien object":

As the great Viennese journalist Karl Kraus wrote, "The closer one looks at a word, the farther away it moves." Your goal should be to treat every word you write as an alien object: You should be able to look at it and say, What is that doing here? Why did I use that word instead of a better one? What am I trying to say here? How can I get to where I'm going if I use such stale and lifeless words?

My mind immediately turned this into a writing game, an exercise that puts the idea into practice. Take any piece of writing.

  1. Choose a random word in the document.
  2. Change the word -- or delete it! -- in a way that improves the text.
  3. Go to 1.

Play the game for a fixed number of rounds or for a fixed period of time. A devilish alternative is to play until you get so frustrated with your writing that you can't continue. You could then judge your maturity as a writer by how long you can play in good spirits.

We could even automate the mechanics of the game by writing a program that chooses a random word in a document for us. Every time we save the document after a change, it jumps to a new word.

As with most first ideas, this one can probablyb be improved. Perhaps we should bias word selection toward words whose replacement or deletion are most likely to improve our writing. Changing "the" or "to" doesn't offer the same payoff as changing a lazy verb or deleting an abstract adverb. Or does it? I have a lot of room to improve as a writer; maybe fixing some "the"s and "to"s is exactly what I need to do. The Three Bears pattern suggests that we might learn something by tackling the extreme form of the challenge and seeing where it leads us.

Changing or deleting a single word can improve a piece of text, but there is bigger payoff available, if we consider the selected word in context. The best way to eliminate many vague nouns is to turn them back into verbs, where they act with vigor. To do that, we will have to change the structure of the sentence, and maybe the surrounding sentences. That forces us to think even more deeply about the text than changing a lone word. It also creates more words for us to fix in following rounds!

I like programming challenges of this sort. A writing challenge that constrains me in arbitrary ways might be just what I need to take time more often to improved my work. It might help me identify and break some bad habits along the way. Maybe I'll give this a try and report back. If you try it, please let me know the results!

And no, I did not play the game with this post. It can surely be improved.

Postscript. After drafting this post, I came across another article by Zweig that proposes just such a challenge for the narrower case of abstract adverbs:

The only way to see if a word is indispensable is to eliminate it and see whether you miss it. Try this exercise yourself:
  • Take any sentence containing "actually" or "literally" or any other abstract adverb, written by anyone ever.
  • Delete that adverb.
  • See if the sentence loses one iota of force or meaning.
  • I'd be amazed if it does (if so, please let me know).

We can specialize the writing game to focus on adverbs, another part of speech, or almost any writing weakness. The possibilities...


Posted by Eugene Wallingford | Permalink | Categories: General, Patterns, Teaching and Learning