Skip to content

TeachScheme teaches principles. What do the rest of us teach?

2010 August 12
by Hélène Martin

Bottom line: I challenge anyone who takes an objects-first approach to teaching introductory programming to provide an account of the order in which concepts are introduced tied to the CS principles they illustrate and to articulate reasons for their ordering based on cognitive load for the students (a paper reference will do, too).

I recently spent a deeply engaging and thought-provoking week learning about the TeachScheme curriculum with Kathi Fisler from Worcester Polytechnic Institute and Shriram Krishnamurthi from Brown.  Both have worked with the curriculum since its inception at Rice around 15 years ago.  During that decade and a half, they have contributed to incremental refinements and seen it taught at hundreds of high schools and colleges. My initial thoughts on the workshop can be read here; I’ve now been reflecting on the material for a few weeks and offer some higher level thoughts.

What’s your course’s underlying philosophy?

The authors of the TeachScheme curriculum note that “college is the only time in a programmer’s life when he is exposed to principled ideas on a regular and rigorous basis” [1].  Unlike most approaches to teaching introductory programming, which can be labeled as ad-hoc at best, TeachScheme is based on several ideas woven through all aspects of the highly-structured curriculum:

  • Use of design recipes as a way to systematize the programming process and provide students with a starting point
  • Testing as an integral part of programming
  • Introduction of syntax only as needed to illustrate broader principles
  • Use of an environment which provides error messages appropriate for a learner’s level

While these underlying ideas may seem fairly simple and language-agnostic, I think it quickly becomes obvious that they are not frequently followed in CS1 courses and more subtly, that many modern languages actually guide instructors away from them.

Take the focus on testing, for example.  A Java instructor might say “Aha, I’ll just introduce JUnit early.”  Unfortunately, understanding JUnit requires a lot of background knowledge on things like inheritance, static methods, reflection… sure, one could probably use it just fine by pattern matching, but I think that process takes away from the simple goal: figure out whether an algorithm does what it’s supposed to.  For a beginner, the challenge in testing should be figuring out appropriate test cases, not expressing them.  Worse even is that much of Java code, whether it’s object-oriented or not, includes changing variables and various kinds of output.  These make verifying whether a certain piece of code works as intended potentially quite difficult.

What about introducing syntax in a measured, systematic way?  That’s something I strongly value because I think students with lower computing self-esteem (girls and ethnic minorities) are particularly hard-hit by syntactic ambiguity.  A lot of my hot-headed boys will play around until they figure out how a particular construct works and not be phased if it doesn’t match their initial expectations but I’ve seen many girls think they were dumb simply because I hadn’t properly explained all the possible errors they might encounter in using a new syntactic element.

Most advocates of languages other than Java pounce on “public-static-void-main-string-bracket-bracket-args” as a prohibitively convoluted way of starting a program.  In practice, though it’s irritating and I hate having to introduce it without being able to give much explanation initially, I don’t find that particularly alarming for students — I have them learn it as an incantation and/or copy it and eventually they do understand all parts.  That said, I think the incantation is symptomatic of a broader problem of dependency: lots of constructs in imperative languages are interconnected.  For example, to have any hope of using an iterative construct (while or for loop), a student is going to need to understand the syntax for variable assignment and mutation (storing a value in a variable and changing it).  Even worse, to reliably use variables, a student will need to understand things about memory.  So many levels of knowledge and understanding are required that we can’t get to solving problems — we’re stuck with syntax and semantics.  Python, PHP, C and your favorite obscure imperative language all include these challenges.

Racket: a Scheme variant

As I mentioned in my last post on the workshop, the ideas which have guided the creation and refinement of the TeachScheme curriculum really resonate with me.  In fact, there’s a lot of overlap with the principles that guide my own instruction but I’m all too aware that I constantly make significant compromises.  For example, I don’t have students use formal testing methodology but I have them diff their output (both text and graphical) to expected output.  That’s certainly not as systematic or scalable as I would like.  Another example of a compromise is the previously-mentioned main method header — I accept that I’ll explain it throughout the semester but I still grind my teeth a little at night because of its initial lack of clarity.  My practice is peppered with these uneasy compromises primarily dictated by the fact that I teach procedural languages.

In contrast, the originators of TeachScheme have been unwilling to compromise on the underlying principles.  They are able to do this by using Racket, a variant of Scheme.  The language has been modified to reflect the needs of the curriculum.  For example, it has a check-expect function which can be used inline with other Racket code to compare the result of two expressions:

Dr. Racket check-expect

This makes testing functions simple and systematic.  I think the fact that the language and environment support this style of testing allows some great early conversation on a fundamental principle of computer science: algorithm correctness.

I’ve also attempted to use this trivial example to illustrate the design process emphasized by How to Design Programs, the free textbook that uses the TeachScheme philosophy.  Most approaches to teaching programming rely on showing lots of examples for students to learn from.  TeachScheme is based on the notion that ” implicit learning does not work well for the majority of students. Most students are not the type of learner who can extract abstract principles on program design from a series of examples” [1].  Instead, we should explicitly describe the process of going from a problem statement to a program.  In the example above, I’ve got a comment at the top that includes the types of inputs and outputs (the contract) as well as a short purpose statement.  Writing those comments and the tests were part of the design process.  Of course, this becomes much more meaningful when operating on more complex data such as lists of CDs:

Racket design process

I think the first thing to notice is that a complex data type is defined concisely using a struct at the very top.  There’s no need for a constructor or default values as would be the case if writing a corresponding class.  This enables the discussion of representing and manipulating fairly complex data without getting bogged down in syntax and concepts like mutation.

The three comments following the struct definition certainly look a little odd but they have their reason.  The first block is a “template” for writing a function that processes a CD.  This is an example of a technique used to reduce the “blank page anxiety.”  If a student writes this template, they can see that the only things that can possibly be done by a function that operates on a CD are manipulating its title, its count or its category.

The second comment block defines what a list of CDs is.  Again, kind of weird for those not used to functional programming, but it has its elegance.  There’s no need to define a new data type for a list of CDs, hence the comment status.  The cons function is used to build linked lists “on the fly.”  The comment is again used to reduce “blank page anxiety” and guide students who are getting lost.

The third comment block defines a template for what a function that consumes a list of CDs should look like.  Unsurprisingly, my total-stock function looks awfully similar to it.

I also wrote some sample data as well as a check-expect BEFORE writing the total-stock function.  With the framework in place, writing the function is very simple and verifying its validity is even simpler.  This may seem like a lot of work for a three-line function but it pays off as examples get more and more complex.  For example, take a look at a filesystem assignment.  I attempted it in an ad hoc manner and got bogged down in all the mutually recursive data definitions.  With the templates, I was done in no time.

Why isn’t it more popular?

Principles may be front and center, but TeachScheme is not a fashionable approach.  First of all, the functional programming paradigm is not very common.  A quick glance at the charts on langpop.com shows imperative and OO languages like Java, C, C++, PHP, etc at the top and functional languages like Lisp, Scheme, Haskell, etc, pretty low on the ladder.  That can be discouraging for students who hope to immediately be able to get an internship or write something that looks like a Windows native application.

Secondly, the signal to noise ratio in functional programming is very high.  In other words, programs are generally quite short, but every line requires deliberate thought.  I think that makes a lot of people shy away from it and treat it as harder than imperative programming.  Related to that, there’s a kind of inertia: if instructors learned procedural or OO languages first, it’s only natural that we’d be uncomfortable reaching out of our expertise, especially to something we have considered harder.  I think the sacrifice here is that although functional programming leverages existing math knowledge, algebra is already quite hard for a lot of people, thus not easily available for transfer.  I also think most people consider software in terms of what it does rather than what it computes and that lends itself better to imperative programming — do this, then change that, then call that routine, etc.

Unfortunately, I suspect the real reason TeachScheme isn’t more prominent has more to do with egos than with technical merit.

Scorn is not a good advertising tactic

Before going to this excellent workshop, I had heard of TeachScheme but generally not in a very positive light.  One of the other workshop participants summed it up in a way I really liked — “scorn is not a good advertising tactic.”  First of all, most of the functional programmers I’ve known, from high school and beyond, have been incredibly brilliant and unwilling to suffer fools, otherwise known as people-who-program-in-PHP-omg-that’s-a-disgusting-language — people like me.  As a result, I was, as many people are, mostly intimidated by functional languages.

Then, there is an aura of religious zealotry and inflexibility around the TeachScheme materials.  I think a lot of people feel threatened by the vague “if you don’t think this is the right way to teach intro CS you are dumb” vibes exuded by the project.  I don’t know quite where those come from, but I don’t think I’m the only one who has felt them.

My next steps

I’m going to be using the TeachScheme curriculum in the fall with my advanced AP class composed of students with some prior programming experience.  I think they’re a good group to focus on principles with because they have enough background to grasp the implications of these principles.

I’m a little more willing to compromise, though, and I’m not ready to make a complete switch.  That said, I think I can be more deliberate about using a lot of the principled ideas in my procedural to OO classes in Java and Python.  It’s also become even more clear to me that starting with objects first is not of interest to me — I think the sacrifices are too great.

Above all, I’m going to continue my search for a single other coherent approach to teaching introductory programming which has gone through such methodical review.  I’m disappointed not to have found any; pointers would be appreciated.

  1. M. Felleisen, R. Findler, M. Flatt, and S. Krishnamurthi, "The structure and interpretation of the computer science curriculum," Journal of Functional Programming, vol. 14, iss. 04, pp. 365-378, 2004.
43 Responses leave one →
  1. August 12, 2010

    Interesting stuff, keep it up.

    I think scheme is a great teaching language… and Java is just a poor language all around.

    That said, I do think the “state manipulation is too difficult” line that usually comes along with FP languages is a bit overstated. In imperative programming, people need to learn hygiene associated with state use definitely, like reducing the scope of state (avoiding globals or static variables), or mediating access to state with procedures that protect invariants.

    I think an FP first approach is great, but… I’ve also been in a lot of classes where profs who lurve java will complain about things like C, pointers, manual memory management, gotos, etc. I worry that students take that stuff as gospel, and develop a mental block about things that aren’t actually that difficult, and which are sometimes useful.

    So, while I think FP is great, I think the *doctrine* that goes along with it can be harmful, in the way I think the “java doctrine” is kind of harmful, by making people scared of other ways of doing things.

    Anyway, sorry for the long post, obviously I can’t stay out of any discussion about PL :p

    • Hélène Martin permalink*
      August 12, 2010

      I love your comments, Brendan! And I’m the one who just dumped a ridiculously long post, so don’t apologize about length. =)

      I agree that doctrine is bad in general. I think you also make an interesting implicit point — students will find things hard if they’re presented as being hard by their instructor.

    • Mark Engelberg permalink
      August 13, 2010

      Brendan,

      I just wanted to point out that the How to Design Programs curriculum does in fact have some useful things to say (towards the end of the book) about how to design code involving mutation, how to isolate those mutations behind procedural abstractions and reason about invariants. Scheme offers a full range of mutation capabilities (although arguably mutation ends up looking a bit uglier in Scheme than it does in languages whose syntax is optimized for that kind of paradigm), and Racket actually offers the option of using a highly elaborate object oriented system that closely mirrors that of Java (but with some extra dynamic capabilities). Racket’s own GUI libraries, for example, are designed using the object-oriented portion of Racket.

      So you won’t see too much outright bias against mutation among Racketeers. However, you will definitely hear Racketeers complain about languages that “force you to use mutation all the time”.

      My Scheme students with prior programming experience are frequently astonished at just how much it is possible to accomplish without using any mutation. I think this realization is a valuable lesson for our future generation of programmers who will be expected to build ever more reliable code.

      link to info.ucl.ac.be is an interesting article (one of several that I have seen) that argues that the future of programming languages is a layered design, in which the language offers some sort of “pure functional subsystem” in which you spend most of your time because it’s the easiest to reason about, and then some sort of advanced mutating capability where you tackle the problems that really need that level of expressiveness (and possibly some layers in between these extremes). If you buy into that argument, then Scheme does a nice job of preparing students for that “layered” future.

      • Hélène Martin permalink*
        August 13, 2010

        Good point, and I think that illustrates the idea that concepts should be laid out so as to avoid cognitive overload for students. Mutation is a really difficult thing to build a correct mental model of and yet most teachers middle school to college spend all of 30 seconds on it! I think once you reach it in HtDP, it can be presented in a more meaningful way.

        Very interesting article — thanks for sharing.

  2. August 13, 2010

    I just don’t see the point of starting programming education in a functional language. Yes, certain tasks are simpler in functional languages. But many are not. And the functional way of thinking just isn’t how humans picture and model computation. We think imperatively: do this, then do that. Languages that mirror that model are the most intuitive.

    I think that the TeachScheme zealots present a false dichotomy. They say, “procedural/OOP languages have confusing syntax and are hard; our pretty language has easy syntax and is great.” Well, maybe they’re looking at the wrong procedural/OOP languages. Or maybe the right procedural language doesn’t quite exist. Something like Python gets around the main method problem, and it mostly gets around the “have to know variables to do repetition” problem, and several others. Procedural does not imply ugly syntax; functional does not imply beautiful syntax.

    I also think that functional languages force the programmer to over-emphasize recursion and to express many operations in self-similar terms that are not really self-similar. Just because recursion is equal in expressive power to iteration does not mean it is the appropriate model for expressing all computations.

    Functionites claim that mutable state is the devil and is very hard to understand. I think it’s very natural and an inherent part of the computing process. I get that mutable state makes it harder to formally verify programs. But nobody really wants to formally verify programs in the first place. Being able to remember things in the computer’s memory (and change them later) is an important part of what the computer does. Ignoring that means artificially limiting oneself for some odd notion of conceptual purity.

    For what it’s worth, to my eyes that Scheme code for the CDs is mostly dreadful, especially the part wher MY-CDS is declared by cons’ing things with a million parentheses. There’s a reason nobody uses these languages…

    • Hélène Martin permalink*
      August 13, 2010

      Marty:

      I mostly agree with what you have to say but one of my biggest realizations from this experience is that the Back to Basics approach and TeachScheme are more in agreement than at odds. I suggest an alliance — I think there are some much uglier non-methodologies out there.

      The important thing for me is the deliberate sequencing of topics and the polishing over years and years of working with real students. I think that’s really important and I’m skeptical of folks who claim to have figured out an amazing thing after they’ve done it once.

      I tend to agree that the parens are dreadful but I do notice that when I get into a Lisp zone they kind of go away. In general, though, I think it’s harder to READ functional code, possibly because of the high signal to noise ratio or maybe just because it’s a less natural way of expressing algorithms (at least for me). That’s a big negative.

      Overall, I think there are significant compromises on both sides. You or I may not feel strongly enough about testing to bring it front and center, but I see why someone would want to. I agree that there’s value to teaching a directly usable language, but I see why someone would prefer a very small language. The trouble is that the compromises are so different that they’re hard to compare.

      I’m going to start using the word ‘functionite’ in casual conversation…

    • Lon Levy permalink
      August 14, 2010

      First, let me ‘fess up that I have been using TeachScheme! materials for several years. That said, I come from a pre-structured programming background. Modular programming (remember?) was the better than sliced bread. Functional was a big hurdle for me.

      “I just don’t see the point of starting programming education in a functional language. …. And the functional way of thinking just isn’t how humans picture and model computation. We think imperatively: do this, then do that. Languages that mirror that model are the most intuitive.”

      We do think imperatively. We also think algebraically.

      “I also think that functional languages force the programmer to over-emphasize recursion and to express many operations in self-similar terms that are not really self-similar. Just because recursion is equal in expressive power to iteration does not mean it is the appropriate model for expressing all computations.”

      I am reminded that anything that can be coded using recursion can be done iteratively and vice versa. In terms of the computer, poorly implemented recursion is far less efficient than iterative loops. However, if the recursion is implemented correctly, it is more efficient. Neither of these should be issues for beginning students.

      My observation (completely anecdotal) is that if one learns iterative loops before recursion, the loops are a challenge and recursion is a bear. Learning in the opposite sequence means that recursion is a challenge and loops are no more of a challenge than they were previously.

      I would not advocate teaching recursion to the exclusion of iterative loops. But, the sequence of learning can be important. I now delay loops for quite a while.

      “Functionites claim that mutable state is the devil and is very hard to understand. I think it’s very natural and an inherent part of the computing process. I get that mutable state makes it harder to formally verify programs. But nobody really wants to formally verify programs in the first place. ”

      Excuse me? In the old days, when I was starting out in computing, acceptance testing was good enough for almost everything (except, perhaps, NASA). My understanding is that more and more of industry wants proof that the code they are using works correctly.

      “Being able to remember things in the computer’s memory (and change them later) is an important part of what the computer does.”

      A little quibble here. You can’t mutate memory. You can change the state of memory locations (load new information in).

      “For what it’s worth, to my eyes that Scheme code for the CDs is mostly dreadful, especially the part wher MY-CDS is declared by cons’ing things with a million parentheses. There’s a reason nobody uses these languages…”

      The TeachScheme! curriculum begins with the (cons x (cons y (cons … empty)))))) notation so that students can learn about and become accustomed to the self-referential nature of the data. As students, correctly, get fed up with typing cons a gazillion times, they move to a more efficient model of (list x y …).

      Three last notes.

      Antepenultimate note: The number of parenthesis can seem daunting. I would say that Java (which I understand to be the plurality educational language) is even more daunting in terms of the numbers of {([])} which which one must contend.

      Penultimate note: The exclamation mark on the end has the traditional meaning in computer science. It’s not about Scheme. It’s not about Racket. Those are learning tools. For most of us, it is not the goal to become or produce Schemers or Racketeers.

      Ultimate note: I am not a member of PLT, just a teacher using their materials. Any mistakes I made in this response are mine and belong to me. Anything right probably belongs to someone else. :-)

      • Hélène Martin permalink*
        August 14, 2010

        Lon:

        Thanks for your valuable perspective — one of my next steps is to get in touch with teachers who use the materials and ask them about some of the things you’ve already mentioned.

    • August 19, 2010

      “I get that mutable state makes it harder to formally verify programs. But nobody really wants to formally verify programs in the first place.”

      It’s not just about formal verification, but even “acceptance testing”.

      If a function depends only on its arguments, and produces nothing but a return value, you can write a dozen test cases in as many statements, re-order them, comment some of them out, etc. without screwing things up. If it depends on mutable state, each test case requires several statements (set variables, call function, check variables), and inserting, deleting, or reordering test cases can change the results.

      I have very little difficulty getting the students in a college-level “computer programming for non-CS-majors” course to write decent test suites for every function — indeed, to write test suites before writing the function itself. And I teach them to look for patterns in which test cases pass and which fail (for example, if everything passes except the borderline cases, you’ve got a < where you need ≤ or vice versa). If they had to deal with all the issues I mentioned in the previous paragraph, they’d be reluctant to write test suites at all.

  3. August 13, 2010

    Forgive me for I only read parts of your post in detail, and skimmed the rest, but it seems like at least one of the reasons you’d like using Racket as the language of choice is because it removes some of the syntax that students have to take for granted until they get advanced enough to understand the concepts behind them.

    Unfortunately (from my perspective), this comes with the tradeoff of grounding students in functional programming rather than imperative, which are two rather different worlds. (As you well know,) most programming is done imperatively these days, and I actually have coworkers that grew up with functional languages — despite the fact that we all write Java, Ruby, and Javascript, their approach to programming is very clearly different from those of us who grew up programming imperatively. I don’t know if this is necessarily a bad thing, but clearly what philosophy you start out learning in has a strong impact on your entire mental formulation on how to program computers (excuse my completely non-correct pedagogical terms =) ).

    If this is a concern, and you like the idea of reducing confusing syntax, might I suggest using a language with enough metaprogramming that you can do a little bit of work to remove those confusions? Ruby is probably the most flexible and well-known for this purpose, though its perhaps over-the-top willingness in what it accepts syntactically and the difficulty of debugging it are good reasons not to use it, if you can’t successfully restrict the range of what it allows.

    On the flip side, though, Ruby is amazing at (and widely appreciated for) creating succinct, powerful DSLs for doing various things. Sinatra (link to sinatrarb.com), for instance, reduces the act of programming a web server to a tiny bit of code. RSpec (link to rspec.info) is a little less terse, but it makes writing tests rather simpler. One could imagine easily writing a DSL to make teaching programming easier, such as a easy way to define basic struct-like classes like you note above.

    Hackety Hack (link to hacketyhack.heroku.com), made by the late and great _why, is at least a step in that direction, though it’s intended more for self-discovery and experimentation than for structured classroom instruction.

    And, since it’s got the trappings of a scripting language, you can just write code, put it in a .rb file, and watch it run without having to wrap it in a class and a main method.

    This is a radical suggestion, I know — but given at least a bit of what you appear to be saying here, I don’t think it’s an unreasonable one.

    • Hélène Martin permalink*
      August 13, 2010

      Clint –

      Totally agree that the paradigm one starts with is going to have a big impact on problem-solving approach. I’m also struggling with the implications of this. Clearly functional programming is less typical, so that may be a problem. On the other hand, students who go on in computer science will learn an imperative language, so maybe I can do a good thing by exposing them to something else as well so they can have more in their toolbox.

      I shy away from using Ruby or Python functionally because they both have so much going on and because most external libraries are procedural/OO. I think it’d be hard to stick to a strict functional style. Not sure about domain specific languages, either, since that seems to defeat the purpose of using a popular language? I like Racket because it has some nice libraries, DrRacket has some nice stuff and it’s ‘pure.’

      I do like Hackety Hack and Ruby in general. I think I’m more likely to teach it in my more comfortable procedural->OO style as a replacement for Python when I get tired of it.

      No, not unreasonable suggestions at all! Love to hear your thoughts. All of this stuff goes somewhere in my brain and helps shape what I ultimately do.

      • August 14, 2010

        re: your point about a DSL defeating the purpose of using a popular language, I don’t think so. Ruby DSLs tend to be really nothing more than syntactic sugar that wrap Ruby into prettily named blocks. The point is usually to hide away the underpinnings of a particular system and let one focus on the higher-level implementation details; I don’t think that point changes here.

        If you want to read input from a file in an assignment, for instance, but you don’t want to have to make students write boilerplate OO code that they don’t yet understand in order to read said file, you could construct a bit of framework behind the scenes such that all the students see/need to write is something like:

        require ‘helenes_awesome_framework’

        file ‘filename.txt’ do |contents|
        puts ‘The longest line is ‘ + contents.map{ |line| line.split(/ /).size }.max + ‘words long.’
        end

        The file command here would load up the file and parse the contents as an array of lines for you, and the rest is idiomatic Ruby. Which is really a strike against Ruby, because it’s full of strange symbols for its syntax. I don’t know how a beginner would deal with |variable| notation for passing in params to blocks. Similarly, one could imagine writing a simple version of RSpec’s DSL, which looks very much like english and is thus very easy to learn, to have students write simple tests:

        test_that “math works” do
        sum = 3 + 3
        sum.should == 6
        end

        Of course, if the point is expressly to teach very, very strictly OO-less; or very, very strictly functional programming: there isn’t much leeway for that in Python, Ruby, Java, C#, C++, et al. At that point, you’re left with C (ha), or Scheme/Haskell/some other functional language. One option there is easy to rule out. I happen to think that Haskell has much less cryptic syntactical bits (parens and cadrs and cdddrs etc), but it also requires some more theoretical absorption up-front (currying etc).

        Either way, at that point, then, we’re left with the question of precisely how stringent we feel we need to be about procedural-first vs objects-first (and now, I guess, even vs functional-first). Here’s my $0.02 on the matter, being fully aware that you’ve discussed this topic here in length; I haven’t myself weighed in on it yet:

        1. Personally I think procedural-first is correct vs functional (I will justify in points 2 and 3) and vs objects-first, but I don’t think that going with procedural-first means we need to completely avoid anything to do with objects. Personally, I learned programming without outside guidance, in VBA on Microsoft Access. I didn’t know much, but I did know that I could draw a bunch of buttons and textboxes on a page, give them names, and then when I was writing code they would magically be there for me to use. I then learned that I could talk to these buttons and textboxes and set “properties” on them, which made them do stuff. (My favorite were .Top and .Left, together with a timer =) ). At this point, I was interacting with objects and instances and methods, but I had no idea that that was what I was doing, and I don’t think it matters that I didn’t.

        2. Tangentially from 1, then, I think there is significant value in making UI and other whiz-bang programming imminently available and accessible to the most beginning of students. I think that for a very tiny subset of students, Mark’s comment that “introducing programming in a way that synergizes with algebra is indeed a very powerful approach,” but that subset of students is highly math-oriented, and those sorts of people will likely pick up Computer Science of all colors without much trouble to begin with. (If they don’t pick up procedural programming, that’s okay — we need more mathy theoretical CS people figuring out P ≠ NP anyway =) ). Rather, I think the majority of students would be much more engaged if, with a couple lines of code (again, see Hackety Hack), make their own music, or make a box move across the screen. The power of creation can’t be underestimated in motivation and excitement; and I think (to bring in yet another thorny issue) this applies across genders and gender stereotypes.

        There’s a good reason we make people print Space Needles before they do anything else. In fact, I think we can do better than ASCII art, and if we are able to leverage the expressive/metaprogrammatical power of some of these newer languages, we can do so in a comfortable way for beginning students. There’s also a good reason why Marty’s web programming class is so popular.

        3. Following 2 (by contrapositive), and in response to both Marty and Mark, I believe that the problem with a functional-only/first approach is that it takes for granted a student’s desire to learn programming. If you have a highly motivated, math- or algorithm- oriented group of students whose collective hearts are set on figuring out this crazy thing that is computer programming, then it’s a perfectly valid approach — these students are going to need to be happy with themselves for being able to manipulate a data structure full of numbers or text into another data structure full of numbers or text… and that’s it. It’s not terribly exciting no matter how you slice it, and on the surface, it doesn’t necessarily feel too useful. Unfortunately, since any sort of I/O in purely functional languages is complete hell even for people with a solid amount of experience (cf. me for instance), there’s really no way around that particular blocking point. Functional programming is, to put it bluntly, rather boring. And mathy, as Mark pointed out.

        Of course, all this is based on my own experience with coding and informally tutoring fellow students in and out of UWCSE over the last 14 years of my life. Other people’s mileage may vary, but considering that I’m a pretty average person I think, I’m willing to stand by my stated opinions here for the majority case.

        I appear to have written an essay in your comments. Whoops. =)

        • Hélène Martin permalink*
          August 14, 2010

          Clint:

          Another set of insightful thoughts!!

          I didn’t realize quite how Ruby DSLs work. Very interesting. I’ll have to look more into that.

          I’m not considering this teaching tactic for my students at large. The group I’m targeting is much as you describe it — already sold on computing, curious about some of the theoretical underpinnings, etc. I think it will be appropriate for them IF I do it right.

        • August 19, 2010

          [The following is from a teacher who uses How to Design Programs but is otherwise not involved in its, or Racket's development.]

          Hi Clint,

          Three comments:

          First, “algebraic thinking” centers on constructing and evaluating expressions (and performing substitutions, but that’s a side issue for now). These are tremendously necessary skills, even for highly imperative code; understanding your example definitely requires them:

          file ‘filename.txt’ do |contents|
          puts ‘The longest line is ‘ + contents.map{ |line| line.split(/ /).size }.max + ‘words long.’
          end

          Everything between puts and end is a big expression. In my experience, constructing such expressions is something beginning students have a tough time grappling with. As a teacher, I’ve found this is where the How To Design Programs curriculum shines: it gives the students some clear, easy steps to try when called upon to put together a complex expression.

          Second, regarding thinking imperatively vs. declaratively (which is a more relevant term than “functionally,” here): I’d argue that in many situations we’re much more comfortable, naturally, thinking declaratively. Consider the difference between the two questions: “What’s the movie ______ about?” and “What happens in the movie _____?” The first is what we typically ask, and it elicits a simple declarative answer that (we hope) gives us an intuitive idea to grab on to. The second would elicit a sequence events (“Well, this guy is late to his wedding, so he calls his friend for a ride, and then…”), and most of us would tune out after the third or fourth step.

          Usually when we think imperatively and want to get something right, we have to think very slowly and deliberately (like when giving driving directions, for example). This is because sequence matters.

          Third and finally, I’ve found the HtDP curriculum and DrRacket provide problems and programming ideas that work very well with students who are not particularly mathematically inclined. So please don’t think we’re taking inherent desire to program for granted: a lot of us teachers take very seriously the requirement to “sell” our subject to the students. We start early on with animations, games, and interactive web pages, to keep it fun even for those who don’t dig mathematical abstractions.

          Regards,
          jmj

          • Hélène Martin permalink*
            August 19, 2010

            The movie topic versus sequence of events example is thought-provoking… not sure quite what to make of it. I agree that giving precise, properly sequenced imperative statements to complete a task is difficult and I also think it’s an important skill to practice. I also agree that constructing and evaluating complex expressions is a difficult thing that’s desirable to master. I’m glad to hear that you too have had success with using HtDP.

        • January 20, 2011

          there is significant value in making UI and other whiz-bang programming imminently available and accessible to the most beginning of students.

          Absolutely; that’s why the TeachScheme! people have been using more and more graphics and animation, earlier and earlier, over the last ten years. My textbook Picturing Programs starts with graphics on page 1, and doesn’t mention arithmetic operators until chapter 7. Emmanuel Schanzer’s Bootstrap project (aimed at middle-school students) likewise emphasizes graphics and animation from the beginning.

          any sort of I/O in purely functional languages is complete hell even for people with a solid amount of experience (cf. me for instance), there’s really no way around that particular blocking point.

          On the contrary, dealing with graphics in DrRacket is much easier than text I/O in Java, and possibly even easier than text I/O in C++. Very simply, the REPL recognizes “image” as a data type, along with “number”, “string”, etc. This means several things:

          you can copy-and-paste an image from somewhere else into the IDE and it’s treated as a literal of type “image”.
          if you evaluate an expression of type “image”, it shows up in the REPL just as if you had evaluated an expression of type “number” or “string”.
          In addition, we have a purely-functional API for GUI programming (in a nutshell, you provide a model->view function, the “draw handler”, and some model->model functions like the “tick handler”, “mouse handler”, etc.). Using this API, I start my non-CS-major students writing event-driven separable-model GUI programs after a few weeks.

  4. Mark Engelberg permalink
    August 13, 2010

    Marty said:
    “And the functional way of thinking just isn’t how humans picture and model computation. We think imperatively: do this, then do that. Languages that mirror that model are the most intuitive.”

    Surely there is more than one way to picture and model computation. How do you picture and model an arithmetic computation, like 2+3? Sure, maybe in Kindergarten, we teach kids to start with a pile of two beans, and count three more beans into the pile, then count the total number of beans in the pile. But certainly by high school, nobody’s really thinking of arithmetic as a destructive operation. And that’s in part because there’s a limit to what kind of math you can hold in your head if you’re worried about the details of adding beans one by one to a pile to do a computation.

    Which model of computation is “most intuitive”? I still have my programmable calculator from when I was a kid. To program an arithmetic function, I had to carefully code a step-by-step assembly-like sequence that laid out what values would be placed in which of four registers, and operations that combined the contents of some registers and placed the results in other registers. But no modern language expects you to describe arithmetic operations at this level of detail. So which model is more intuitive? I’d bet most people would say the non-mutating version, where you just write out the overall computation you want and the computer works out the details, is the more intuitive.

    There’s a reason why most recent languages have decided to make strings and string operations non-destructive. There’s also a reason why most languages provide some sort of mutating “StringBuilder” class for the operations that can’t be done efficiently in a non-destructive manner.

    Don’t you think we owe it to our students to provide them with an appreciation for why both of these computation models are valuable?

    The TeachScheme approach doesn’t deny that multiple models of computation are valuable, but it argues that the easiest one to start with is the one that most closely parallels math/algebra, because that’s the model of computation that students have spent several years of their life already learning. My own personal experience is that introducing programming in a way that synergizes with algebra is indeed a very powerful approach.

  5. John Burnette permalink
    August 13, 2010

    Interesting post, but it requires two important corrections.

    (1) The name of the curriculum is TeachScheme! Perhaps it would be a punchline more people got if it were written TeachScheme(!), as in, it’s **NOT** about a choice of which language to teach first (whether Scheme or Racket, or (insert your favorite language here)) It’s about constructing a coherent introductory curriculum and a programming environment which fully supports that effort.

    (2) While the text “How to Design Programs” is freely accessible on line, it is not a free textbook. From the copyright statement:

    “Copyright © 2001 Massachusetts Institute of Technology

    Illustrations © 2000 Torrey Butzer

    All rights reserved. No part of this book may be reproduced in any form
    by any electronic or mechanical means (including photocoying, recording,
    or information storage and retrieval) without permision in writing from
    the publisher.

    This Web tree is the publisher-endorsed, on-line version of the book.
    You may purchase a paper copy directly from MIT Press
    or any other bookstore. “

    • Hélène Martin permalink*
      August 14, 2010

      John:

      Blasphemous as it may be, I think the exclamation mark is just annoying. I’m aware of what it means, but that’s not how it comes across to someone who hasn’t read the explanation so I’d rather leave it off because it’s distracting.

      I’m afraid I don’t really understand the ramifications of your second point. Teachers can point their students to HtDP readings, which is what I think is really important. It can’t be repackaged or remixed, that’s correct. Is that a big limitation?

  6. David Binnion permalink
    August 14, 2010

    Marty – I think you are focusing on all the wrong things. I can’t document that a functional language such as Racket or Lisp is any easier to learn than an imperative language but I can document that Racket IS easier to teach and learn than any imperative language I’ve learned or taught. It isn’t just a question of the language, it is the entire development environment that makes the TeachScheme! project work. By switching the language to Beginner I can keep students from accidentally discovering and tripping over things that will create barriers to their learning.

    Perhaps people don’t think in a functional manner but I think it is just as easy to argue that people don’t think in an imperative manner either. For example, I think, “Time to get up and get breakfast.” I don’t think, “Pull back covers, swing legs to floor….”

    The TeachScheme! people discovered the same thing I did but they were much more systematic and structured in their attack of the problem. They discovered that the first introduction to programming isn’t about teaching a language – it is about teaching students how to think. How to look at a problem, how to conceptualize a solution, and how to turn that abstraction into working code. Most approaches to programming simply assume students can do the first two things and move on to the last and that’s why so many students fail to move on from CS1 to CS2 (let alone survive CS1).

    The point about syntax is very simple and it isn’t a religion, at least not with me. In the first week I can present the syntax rules my beginning students will use all semester – no exceptions. That takes a big load off of me and them. The whole point is to eliminate the barriers that make teaching an intro class difficult and remember, we are focusing on teaching the students problem solving techniques, not teaching a specific language.

    Your objection to all the CONSing of the list in the CD example is a trivial one and you missed the larger issue. CONSing a list is a purposeful way of teaching students how to create a list. A list is constructed by CONSing an item to a list: (CONS 12 (CONS 15 EMPTY)) for example. It is important for students to deeply understand how a list is constructed because it is directly related to the way a list is manipulated. And this point is true for all programming languages, imperative or functional. However, once my students have mastered this concept I introduce them to LIST: (LIST 12 15) for example. By the time I introduced them to a list of structures like the CD example, they’d be using LIST and the whole parens thing becomes trivial. What isn’t trivial is that the shape of the data determines the shape of the problem and that is a huge tool.

    I attended the introductory TeachScheme! workshop in 2001 on the recommendation of a friend. I was no big fan of Scheme prior to the workshop – I’d suffered through a semester of Lisp in college – but by mid week I was well on my way to thinking about how I’d incorporate it into my curriculum. I wasn’t disappointed.

    Some students come into a programming class with good problem solving skills and a firm grasp on the concept of cause and effect. Sadly, most do not. For years I used a number of different languages and refined my teaching techniques but the results were all similar. Those students who could already think learned to program; of those who had poor problem solving skills, some would muddle through while others dropped out either physically or mentally. Sadly, I had a small impact on students who weren’t problem solvers already.

    There is no question that using the TeachScheme! curriculum has allowed me to give students a set of tools to make them into good problem solvers, and to make good ones better. The number of students who physically or mentally drop out is much smaller than it used to be. The number of students who move on to the next class has increased. Could the project be recreated with an imperative language? Maybe, but I’ve not seen any examples of that yet.

    • Hélène Martin permalink*
      August 14, 2010

      David:

      I don’t think I quite stressed enough how valuable the language levels idea is. For me, one of the biggest challenges in teaching programming is students stumbling on new ways to use things they have learned that they can’t fit into a mental model.

      I appreciate hearing your experience — cool to read how others have been convinced of the merits of this approach.

      I also want to note that I really do believe that Marty and Stuart Reges at the University of Washington have largely created a similarly well-structured and deliberate introduction to programming despite working with the fairly disgusting Java. I think that’s why it’s a touchy issue for Marty. :O

  7. August 14, 2010

    Helene, just a few comments on perspective:

    1. TeachScheme! is about systematic design from the get-go. The design recipe has successfully been applied by our students to the full range of PLs, including assembly, Perl, Python, Ruby, and Java.

    2. We teach the functional version first because functional is just mathematics at the K-12 level. This is particularly obvious when you see how easy graphical interactive I/O is (for the simple things you want to teach at this level).

    3. As Mark pointed out the emphasis is on inductive programming first, indexed programming second. That’s reverse of what you normally encounter, and that is done for many different reasons. One post-hoc justification is Josh Bloch’s book on Java; here is the architect of Java’s API writing that “I wish I had made the API a lot more functional.” An old justification can be found in the original (1970s) writings on Smalltalk, especially by Kay, who wrote (among other things) that he wanted to abolish assignment statements (i.e., plain imperative programming) — especially in the context of using these languages with children.

    Over the 15 years of work, we have repeatedly integrated ideas from elsewhere and we have expanded the range of our topics. We take the ‘not Scheme’ extremely seriously and demonstrate to anyone/anywhere how the design ideas of HtDP relate to the rest of the programming work. We reject the idea that our work is written in stone at any point in time and finished. Researchers can’t bring such an attitude to their work; it kills minds. So I don’t know why you call us close-minded or ‘the right way’ people, but I take it that someone/somewhere is doing better (anti)marketing than we do.

    (Thanks to Mark for pointing me to your write-up.)

    • Hélène Martin permalink*
      August 14, 2010

      Intimidating to have the guru get involved! Thanks for your comments.

      As I said in the post, I really do agree with the guiding principles and I’m excited to work through the material with my students.

      Can you point to an example of a course that does TS! in Python? I would love to take a look at how an instructor approaches that. I assume that when you mention Java you’re talking about the ReachJava portion of the curriculum using How to Design Class Hierarchies?

      I don’t buy the idea that functional is “just” K-12 math or “the language we already know.” As other commenters have mentioned, algebra is really hard for even a lot of adults. Bootstrap resonates with me because instead of assuming all the algebra background and working from there, it uses programming to strengthen algebra skills. I find that to be one of the weaker arguments for the pedagogy and just too easy for people to disagree with.

      It’s obvious that the materials have gone through a tremendous amount of review and that in and of itself is reason to trust the approach. I’m very skeptical of teaching methodologies that have emerged in the last six months being lauded as the way to fix computer science education.

      I don’t think there’s much anti-marketing out there — not sure what the point would be — just zealous followers making disparaging comments about the computer science education community, the choices many educators make in good faith, etc. Whether they’re correct in their criticisms is beside the point; it just leaves a bad taste in the mouth of those of us who are relatively new to computer science education and trying to find our way around the space.

      • August 14, 2010

        Helene,

        I take you up on the algebra point.

        with due respect to a person that I haven’t met, but in my 30 years in the US I have encountered a lot of teachers who say “students can’t understand algebra” and then teach with exactly the predicted results: their students can’t understand algebra. I have seen some edu school algebra courses, and I am not surprised any more.

        On the K-8 end: If you saw Emmanuel’s Boostrap talk, you know that we reach kids from innercity neighborhoods that such teachers have given up on. Many of these kids graduate from Bootstrap with a much-improved understanding of expressions, variables, functions and the evaluation process. They are “suddenly” able to solve problems and to pass state-mandated algebra tests. Emmanuel may also have mentioned that algebra scores are a direct predictor of income (according to the US DoED) under otherwise equal conditions. This applies to programmers, civil engineers, lab technicians, and others.

        At the other end: If you have ever produced commercial software that demands extreme reliability, you know that the only way to reason about software — written in FP, OOP, Structured or no style — is some form of algebra. You also need a form of logic that generalizes algebra. Some programmers master this insight w/o formal background; most don’t. A part of the so-called “software and security” crisis (I didn’t make up this term) is due to the fact that we don’t train programmers in “algebra” and some instructors even tell students that they never need to.

        In short, algebra and programming are in a symbiotic relationship. You are free to deny this relationship, and many people do — on your blog. That doesn’t mean it doesn’t exist, it doesn’t mean it doesn’t help. I am free to advertise it as the right starting point for many reasons (see my CACM paper with Shriram). That doesn’t mean I think it is the only form of programming, it doesn’t mean I use it exclusively (I don’t), it doesn’t mean I don’t teach anything else (I do!). But 20+ years of experiments at this level of instructions have taught me that it is the right starting point for programming.

        In contrast to the people who — on your blog — condemn FP and throw us in with their whole-sale condemnation — not having read any of our materials as their posts show — all of us have gone thru plain old imperative training; many of us have taught imperative programming. We do have the background to evaluate and to judge.

        The one thing we may get wrong is to teach the somewhat-better language first. As one of my first MS thesis students used to say, “people have to go thru hell first so that they can appreciate heaven; I will teach imperative programming first”. Perhaps she was right.

        • Hélène Martin permalink*
          August 14, 2010

          Matthias:

          Note that I didn’t say that students CAN’T understand algebra. I claimed that in practice many of them don’t, for any number of reasons, including poor teacher preparation. As I said, I like Emmanuel’s approach because it treats algebra knowledge as a desired outcome rather than an assumed precondition. I don’t disagree that algebra and programming are closely related. That said, I do believe that claiming that functional programming is more natural because it’s like algebra is not a compelling argument for using TeachScheme!.

          I’d like to note that in this last comment you’ve spoken disparagingly about other posters (whom I have deep respect for), ed schools, math teachers, me. You also end by implying that the ONLY thing the approach gets wrong is teaching a better language first. Again, you may be entirely right, but what matters more is the emotional impact. My initial post was gushing about the program’s merits and all other commenter’s posts were constructive. Now I’m feeling attacked and defensive. Just something to think about.

          • August 14, 2010

            Helene, I didn’t attack you. I addressed what I considered a misunderstanding. Your reply makes me think that perhaps I misunderstood your claim about algebra. Apologies for creating the impression that I attack you. Far from it. Read on.

            I do criticize posters on your blog (and other blogs) who immediately attack our ideas (I am sorry but I have no other word, criticize is too weak) and our program with words that suggest that they made no effort to read our materials, to understand our goals, to figure out our universal innovations. You have done so, and I applaud your participation in one of our workshops and your critical thoughts. Teach our curriculum, criticize us based on your experience, and you will find that we are positive about criticism.

            I do criticize ed schools. If I were to list all my grievances with them, I would run of out bits to write them all up on this blog :-) I know that I am not alone with these criticism; indeed, I have heard such criticisms from the dean of a (non-conventional) local ed school with whom I had lunch not too long ago.

  8. Pat St.Clair permalink
    August 14, 2010

    On a much lighter note…this discussion has moved attending a TeachScheme! workshop way, way up on my ToDo list. Would you mind pointing me in the right direction for getting some funding to cover my expenses?

    • Hélène Martin permalink*
      August 14, 2010

      Pat:

      The workshop page should eventually be updated for 2011. I’m planning on applying again so I can look more into the Java transition — I’ll make sure to let you know when registration opens (probably in the spring). It’d be fun to see each other again there!

    • August 17, 2010

      Hi Pat,

      We can cover the costs of university educators, and perhaps even some high-school educators.

      More to the point, we never charge anything — you don’t pay for the workshop, the books, the software, or anything else — so at the very least, if you and/or your school could get your to the workshop and back, you wouldn’t be paying a single cent more. This is very important part of how we operate.

  9. August 14, 2010

    Very interesting and thought-provoking post!

    I have several comments to add:
    * I have taken to thinking of HtDP as a “functions-first” approach — because of the CS1 courses’ requirements where I teach, I have to get to imperative and (depending on the intro course) object-oriented programming by the end of the semester. But that doesn’t mean I have to start the semester using them… 8-) Functions-first — and mutation a few weeks later — seems like a reasonable progression.

    (So I only get to use the first few sections of HtDP — someday I’d like to try using the rest!)

    * I was so taken with the design-recipe and early-testing aspects of the HtDP approach that I just couldn’t go back to teaching C++ the way I had before. So I built Perl scripts that let me start C++ functions-first. (Then, after a few weeks of this, then we get to the main function, I/O, and actually changing variables.) And I have also taught functions-first using Python. So, yes, these principles can be used with different languages.

    (Aside: after a few semesters of this, though, I finally decided that I wanted to try starting the semester in Scheme/Racket, and then transitioning to the required C++.)

    * …but someone was mentioning, in the discussion, the importance of student engagement. The ironic part, to me, is that I find I can get to easy engaging activities for my students much faster using Racket with the universe and image teachpacks than I have so far with C++ and even Python — the students get to create “fun” graphical things in week one and two with Racket. In C++ especially, I have to stick to numbers and strings, and even strings can be a little tricky to start. I end up being more “algebraic” in C++ as a result…

    * Finally, I love the transition from structs to classes in HtDP — it just seems so smooth and natural. As someone who initially learned programming in the pre-OO era, I found I understand object-oriented programming much better after seeing it approached in this way.

    Good luck with your continuing exploration of how to effectively encourage students to enter this wonderful, interesting world of solving problems using computers!

    • Hélène Martin permalink*
      August 16, 2010

      Sharon:

      I absolutely agree with your point about transitioning from structs to classes — I’m looking forward to that with my students. I think object oriented programming will be less baffling for students who have had a taste of both procedural and functional programming. I’ll report back on how it goes!

  10. Nadeem Abdul Hamid permalink
    August 14, 2010

    Hélène, you said:
    > “Can you point to an example of a course that does TS! in Python?”

    I have in fact taught HtDP using Python. It carried through fairly well. I developed a little library for students to use with standard Python, that provided things like “define-struct”, “check-expect”, etc. We even did programming “worlds” (interactive animations) using the same approach and interface as TS!. I don’t have the library posted anywhere public, nor course materials, but can send them to you if interested. What I missed in Python were things like: language levels, an IDE designed for teaching, efficient support of recursion, syntactical uniformity, etc. Nonetheless, it is doable.

    Marty, “I just don’t see the point of starting programming education in a functional language. Yes, certain tasks are simpler in functional languages. But many are not.”

    Perhaps this is arguable, but nonetheless, the HtDP curriculum doesn’t start and end with functional programming. Imperative programming is covered in the text (as mentioned already), but beyond that there is the follow-up semester teaching Java along the same principles. Students end up being able to design, write, and test OO programs much better than starting in Java from scratch, and things like assignment and loops can be explained in a way consistent with everything they’ve learned up to that point. It certainly doesn’t hurt to start with a simple model of computation and introduce complexity one step at a time.

    • Hélène Martin permalink*
      August 16, 2010

      Nadeem:

      Excited to hear that you’ve used Python to teach this material. I’ve e-mailed you to see if I can take a look at what you’ve come up with!!

  11. August 15, 2010

    The main reason (IMHO) functional programming isn’t more popular: fifty years ago Fortran and COBOL were used for large scientific and business applications (respectively) while Lisp was used for AI experiments. Accordingly, the Fortran and COBOL compilers emphasized optimization, while Lisp was traditionally interpreted, with an emphasis on simplicity and correctness. The programming community concluded (invalidly) from this that imperative programming was efficient and useful for real-world tasks, and that functional programming was inefficient and useful only for ivory-tower academic toys. Fifty years later, a majority of programmers seem to still believe that.

  12. August 15, 2010

    I just don’t see the point of starting programming education in a functional language. Yes, certain tasks are simpler in functional languages. But many are not. And the functional way of thinking just isn’t how humans picture and model computation. We think imperatively: do this, then do that. Languages that mirror that model are the most intuitive.

    The greatest contribution Fortran made was the ability to write
    X = (-B + SQRT(B*B-4*A*C))/(2*A)
    instead of
    LOAD B
    MULT B
    STORE TEMP1
    LOAD A
    MULT B
    MULTI 4
    STORE TEMP2
    LOAD TEMP1
    SUB TEMP2
    CALL SQRT
    SUB B
    DIV A
    DIVI 2

    In other words, replacing imperative programming (in the restricted realm of numeric-valued expressions) with functional programming.

  13. August 15, 2010

    I think there is significant value in making UI and other whiz-bang programming imminently available and accessible to the most beginning of students….I think the majority of students would be much more engaged if, with a couple lines of code (again, see Hackety Hack), make their own music, or make a box move across the screen. The power of creation can’t be underestimated in motivation and excitement; and I think (to bring in yet another thorny issue) this applies across genders and gender stereotypes.

    Quite true, which is why the TS! people have been putting more and more emphasis on graphics and GUI programming over the past ten years. My new textbook (which originated as a high school edition of HtDP) starts with image manipulation on page 1, starts event-driven GUI programming in chapter 5, and introduces arithmetic in chapter 7. (I teach a lot of mathophobes….) GUI programming is used throughout to motivate other programming concepts such as conditionals and structures.

    • Hélène Martin permalink*
      August 16, 2010

      Stephen–

      Thanks for mentioning your book — I’m looking forward to seeing it!

  14. Kyle Gillette permalink
    August 15, 2010

    Helene, in your cd example, it may make more sense pedagogically for the data examples (structs and lists) to immediately follow the appropriate data/structure/list definitions.

    • Hélène Martin permalink*
      August 16, 2010

      Thanks for the feedback! I haven’t taught this stuff before so I may have some questions in the next few months…

  15. Kyle Gillette permalink
    August 15, 2010

    Clint, states “… the problem with a functional-only/first approach is that it takes for granted a student’s desire to learn programming. [snip] It’s not terribly exciting no matter how you slice it…”

    I’ve been teaching for awhile and can remember when this claim could also be made of imperative/OO/procedural programming. If you take a peek at HtDP 2/ed you will see that the problems have gotten more interesting with many using images/animations. Yet, the underlying principles, such as the “design recipe” have remained intact.

  16. August 18, 2010

    What an energetic discussion! As a physics guy who is teaching AP Comp Sci to 58 kids, I really appreciate the energy! The students I have are 1/2 “gamer” types and the other 1/2 are probably college bound liberal arts students. Somehow, the population is 50/50 guys/girls. My physics classes are 70/30 guys/girls.

    Anyhow, I’ve been modifying my approach to initially learning enough code to really create working algorithms. A particular experiment is to use 10 Arduino microcontrollers equipped with light sensors, touch sensors (microswitches), motors, etc to do “robotics” projects. The Arduino is a C-looking language with a setup method and loop method, and you can add as many other methods as you want. Here is the blinking LED program for reference:

    int ledPin = 13; // LED connected to digital pin 13

    // The setup() method runs once, when the sketch starts

    void setup() {
    // initialize the digital pin as an output:
    pinMode(ledPin, OUTPUT);
    }

    // the loop() method runs over and over again,
    // as long as the Arduino has power

    void loop()
    {
    digitalWrite(ledPin, HIGH); // set the LED on
    delay(1000); // wait for a second
    digitalWrite(ledPin, LOW); // set the LED off
    delay(1000); // wait for a second
    }

    This post is probably mostly off topic, but I claim the physicist exemption! I’ll get a web page up to document the results of this experiment by Christmas time. I’m hoping this kind of instant gratification of seeing something happen in real life due to some code written will do something for the masses. I’m hoping to find time to try a few computing alternatives like Racket this year to find more options for teaching.

    I also wanted to comment on the different approach of male and female students. An electrical engineering friend of mine made an observation that girls are more likely to get frustrated with science or engineering (computers included of course) because they expect perfection more than their nerdy male counterparts. I try to sell the point to my students in physics and computer science that they HAVE to fail/mess-up to really learn such a new way of thinking. Anyhow, it seems to be a parallel between analytical science and computing.

    • Hélène Martin permalink*
      August 19, 2010

      Hi Luther,

      I also have so far had gender balanced teams and puzzle a little over the difficulty lots of programs seem to have attracting girls. I do think your comment about perfection is spot on: it’s something I have to fight in myself. For whatever reason, if things aren’t working, I usually assume it’s me but when I stop to look around, I see a bunch of males saying things like “man, this computer is stupid.” I don’t know whether that’s an innate response or something socially conditioned but for my purposes, I don’t care — I just care that it’s a real thing that happens in my classroom all the time.

      I’m looking forward to your Arduino writeup and do encourage you to look into Racket and HtDP, if only for the cultural experience! I believe it will make you a better instructor no matter what you teach.

Trackbacks and Pingbacks

  1. Maxed Out « And Yet It Moves

Leave a Reply

Note: You can use basic XHTML in your comments. Your email address will never be published.

Subscribe to this comment feed via RSS