What is this?
A new teaching with authority.
-- Mark 1:27
Over the last few weeks, we've been processing student assessments from fall semester. Reading student comments about my course and other profs' courses has me thinking about the different ways in which students "see" their instructors. Two profs can be equally knowledgable in an area yet give off very different vibes to their class. The vibe has a lot to do with how students interpret the instructor's behavior. It also affects student motivation and, ultimately, student learning.
Daniel Lemire recently offered two rules for teaching in the 21st century, one of which was to be an authentic role model. If students know that "someone ordinary" like a professor was able to master the course material, then they will have reason to believe that they can do the same. Authenticity is invaluable if we hope to model the mindset of a learner for our students.
It is also a huge factor in the classroom in another way as well. Students are also sensitive to whether we are authentic users of knowledge. If I am teaching agile approaches to software development but students perceive that I am not an agile developer when writing my own code outside the course, then they are less likely to take the agile approaches seriously. If I am teaching the use of some theoretical technique for solving a problem, say, nondeterministic finite state machines, but my students perceive that I do something else when I'm not teaching the course, then their motivation to master the technique wanes.
I think that how students "see" their instructors is affected by something as important as being authentic: being authoritative. I don't mean authority in the sense of power, in particular power granted from on high. In my experience, that sort of authority is surprisingly ineffective as a tool for getting students to follow me into a difficult forest of knowledge. They respect the authority, perhaps, but they tend to balk at orders to march into the dark.
I also don't mean authority born out of perfection. If that were the case, I could never step into a classroom. Just today, I made an error in my compilers course while demonstrating a technique for converting nondeterministic finite automata into deterministic automata. Such errors occur frequently enough to disabuse both me and my students of the thought that mastery means always getting the right answers. (But not so often, I hope, as to undermine students' confidence in my mastery of the material.)
Instead, I am thinking of the persuasive or influential sense of authority that comes out of mastery itself. This sense of the word is more faithful to the origin of the word in the Latin auctor, also the source of "author". An author is someone who originates or gives existence to something. Among the earliest uses of the "auctor" or "author" was to refer renowned scholars in medieval universities. Such scholars created new knowledge, or at least discovered it and incorporated it into the knowledge of the community. They did not simply mimic back what was already understood.
I suspect that this is what the crowds thought in the Bible passage from Mark given above. The scribes of the time could read scripture and recite it back to people. They could even teach by elaborating on it or relating it to the lives of the people. But the essence of their teaching was already present in the scripture. Along came Jesus, who taught the scripture, but more. His elaborations and parables brought new depth to the old laws and stories. They taught something new. He was speaking with authority.
The sense of authorship or origination is key. We see this sense of authority when we speak of authors. In modern times, the word "auctor" is sometimes used to denote the person who donates the genetic material that serves as the basis for a clone. This usage draws even more heavily on the idea of creation residing in the root word.
That's all fine as philosophy and etymology, but I think this matters in the classroom, too. The authoritative teacher does not simply "read the book" and then lecture, which at a certain level is simply reading the book to the students. Good teachers understand the material at a deeper level. They use it. They apply the techniques and makes connections to other topics, even other course and disciplines. They create new ideas with the course material. They don't simply relay information to students; they also create knowledge.
Such teachers are able to teach with authority.
One of the big challenges for new instructors, especially new ones, is to learn how to teach with this kind of authority. Some assume that their status as professors grants them the sort of authority founded in power, and that is what they project to their students. They know their stuff, yet they don't speak with the sort of authority that resonates with their students. When the students respond with less than capitulation, the professor reacts with power or defensiveness. These only make the problem worse.
It takes experience in the classroom for most of us to figure this out. I know it took me a while. It also takes an openness to change and a willingness to learn. Fortunately, these are traits possessed by many people who want to teach.
When things are going wrong in my classes these days, I try to step back from the situation. I ask myself, Am I being authentic? Am I speaking with an authority born out of scholarship, rather than an authority born out of status? Am I letting my students see these things?
Last week, I found myself reading The Most Entertaining Philosopher, about William James. It was good fun. I have always liked James. I liked the work of his colleagues in pragmatism, C.S. Peirce and John Dewey, too, but I always liked James more. For all the weaknesses of his formulation of pragmatism, he always seemed so much more human to me than Peirce, who did the heavy theoretical lifting to create pragmatism as a formal philosophy. And he always seemed a lot more fun than Dewey.
I wrote an entry a few years ago called The Academic Future of Agile Methods, which described the connection between pragmatism and my earlier AI, as well as agile software development. I still consider myself a pragmatist, though it's tough to explain just what that means. The pragmatic stance is too often confounded with a self-serving view of the world, a "whatever works is true" philosophy. Whatever works... for me. James's references to the "cash value" of truth didn't help. (James himself tried to undo the phrase's ill effects, but it has stuck. Even in the 1800s, it seems, a good sound bite was better than the truth.)
As John Banville, the author NY Times book review piece says, "It is far easier to act in the spirit of pragmatism than to describe what it is." He then gives "perhaps the most concise and elegant definition" of pragmatism, by philosopher C. I. Lewis. It is a definition that captures the spirit of pragmatism as well as any few lines can:
Pragmatism could be characterized as the doctrine that all problems are at bottom problems of conduct, that all judgments are, implicitly, judgments of value, and that, as there can be ultimately no valid distinction of theoretical and practical, so there can be no final separation of questions of truth of any kind from questions of the justifiable ends of action.
This is what drew me to pragmatism while doing work in knowledge-based systems, as a reaction to the prevailing view of logical AI that seemed based in idealist and realist epistemologies. It is also what seems to me to distinguish agile approaches to software development from the more common views of software engineering. I applaud people who are trying to create an overarching model for software development, a capital-t Theory, but I'm skeptical. The agile mindset is, or at least can be, pragmatic. I view software development in much the way James viewed consciousness: "not a thing or a place, but a process".
As I read again about James and his approach, I remember my first encounters with pragmatism and thinking: Pragmatism is science; other forms of epistemology are mathematics.
Last summer, I wrote an entry, Failure and the Liberal Arts, which suggested (among things) that the value of a liberal education lies in the intersections between disciplines and ideas. This contrasts with the view seemingly held by many people that a liberal education means to study the "liberal arts", mostly the humanities and arts.
The traditional liberal arts education faces a lot of challenges in the current cultural and economic climate. As colleges and universities cope with rising costs, increasing competition for students, and an unbundling of the university's products engendered by technology, undergraduate degrees filled only with history, literature, and upper-class culture -- and no obvious preparation for economic life after graduation -- creates another barrier to making a sale to prospective parents and students.
The goals of a liberal education are laudable. How can we craft undergraduate experiences that help students to develop broad skills in reading, writing, and thinking? Isn't that what the traditional liberal arts do best?
Timothy Burke nails the answer to these questions in this comment on his own blog:
... a person becomes most skilled at creating, making, innovating, thinking, in ways that have value in existing professions *and* in life through indirect means. Studying communication doesn't make you a better communicator, studying entrepreneurship doesn't make you a better entrepreneur, and so on.
But this has huge, huge implications as a perspective for the content and practice of "liberal arts" as an educational object. ... Maybe learning to do things (creating, innovating, expressing, etc.) isn't advanced by anything resembling intensive study of a fixed body of knowledge, but by doing.
I couldn't agree more. This idea lies at the heart of my blog, in both theme and name: knowing and doing. Learning to do things is best accomplished by doing things, not (just) by studying a fixed body of knowledge, however intensive the studying or valuable the body of knowledge. Sure, at some point, you gotta know stuff, and intensive study of a domain is a useful and valuable enterprise. But we learn best by doing.
My compilers students will -- if all goes as we plan and hope -- learn much more this semester than how to write a compiler. They will learn things that I can't teach them directly with a lecture. And even when I could give them the lecture, they would not learn it in the same way as when they learn it on the ground, in the trenches, one shovel of dirt at a time.
Liberal arts colleges -- and universities with liberal arts cores and general education programs -- would do well to take this lesson to heart sooner rather than later.
To be honest, it is a little of both.
I gave the students in my compilers course a small homework assignment. It's a relatively simple translation problem whose primary goals are to help students refresh their programming skills in their language of choice and to think about the issues we will be studying in depth in coming weeks: scanning, parsing, validating, and generating.
I sat down the other day to write a solution ... and promptly made a mess.
In retrospect, my problem was that I was somewhere in between "do it 'simple'" and "do it 'right'". Unlike most of the students in the class, already know a lot about building compilers. I could use all that knowledge and build a multi-stage processor that converts a string in the source language (a simple template language) into a string in the target language (ASCII text). But writing a scanner, a parser, a static analyzer, and a text generator seems like overkill for such a simple problem. Besides, my students aren't likely to write such a solution, which would make my experience less valuable helping them to solve the problem, and my program less valuable as an example of a reasonable solution.
So I decided to keep things simple. Unfortunately, though, I didn't follow my own agile advice and do the simplest thing that could possibly work. As if with the full-compiler option, I don't really want the simplest program that could possibly work. This problem is simple enough to solve with a single pass algorithm, processing the input stream at the level of individual characters. That approach would work but would obscure the issues we are exploring in the course in a lot of low-level code managing states and conditions. Our goal for the assignment is understanding, not efficiency or language hackery.
I was frustrated with myself, so I walked away.
Later in the day, I was diddling around the house and occasionally mulling over my situation. Suddenly I saw a solution in mind. It embodied a simple understanding of my the problem, in the middle ground between too simple and too complex that was just right.
I had written my original code in a test-first way, but that didn't help me avoid my mess. I know that pair programming would have. My partner would surely have seen through the complexity I was spewing to the fact that I was off track and said, "Huh? Cut that out." Pair programming is an unsung hero in cases like this.
I wonder if this pitfall is a particular risk for CS academics. We teach courses that are full of details, with the goal of helping students understand the full depth of a domain. We often write quick and dirty code for our own purposes. These are at opposite ends of the software development spectrum. In the end, we have to help students learn to think somewhere in the middle. So, we try to show students well-designed solutions that are simple enough, but no simpler. That's a much more challenging task that writing a program at either extreme. Not being full-time developers, perhaps our instincts for finding the happy medium aren't as sharp as they might be.
As always, though, I had fun writing code.
One of the things I love about reading professional blogs and twitter feeds is reassuring myself that I am not crazy in many of my compulsions and obsessions.
On the exercise bike yesterday morning, I read Matt Might's End artificial scarcities to increase productivity. Many years ago I saw my colleague, friend, and hero Joe Bergin do something that I now do faithfully: always carry with me a pad of paper, small enough to fit comfortably in most any pocket, and a good pen. When your life is writing code, writing lectures, writing blog entries, you often want to write at the oddest of times. Now I am always ready to jot down any idea that comes into my head as soon as it does. I may throw it away later as a hare-brained scheme, but I prefer that to losing an idea for lack of a notepad.
Our house has pens, pencils, and usually paper in nearly every room. I have them in every bag I carry an in most coats I wear. The kind of pen matters some; I hate splotching and bleeding through. I have a fondness for a particular older model of Uniball pens, but I'm not obsessed with them. I do have a box of them in my desk at home, and every once in a while I'll pull one out to replace a pen that has run dry. They feel right in my hand.
Like Might, I have MacbookPro power adapters in every room in which I work, as well as one in my travel bag. The cost of having three or four adapters have been well worth the peace of mind. I even have a back-up battery or two on hand most of the time. (My Pro is one of the older ones with the removable battery.) I like to have one each in my home and school offices, where i do most of my work and from which most excursions begin.
On the bike this morning, I read Rands in Repose's bag pr0n essay from last month. Loved it! Like Lopp and many other geeks, I have at times obsessed over my bag. Back in high school I carried an attache case my parents gave me for Christmas. (Yes, I was that guy.) Since college and grad school, I've gone through several styles of bag, including freebies given out at conferences and a couple of nice ones my wife gave me as gifts. A few have provided what I desire: compactness, with a few compartments but not too many.
One of my favorites was from SIGCSE in the late 1990s. I still have it, though it shows its age and wear. Another is a bag I got at one of the PLoP conferences in the early part of the previous decade. It was perfect for an iBook, but is too small for my Pro. I still have it, too, waiting for a time when it will fit my needs again. Both were products of the days of really good conference swag. My current bag is a simple leather case that my wife gave me. It's been serving me well for a couple of years.
Each person has his or her particular point of obsession. Mine is the way the shoulder strap attaches to the body of bag. So many good bags have died too soon when the metallic clasp holding strap to body broke, or the clasp worked loose, or the fabric piece wore through.
Strange but true: One of my all time favorite bags was a $5 blue vinyl diaper bag that my wife bought at a garage sale in the early 1990s. No one knew it was a diaper bag, or so I think; at a glance it was rather inncouous. This bag was especially useful at a time when I traveled a lot, attending 4-6 conferences a year and doing more personal travel than I do these days. The changing pad served as a great sleeve to protect my laptop (first a G3 clamshell, then an iBook). The side compartments designed to hold two baby bottles were great for bottles of water or soda. This was especially handy for a long day flying -- back when we could do such crazy things as carry drinks with us. This bag also passed Rands' airport security line test. It allowed for easy in-and-out of the laptop, and then rolled nicely on its side for going through x-ray. I still think about returning to this bag some day.
I'm sure that this sort of obsessiveness is a positive trait for programmers. So many of us have it, it must be.
Spring semester is underway. My compilers course met for the first time today. After all these years, I still get excited at the prospect of writing a compiler. On top of that, we get to talk about programming languages and programming all semester.
I've been preparing for the course since last semester, during the programming languages course I debriefed recently. I've written blog entries as I planned previous offerings of the compiler course, on topics such as short iterations and teaching by example, fifteen compilers in fifteen weeks and teaching the course backwards. I haven't written anything yet this time for one of the same reasons I haven't been writing about my knee rehab: I haven't had much to say. Actually, I have two small things.
First, on textbooks. I found that the textbook I've used for the last few offering of the course now costs students over $140, even at Amazon. That's no $274.70, but sheesh. I looked at several other popular undergrad compiler texts and found them all to be well over $100. The books my students might want to keep for their professional careers are not suitable for an undergrad course, and the ones that are suitable are expensive. I understand the reasons why yet can't stomach hitting my students with such a large bill. The Dragon book is the standard, of course, but I'm not convinced it's a good book for my audience -- too few examples, and so much material. (At least it's relatively inexpensive, at closer to $105.)
I found a few compiler textbooks available free on-line, including that $275 book I like. Ultimately I settled on Torben Mogensen's Basics of Compiler Design. It covers the basic material without too much fluff, though it lacks a running example with full implementation. I'll augment it with my own material and web readings. The price is certainly attractive. I'll let you know how it works out.
Second, as I was filing a pile of papers over break, I ran across the student assessments from last offering of the course. Perfect timing! I re-read them and am able to take into account student feedback. The last group was pretty pleased with the course and offered two broad suggestions for improvement: more low-level details and more code examples. I concur in both. It's easy when covering so many new ideas to stay at an abstract level, and the compiler course is no exception. Code examples help students connect the ideas we discuss with the reality of their own projects.
These are time consuming improvements to make, and time will be at a premium with a new textbook for the course. This new text makes them even more important, though, because it has few code examples. My goal is to add one new code example to each week of the course. I'll be happy if I manage one really good example every other week.
And we are off.
This morning, I did something I hadn't done since Sunday, February 27. I did a long workout. That day, it was a 12-mile run in single-digit temperatures, a bright, sunny morning. This day, it was a 1-hour ride on an exercise bike in my basement. It is again a bright, sunny morning, but I was shielded from the winter old.
It felt good.
I've been riding an exercise bike daily since mid-November or so, working my way up from the 10-15 minute I rode occasionally in earlier therapy physical sessions first to 30 minutes, and now to 45 minutes at a time. Today for some reason, my mind said, just keep riding.
Over the last couple of months, I have begun exercising my knee more often and for longer, as I rehab from knee surgery last summer. In addition to the exercise bike, I have been walking a lot. Most days now, I walk 4-5 miles, usually in the evening with my family. It's not running, but it's moving, and it feels good to move -- and burn a few calories. After seven months of inactivity, I had gained twenty pounds and lost my lovely figure. I'm working on both those problems now.
The last two months of 2011 offered an experience that turned my memory inside out: my therapist had me run in our athletic department's Hydroworx pool. Put simply, this is a treadmill on the floor of a pool, which can be lowered to any level. Air jets blow water at the runner to create more resistance. Running in the water blunts impact on all the joints, including the knee, so my surgeon recommended it as part of my therapy.
The first time we speeded the treadmill from walk to gentle run, I was in ecstasy. My body fell into that comfortable rhythm that runners know and love. My heart raced. At first, my mind was empty, but soon it flooded with memories of runs past. I had not felt like a runner since last March. Yet there I was, a runner again.
That feeling was bittersweet, though. I knew that I could run in the pool only for a couple of months, as part of my therapy. Once my knee regained a certain level of strength and balance, pool sessions for therapy would end. And so they did. When I make my first Internet million, perhaps I'll build such a pool at my house, but for now I am back to walking and biking.
I haven't been writing about my knee, or about not running, for a lot of small reasons. This isn't a confessional blog, and I doubt many readers are interested in hearing me go on and on about my feelings. I also haven't find myself making connections between my rehab and my teaching or my software development, as I did when I was running. My experiences have been nothing unique, mostly what musical artist John Mellencamp calls "ditch digging": just doing what little I have to do each day. There is certainly something to be learned in this experience, but at this point I have nothing special to say.
Still, after riding for a full hour today, feeling a little like I did on all those Sunday long runs, reminded me of something worth remembering. When we do the little work day to day, we build something bigger. It takes patience. Another shovel of dirt.
At Week 2 of my fall programming languages course, I planned to write an entry called More Concrete Ideas for the course, following up on an entry about extravagant ideas. I even had a geeky Scheme joke to open, asking whether that was ((More Concrete) Ideas) or (More (Concrete Ideas)).
Suddenly, or so it seemed, we were two-thirds of the way through the course, and I still hadn't written. Now we are three weeks past the end of the course. Time to debrief. (At least I'm not waiting to debrief the course until the next time we offer it, in Spring 2013!)
Due to a recent change in my department's prerequisite structure, I had a more diverse student population this semester than I have ever had in Programming Languages. Their diversity covered multiple dimensions, including the languages they knew well and the level of experience they had writing larger programs. Many did not know OOP or Java yet, which have long been staples of my reference set.
This led to an interesting phenomenon. One particular student was at the low end of background, experience, and skill set. In most ways, he was more of a rank beginner than the usual student in the course. Over the course of the semester, he asked me questions unlike any I had been asked in this course for a long while, if ever. His questions caused me to step back and focus on basic elements of the craft of programming that I have never discussed in the context of this course and functional programming. At times it was frustrating, but most of the time it was a good challenge.
More importantly, his questions exposed for me the sort of difficulties that I often miss when students are doing better. Even students who are doing well in the course develop subtle misconceptions about the material, or start with misconceptions that my teaching does address. However, their decent scores on quizzes and their general understanding of the material allow me to gloss over misconceptions that come back to trouble us later.
This is the frame of mind I was in when I wrote an entry on open dialogue a few weeks back. Even with my beginner-like student, I did not enough questions soon enough. For all I know, students in previous semesters have had similar problems that I never addressed in class. After this round, I am thinking more concretely about where I have gone wrong and how I might do better in the future.
As mentioned earlier, I offered students a chance to document some of their epic failures during the semester. Of course, students always have that opportunity; this time, I offered extra credit as an inducement to take on the challenge.
In the end, roughly a third of the students submitted essays, though all came in very late in the semester, enough so that anything I might fold back into the course will have to wait until the next time around.
I enjoyed several of the essays. One student learned one valuable lesson this semester: "There are only so many hours in a day." Another student wrote,
My usual strategy with all but the most basic of the problems is to stare at them for a while and then walk away.
(A former student wondered, "But does he ever come back?")
Like many programmers, this student lets his brain work on a problem over time and eventually arrives at a solution without the stress of staring at the problem until he gets it right the first time. However, he found this semester that even this approach cannot alleviate all stress, because sometimes no answer seems to work. What then?
I'll try the Epic Fail idea again in coming semesters. I'll probably give students a bit more guidance about the kind of failures I mean (not run-of-the-mill stuff, really) and the kind of write-up that I'm looking for. As always, students appreciate examples!
In that vein, I had thought this semester that I would provide students with occasional example programs (1) to illustrate functional programming and Scheme outside the realm of the study of programming languages and (2) to illustrate programming language topics with non-FP code. The idea was to broaden the reach of the course, to help students struggling with FP and to open doors for those students who were really interested and ready to see more.
Unfortunately, I did not do nearly enough of this. Next time, I will find a way, somehow. Among the topics that can benefit most from this idea are continuation-based web servers and MapReduce.
As I graded the final exam, I was most disappointed with student understanding of curried functions and of the equivalence between local variables and function application. Currying is such a beautiful idea at the heart of functional style, which we saw repeatedly throughout the semester. The local variable/function app idea is one we discussed in some detail at least three times during the semester, in different contexts, and which I highlighted as "something that will be on the final".
I'll think long and hard before I teach the course again about ways to help students understand these ideas better. If you have any suggestions, please let me know!
One student tweeted after the course:
I think the larger examples are what helped ideas stick in my mind. This class had the most information I've learned in a class before. It was a challenge which was really refreshing. Gliding through classes put me into a lull for awhile.
It's important for me and other teachers to remember just how heavy some courses can be. I'm fully aware that this course is different than any students have taken before and that it will challenge them in new ways. I tell them so on Day 1. Still, it's good for me to remember just what this means for students on a day-to-day basis, and to find ways to help them face the challenge while they are in the trenches.
All in all, this was a good group of students. They were game for a challenging, deep course and gave me a lot of their time and energy. I can't ask for much more than that. The good news is that they made decent progress and should be better prepared for some of the challenges they'll face in their careers. And a good number of them are going on to the compilers course. Great fun will be had by all.