September 28, 2017 3:17 PM

Pascal's Criticism of Extreme Programming

Blaise Pascal believed that the key error of the school of philosophy known as Stoicism lay in thinking that people can do always what they can, in reality, only do sometimes.

Had Pascal lived in the time of software development, he would probably have felt the same way about Extreme Programming and test-driven design.

I was reminded of Pascal the philosopher (not the language) earlier this week when I wrote code for several hours without writing my unit tests. As a result, I found myself refactoring blind for most of the project. The code was small enough that this worked out fine, and I didn't even feel much fear while moving along at a decent pace. Even so, I felt a little guilty.

Pascal made a good point about Stoicism, but I don't think that this means I ought not be a Stoic -- or a practitioner of XP. XP helps me to be a better programmer. I do have to be aware, though, that it asks me to act against my natural tendencies, just as Stoicism encourages us not to be controlled by desire or fear.

One of the beauties of XP is that it intertwines a number of practices that mutually support one another, which helps to keep me in a groove. It helps me to reduce the size of my fear, so that I don't as much to control. If I hadn't been refactoring so often this week, I probably wouldn't have even noticed that I hadn't written tests!

One need not live in fear of coming up short of the ideal. No one is perfect. I'll get back to writing my tests on my next program. There is no need to beat myself up about one program. Everything worked out fine.


Posted by Eugene Wallingford | Permalink | Categories: Software Development

September 26, 2017 3:58 PM

Learn Exceptions Later

Yesterday, I mentioned rewriting the rules for computing FIRST and FOLLOW sets using only "plain English". As I was refactoring my descriptions, I realized that one of the reasons students have difficulty with many textbook treatments of the algorithms is that the books give complete and correct definitions of the sets upfront. The presence of X := ε rules complicates the construction of both sets, but they are unnecessary to understanding the commonsense ideas that motivate the sets. Trying to deal with ε too soon can interfere with the students learning what they need to learn in order to eventually understand ε!

When I left the ε rules out of my descriptions, I ended up with what I thought were an approachable set of rules:

  • The FIRST set of a terminal contains only the terminal itself.

  • To compute FIRST for a non-terminal X, find all of the grammar rules that have X on the lefthand side. Add to FIRST(X) all of the items in the FIRST set of the first symbol of each righthand side.

  • The FOLLOW set of the start symbol contains the end-of-stream marker.

  • To compute FOLLOW for a non-terminal X, find all of the grammar rules that have X on the righthand side. If X is followed by a symbol in the rule, add to FOLLOW(X) all of the items in the FIRST set of that symbol. If X is the last symbol in the rule, add to FOLLOW(X) all of the items in the FOLLOW set of the symbol on the rule's lefthand side.

These rules are incomplete, but they have offsetting benefits. Each of these cases is easy to grok with a simple example or two. They also account for a big chunk of the work students need to do in constructing the sets for a typical grammar. As a result, they can get some practice building sets before diving into the gnarlier details ε, which affects both of the main rules above in a couple of ways.

These seems like a two-fold application of the Concrete, Then Abstract pattern. The first is the standard form: we get to see and work with accessible concrete examples before formalizing the rules in mathematical notation. The second involves the nature of the problem itself. The rules above are the concrete manifestation of FIRST and FOLLOW sets; students can master them before considering the more abstract ε cases. The abstract cases are the ones that benefit most from using formal notation.

I think this is an example of another pattern that works well when teaching. We might call it "Learn Exceptions Later", "Handle Exceptions Later", "Save Exceptions For Later", or even "Treat Exceptions as Exceptions". (Naming things is hard.) It is often possible to learn a substantial portion of an idea without considering exceptions at all, and doing so prepares students for learning the exceptions anyway.

I guess I now have at least one idea for my next PLoP paper.

Ironically, writing this post brings to mind a programming pattern that puts exceptions up top, which I learned during the summer Smalltalk taught me OOP. Instead of writing code like this:

    if normal_case(x) then
       // a bunch
       // of lines
       // of code
       // processing x
    else
       throw_an_error
you can write:
    if abnormal_case(x) then
       throw_an_error

// a bunch // of lines // of code // processing x
This idiom brings the exceptional case to the top of the function and dispatches with it immediately. On the other hand, it also makes the normal case the main focus of the function, unindented and clear to the eye. It may look like this idiom violates the "Save Exceptions For Later" pattern, but code of this sort can be a natural outgrowth of following the pattern. First, we implement the function to do its normal business and makes sure that it handles all of the usual cases. Only then do we concern ourselves with the exceptional case, and we build it into the function with minimal disruption to the code.

This pattern has served me well over the years, far beyond Smalltalk.


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

September 25, 2017 3:01 PM

A Few Thoughts on My Compilers Course

I've been meaning to blog about my compilers course for more than a month, but life -- including my compilers course -- have kept me busy. Here are three quick notes to prime the pump.

  • I recently came across Lindsey Kuper's My First Fifteen Compilers and thought again about this unusual approach to a compiler course: one compiler a week, growing last week's compiler with a new feature or capability, until you have a complete system. Long, long-time readers of this blog may remember me writing about this idea once over a decade ago.

    The approach still intrigues me. Kuper says that it was "hugely motivating" to have a working compiler at the end of each week. In the end I always shy away from the approach because (1) I'm not yet willing to adopt for my course the Scheme-enabled micro-transformation model for building a compiler and (2) I haven't figured out how to make it work for a more traditional compiler.

    I'm sure I'll remain intrigued and consider it again in the future. Your suggestions are welcome!

  • Last week, I mentioned on Twitter that I was trying to explain how to compute FIRST and FOLLOW sets using only "plain English". It was hard. Writing a textual description of the process made me appreciate the value of using and understanding mathematical notation. It is so expressive and so concise. The problem for students is that it is also quite imposing until they get it. Before then, the notation can be a roadblock on the way to understanding something at an intuitive level.

    My usual approach in class to FIRST and FOLLOW sets, as for most topics, is to start with an example, reason about it in commonsense terms, and only then to formalize. The commonsense reasoning often helps students understand the formal expression, thus removing some of its bite. It's a variant of the "Concrete, Then Abstract" pattern.

    Mathematical definitions such as these can motivate some students to develop their formal reasoning skills. Many people prefer to let students develop their "mathematical maturity" in math courses, but this is really just an avoidance mechanism. "Let the Math department fail them" may solve a practical problem, sometimes we CS profs have to bite the bullet and help our students get better when they need it.

  • I have been trying to write more code for the course this semester, both for my enjoyment (and sanity) and for use in class. Earlier, I wrote a couple of toy programs such as a Fizzbuzz compiler. This weekend I took a deeper dive and began to implement my students' compiler project in full detail. It was a lot of fun to be deep in the mire of a real program again. I have already learned and re-learned a few things about Python, git, and bash, and I'm only a quarter of the way in! Now I just have to make time to do the rest as the semester moves forward.

In her post, Kuper said that her first compiler course was "a lot of hard work" but "the most fun I'd ever had writing code". I always tell my students that this course will be just like that for them. They are more likely to believe the first claim than the second. Diving in, I'm remembering those feelings firsthand. I think my students will be glad that I dove in. I'm reliving some of the challenges of doing everything that I ask them to do. This is already generating a new source of empathy for my students, which will probably be good for them come grading time.


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

September 19, 2017 2:52 PM

Still Skeptical About Tweetstorms

The last couple of months have been the sparsest extended stretch on my blog since I began writing here in 2004. I have missed the feeling of writing, and I've wanted to write, but I guess never wanted it enough to set aside time to do the work. (There may be a deeper reason, the idea of which merits more thinking.) It's also a testament to the power of habit in my life: when I'm in the habit of writing, I write; when I fall out of the habit, I don't. During my unintended break from blogging, I've remained as active as usual on Twitter. But I haven't done much long-form writing other than lecture notes for my compiler class.

And that includes writing tweetstorms.

I'm one of those people who occasionally snarks on Twitter about tweetstorms. They always seem like a poor substitute for a blog entry or an essay. While I've probably written my last snarky tweet about tweetstorms, I remain skeptical of the form.

That said, my curiosity was aroused when Brian Marick, a writer and programmer whose work I always enjoy, tweeted yesterday:

[Note re: "write a blog post". I think the tweetstorm is different lit'ry form, and I like exploring it.]

I would love for Brian or anyone else to be able to demonstrate the value in a tweetstorm that is unique from equivalent writing in other forms. I've read many tweetstorms that I've enjoyed, including the epic Eric Garland disquisition considered by many to be the archetype of the genre. But in the end, every tweetstorm looks like either a bullet-point presentation that could be delivered in Powerpoint, or something that could stand on its own as an essay, if only the sentences were, you know, assembled into paragraphs.

I am sympathetic to the idea that there may be a new literary form lurking here. Like any constraint, the 140-character limit on tweets causes writers to be creative in a new way. Chaining a sequence of similarly constrained statements together as a meaningful whole requires a certain skill, and writers who master the style can pull me through to the end, almost despite myself. But I would read through to the end of a blog entry written as skillfully, and I wouldn't have to do the assembly of the work in my head as I go.

Perhaps the value lies in Twitter as an interaction mechanism. Twitter makes it easy to respond to and discuss the elements of a tweetstorm at the level of individual tweet. That's handy, but it can also be distracting. Not every Twitter platform manages the threading as well as it could. It's also not a new feature of the web; any blogging platform can provide paragraph-level linking as a primitive, and discussion forums are built on modular commentary and linking. Maybe tweetstorms are popular precisely because Twitter is a popular medium of the day. They are the path of least resistance.

That leads to what may be the real reason that people explore the form: Twitter lowers the barrier of entry into blogging to almost nothing: install an app, or point a web browser to your homepage, and you have a blogging platform. But that doesn't make the tweetstorm a new literary form of any particular merit. It's simply a chunking mechanism enforced by the nature of a limited interface. Is there anything more to it than that?

I'm an open-minded person, so when I say I'm skeptical about something, I really am open to changing my mind. When someone I respect says that there may be something to the idea, I know I should pay attention. I'll follow Brian's experiment and otherwise keep my mind open. I'm not expecting to undergo a conversion, but I'm genuinely curious about the possibilities.


Posted by Eugene Wallingford | Permalink | Categories: General