May 22, 2018 3:30 PM

Bookends

This weekend, my family headed to St. Paul, Minnesota, to celebrate my younger daughter's graduation from college. The day served as a bookend to the day. seven years ago this fall when I dropped my older daughter off at college. Two beginnings, two endings -- and the beginnings they created.

Graduation day was emotional for me in a different way. It is wonderful gift to hear faculty and friends say such good things about your child. This is a young women I've always known to be special, and now we know some of the ways the rest of the world appreciates her. They appreciate some of the same things I appreciate, but they also know her in ways I do not and so can appreciate her ways I don't always have access to. Another gift.

Off into the world she goes to do her thing. To be honest, though, she's been out in the world for a long time doing her thing and making it a better place. It's one of the things I admire so in her, and in her big sister. I enjoy admiring my daughters as much as I do.

With both daughters out of college, I will miss the time we've spent visiting their college campuses. I tried to savor this weekend more knowing as I do how much I missed my older daughter's campus after she graduated. Of course, now I'll get to visit them in places like Boston and Minneapolis and get to know these cities better, through their eyes. Yet another gift.


Posted by Eugene Wallingford | Permalink | Categories: Personal

May 18, 2018 1:24 PM

Sharing Control

Sidney Lumet, in his book Making Movies, writes:

Arthur Miller's first, and I think, only novel, Focus, was, in my opinion, every bit as good as his first produced play, All My Sons. I once asked him why, if he was equally talented in both forms, he chose to write plays. Why would he give up the total control of the creative process that a novel provides to write instead for communal control, where a play would first go into the hands of a director and then pass into the hands of a cast, set designer, producer, and so forth? His answer was touching. He loved seeing what his work evoked in others. The result could contain revelations, feelings, and ideas that he never knew existed when he wrote the play. That's what he hoped for.

Writing software for people to use is something quite different from writing a play for audiences to watch, but this paragraph brought to mind experiences I had as a grad student and new faculty member. As a part of my doctoral work, I implemented a expert system shells for a couple of problem-solving styles. Experts and grad students in domains such as chemical engineering, civil engineering, education, manufacturing, and tax accounting used these shells to build expert systems in their domains. I often found myself in the lab with these folks as they used my tools. I learned a lot by watching them and discussing with them the languages implemented in the tools. Their comments and ideas sometimes changed how I thought about the languages and tools, and I was able to fold some of these changes back into the systems.

Software design can be communal, too. This is, of course, one of the cornerstones of agile software development. Giving up control can help us write better software, but it can also be a source of the kind of pleasure I imagine Miller got from working to bring his plays to life on stage.


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

May 09, 2018 4:02 PM

Middles

In an old blog post promoting his book on timing, Daniel Pink writes:

... Connie Gersick's research has shown that group projects rarely progress in a steady, linear way. Instead, at the beginning of a project, groups do very little. Then at a certain moment, they experience a sudden burst of activity and finally get going. When is that moment? The temporal midpoint. Give a team 34 days, they get started in earnest on day 17. Give a team 11 days, they get really get going on day 6. In addition, there’s other research showing that being behind at the midpoint--in NBA games and in experimental settings--can boost performance in the second half.
So we need to recognize midpoints and try to use them as a spark rather than a slump.

I wonder if this research suggests that we should favor shorter projects over longer ones. If most of us start going full force only at the middle of our projects, perhaps we should make the middle of our projects come sooner.

I'll admit that I have a fondness for short over long: short iterations over long iterations in software development, quarters over semesters in educational settings, short books (especially non-fiction) over long books. Shorter cycles seem to lead to higher productivity, because I spend more time working and less time ramping up and winding down. That seems to be true for my students and faculty colleagues, too.

In the paragraph that follows the quoted passage, Pink points inadvertently to another feature of short projects that I appreciate: more frequent beginnings and endings. He talks about the poignancy of endings, which adds meaning to the experience. On the other end of the cycle are beginnings, which create a sense of newness and energy. I always look forward to the beginning of a new semester or a new project for the energy it brings me.

Agile software developers know that, on top of these reasons, short projects offer another potent advantage: more opportunities to take stock of what we have learned and feed that learning back into what we do.


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

May 08, 2018 4:45 PM

"Tell Me Something You Learned"

I spent big chunks of the last two days grading final projects and final exams for my Programming Languages course. Grading exams is important but not a lot of fun, so I released a little tension on Twitter as thoughts popped into my head:

I love final exam answers that appear to be randomly generated from a list of terms learned in the course.
Also fun: code that appears to be randomly generated from a list of functions learned in the course.
... and then a student surprises me with a creative, efficient solution. I like those answers just as much.
Answer of the day so far: "Local variables help us be more ambiguous solving many problems at once."

I don't know what that means, but I love it.

I hope folks did not think I was "punching down". I know how stressful final exams are for most students, and I know how challenging a comprehensive final exam in this course is. Students have to write code, explain ideas, and connect ideas to code. It's tough. The tweets were just me having a little fun during what is otherwise a slow, laborious process.

This exam ended differently than any of the previous finals in this course. The final question, worth 5% of the exam grade, was this:

Identify one topic from the course that is not covered by an exam question but about which you learned something valuable. Write two to three sentences about what you learned.

I used to include a more wide-ranging version of this question to end my AI final exams many years ago, in which students had a chance to write a summary of the important ideas they had learned in the course. I'm not sure what reminded of the idea (perhaps one of James Tanton's essays), but this seemed like a nice way to give students a chance to boost their grades without a curve. I figured I would be generous and give them some latitude with their own experiences. My hope was that students could end the exam on a good note, feeling positive about something they learned and appreciated rather than solving yet another problem I fished out of fifteen weeks of material. There was a small risk -- what if a bunch of them panicked at the unusual question and couldn't think of anything to say? But that risk exists for almost any question I ask.

The question seems to have gone over quite well. Some students talked about a specific topic from the course, among them variable arity functions, currying, higher-order procedures, and syntactic abstraction. That's mostly what I had in mind when I wrote the question, even if some of their answers were covered in part somewhere else on the exam. Others answered more generally than I expected. A couple talked about how the course gave them a deeper appreciation for data abstraction; a couple of others wrote about the experience of writing an interpreter and having to live with their design decisions as the code as it grew over three weeks. All but one student wrote an answer substantive and reflective enough that I didn't even have to think about how many points to award. I was happy to read them.

I really shouldn't have been surprised. Most students care more about their learning, and get more out of a class, than exam answers and classroom participation might indicate. They face a lot of pressures, and as a result have a limited amount of time and energy to express about any one course day in and day out. But making software matters to most of them; sometimes even big ideas matter. This question let them express some of what made the class work for them.

This problem had unexpected effect... I ended the exam on a good note. I put down my grading pen feeling good about the course, knowing that each student learned something that stood out to them, that they appreciated enough to write a few sentences about. I got a small glimpse of how they changed as a result of the course. I put the question on the exam for the students' sake, but it affected me as much as it affected them.

That's not a bad way to end the semester.


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

May 04, 2018 1:25 PM

No Venom Here

Ken Perlin liked Ready Player One at the theater and then went off to read some reviews:

Many critics seem incensed, indignant, left sputtering in outrage at the very idea of a Spielberg film that is simply fun, a pop confection designed mainly to entertain and delight.
Perhaps some of it is their feeling of horror that modern pop culture might be something worthy of celebrating, simply for the sake of celebrating a phenomenon that many people find delightful. But why the extreme degree of venom?

I am an unashamed fan of pop culture: music, TV, movies, and all the rest. My biggest complaint these days is that I can't keep up with all the good stuff being created... (It helps that I'm not as big a fan of superhero movies as most people.) Critics can claim to serve as the gatekeepers of culture if they want, but I'll enjoy "Shut Up and Dance" [ YouTube ] all the same.


Posted by Eugene Wallingford | Permalink | Categories: General

April 29, 2018 8:04 AM

Bugs Keep Me Humble

Joshua Bloch, in this oldie but goodie:

The general lesson that I take away from this bug is humility: It is hard to write even the smallest piece of code correctly, and our whole world runs on big, complex pieces of code.

Having just written a small interpreter for my programming languages course, I, too, am feeling humble. Even in code that couldn't possibly go wrong, I had a small bug that bedeviled me for fifteen minutes. (You have to dereference those bindings in order to get the cells you want to mutate...) The experience is good preparation for a couple of software projects I hope to do this summer and for my compiler course this fall.

Oh, and Bloch's old post reminds me that it may be a good time to work through "Programming Pearls" again. It's been a while.


Posted by Eugene Wallingford | Permalink | Categories: Software Development

April 17, 2018 4:25 PM

The Tension Among Motivation, Real Problems, and Hard Work

Christiaan Huygens's first pendulum clock

In today's edition of "Sounds great, but...", I point you to Learn calculus like Huygens, a blog entry that relates some interesting history about the relationship between Gottfried Leibniz and Christiaan Huygens, "the greatest mathematician in the generation before Newton and Leibniz". It's a cool story: a genius of the old generation learns a paradigm-shifting new discipline via correspondence with a genius of the new generation who is in the process of mapping the discipline.

The "Sounds great, but..." part comes near the end of the article, when the author extrapolates from Huygens's attitude to what is wrong with math education these days. It seems that Huygens wanted to see connections between the crazy new operations he was learning, including second derivatives, and the real world. Without seeing these connections, he wasn't as motivated to put in the effort to learn them.

The author then asserts:

The point is not that mathematics needs to be applied. It is that it needs to be motivated. We don't study nature because we refuse to admit value in abstract mathematics. We study nature because she has repeatedly proven herself to have excellent mathematical taste, which is more than can be said for the run-of-the-mill mathematicians who have to invent technical pseudo-problems because they can't solve any real ones.

Yikes, that got ugly fast. And it gets uglier, with the author eventually worrying that we alienate present-day Huygenses with a mass of boring problems that are disconnected from reality.

I actually love the heart of that paragraph: We don't study nature because we refuse to admit value in abstract mathematics. We study nature because she has repeatedly proven herself to have excellent mathematical taste.... This is a reasonable claim, and almost poetic. But the idea that pseudo-problems invented by run-of-the-mill mathematicians are the reason students today aren't motivated to learn calculus or other advanced mathematics seems like a massive overreach.

I'm sympathetic to the author's position. I watched my daughters slog through AP Calculus, solving many abstract problems and many applied problems that had only a thin veneer of reality wrapped around them. As someone who enjoyed puzzles for puzzles' sake, I had enjoyed all of my calculus courses, but it seemed as if my daughters and many of their classmates never felt the sort of motivation that Huygens craved and Leibniz delivered.

I also see many computer science students slog through courses in which they learn to program, apply computational theory to problems, and study the intricate workings of software and hardware systems. Abstract problems are a fine way to learn how to program, but they don't always motivate students to put in a lot of work on challenging material. However, real problems can be too unruly for many settings, though, so simplified, abstract problems are common.

But it's not quite as easy to fix this problem by saying "learn calculus like Huygens: solve real problems!". There are a number of impediments to this being a straightforward solution in practice.

One is the need for domain knowledge. Few, if any, of the students sitting in today's calculus classes have much in common with Huygens, a brilliant natural scientist and inventor who had spent his life investigating hard problems. He brought a wealth of knowledge to his study of mathematics. I'm guessing that Leibniz didn't have to search long to find applications with which Huygens was already familiar and whose solutions he cared about.

Maybe in the old days all math students were learning a lot of science at the same time as they learned math, but that is not always so now. In order to motivate students with real problems, you need real problems from many domains, in hopes of hitting all students' backgrounds and interests. Even then, you may not cover them all. And, even if you do, you need lots of problems for them to practice on.

I think about these problems every day from the perspective of a computer science prof, and I think there are a lot of parallels between motivating math students and motivating CS students. How do I give my students problems from domains they both know something about and are curious enough to learn more about? How do I do that in a room with thirty-five students with as many different backgrounds? How do I do that in the amount of time I have to develop and extend my course?

Switching to a computer science perspective brings to mind a second impediment to the "solve real problems" mantra. CS education research offers some evidence that using context-laden problems, even from familiar contexts, can make it more difficult for students to solve programming problems. The authors of the linked paper say:

Our results suggest that any advantage conveyed by a familiar context is dominated by other factors, such as the complexity of terminology used in the description, the length of the problem description, and the availability of examples. This suggests that educators should focus on simplicity of language and the development of examples, rather than seeking contexts that may aid in understanding problems.

Using familiar problems to learn new techniques may help motivate students initially, but that may come at other costs. Complexity and confusion can be demotivating.

So, "learn calculus like Huygens" sounds great, but it's not quite so easy to implement in practice. After many years designing and teaching courses, I have a lot of sympathy for the writers of calculus and intro programming textbooks. I also don't think it gets much easier as students advance through the curriculum. Some students are motivated no matter what the instructor does; others need help. The tension between motivation and the hard work needed to master new techniques is always there. Claims that the tension is easy to resolve are usually too glib to be helpful.

The Huygens-Leibniz tale really is a cool story, though. You might enjoy it.

(The image above is a sketch of Christiaan Huygens's first pendulum clock, from 1657. Source: Wikipedia.)


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

April 06, 2018 3:19 PM

Maps and Abstractions

I've been reading my way through Frank Chimero's talks online and ran across a great bit on maps and interaction design in What Screens Want. One of the paragraphs made me think about the abstractions that show up in CS courses:

When I realized that, a little light went off in my head: a map's biases do service to one need, but distort everything else. Meaning, they misinform and confuse those with different needs.

CS courses are full of abstractions and models of complex systems. We use examples, often simplified, to expose or emphasize a single facet a system, as a way to help students cut through the complexity. For example, compilers and full-strength interpreters are complicated programs, so we start with simple interpreters operating over simple languages. Students get their feet wet without drowning in detail.

In the service of trying not to overwhelm students, though, we run the risk of distorting how they think about the parts we left out. Worse, we sometimes distort even their thinking about the part we're focusing on, because they don't see its connections to the more complete picture. There is an art to identifying abstractions, creating examples, and sequencing instruction. Done well, we can minimize the distortions and help students come to understand the whole with small steps and incremental increases in size and complexity.

At least that's what I think on my good days. There are days and even entire semesters when things don't seem to progress as smoothly as I hope or as smoothly as past experience has led me to expect. Those days, I feel like I'm doing violence to an idea when I create an abstraction or adopt a simplifying assumption. Students don't seem to be grokking the terrain, so change the map. We try different problems or work through more examples. It's hard to find the balance sometimes between adding enough to help and not adding so much as to overwhelm.

The best teachers I've encountered know how to approach this challenge. More importantly, they seem to enjoy the challenge. I'm guessing that teachers who don't enjoy it must be frustrated a lot. I enjoy it, and even so there are times when this challenge frustrates me.


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

March 29, 2018 3:05 PM

Heresy in the Battle Between OOP and FP

For years now, I've been listening to many people -- smart, accomplished people -- feverishly proclaim that functional programming is here to right the wrongs of object-oriented programming. For many years before that, I heard many people -- smart, accomplished people -- feverishly proclaim that object-oriented programming was superior to functional programming, an academic toy, for building real software.

Alas, I don't have a home in the battle between OOP and FP. I like and program in both styles. So it's nice whenever I come across something like Alan Kay's recent post on Quora, in response to the question, "Why is functional programming seen as the opposite of OOP rather than an addition to it?" He closes with a paragraph I could take on as my credo:

So: both OOP and functional computation can be completely compatible (and should be!). There is no reason to munge state in objects, and there is no reason to invent "monads" in FP. We just have to realize that "computers are simulators" and figure out what to simulate.

As in many things, Kay encourages to go beyond today's pop culture of programming to create a computational medium that incorporates big ideas from the beginning of our discipline. While we work on those ideas, I'll continue to write programs in both styles, and to enjoy them both. With any luck, I'll bounce between mindsets long enough that I eventually attain enlightenment, like the venerable master Qc Na. (See the koan at the bottom of that link.)

Oh: Kay really closes his post with

I will be giving a talk on these ideas in July in Amsterdam (at the "CurryOn" conference).

If that's not a reason to go to Amsterdam for a few days, I don't know what is. Some of the other speakers looks pretty good, too.


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

March 23, 2018 3:45 PM

A New Way to Design Programming Languages?

Greg Wilson wrote a short blog post recently about why JavaScript isn't suitable for teaching Data Carpentry-style workshops. In closing, he suggests an unusual way to design programming languages:

What I do know is that the world would be a better place if language designers adopted tutorial-driven design: write the lessons that introduce newcomers to the language, then implement the features those tutorials require.

That's a different sort of TDD than I'm used to...

This is the sort of idea that causes me to do a double or triple take. At first, it has an appealing ring to it, when considering how difficult it is to teach most programming languages to novices. Then I think a bit and decide that it sounds crazy because, really, are we going to hamstring our languages by focusing on the struggles of beginners? But then it sits in my mind for a while and I start to wonder if we couldn't grow a decent language this way. It's almost like using the old TDD to implement new the TDD.

The PLT Scheme folks have designed a set of teaching languages that enable beginners to grow into an industry-strength language. That design project seems to have worked from the outsides in, with a target language in mind while designing the teaching languages. Maybe Wilson's idea of starting at the beginning isn't so crazy after all.


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