Teaching programming could be made easier

June 17, 2014 at 8:55 am 12 comments

Gas station without pump’s post on Garth’s complaint “Teaching programming is not getting easier” intrigued me.  Garth does a good job of pulling together a lot of the themes of what makes teaching CS hard today.  I think that we can improve the situation.  I’m particularly interested in learning how to scaffold the development of programming knowledge, and we have to find ways to create professional communities of CS teachers.  There are techniques to share (worked examples, peer instruction, pair programming, Parson’s problems, audio tours), and we’re clearly not doing a good job of it yet.

In programming there are 4 homework problems over the period of a week, none of which are “easy”, and all require some problem solving and thinking.  There is somewhat of an incremental progression to the problems but that step from written problem to code is always a big one.  It is somewhat similar to solving word problems in math, every student’s favorite task.  For programming there are no colleagues available that have as much or more experience to pull teaching ideas from, if there are any other programming teachers at all.  There are no pedagogical resources anywhere online for teaching strategies.  After watching a number (3) of programming teachers teach it seems the teaching strategy is pretty consistent; show and tell and hope.

via Teaching programming is not getting easier. | Garth’s CS Education Blog.

Entry filed under: Uncategorized. Tags: , , .

Guest Post from Shriram Krishnamurthi: Growing respect for Research around Computational Learning and Thinking Let’s do the math: Does it make sense to fill a pipeline of CS workers from 3rd grade?

12 Comments Add your own

  • 1. Bonnie  |  June 17, 2014 at 9:16 am

    We need to be careful about scaffolding. A lot of instructors use too much and let it go on too long. If students have spent most of their time filling in small missing bits in code given to them, they do not learn how to start from scratch, which is pretty essential. Worked examples are great if the instructor focuses on the design process, but that is hard to do, and too often students take worked examples as something to memorize. I have tried clicker questions in class, and find they are great for keeping students awake, but do not help students at all when they are faced with writing their own programs.

    Honestly, I think learning to program is ultimately a lot like learning to write. The key is practice and feedback, lots of it. I think students need to be spending far more time writing programs, with extensive oversight and feedback. Perhaps they should also be spending time actively reading and analyzing programs too. But I am more and more thinking that lectures are actively detrimental to the process of learning to program, because a student listening to a lecture isn’t practicing.

  • 2. Bri Morrison  |  June 17, 2014 at 10:27 am

    I think the key is that it requires different amounts of scaffolding for different audiences, and at different times. If you are trying to educate students that will become software developers, then filling in missing blanks may not be that helpful in the long run. But having them write functions/procedures/methods that meet precise APIs and specifications is perfect. On the other hand, if you’re trying to educate non-CS majors, or those we’re just trying to expose to computing solutions, then filling in the missing blanks is a great way to go.

    Many of the current “worked examples” in intro CS suffer from “Here’s the problem, here’s the solution”. This is not an appropriate worked example. Instead they should show the design process (here are the pieces of data that are needed to solve the problem, here’s the output we’re required to produce, etc.) rather than just the finished solution. They also need to expose some of the “tricks” of the solution (oh, what happens if there aren’t any days with rain…we can’t divide by 0). Some would consider this TDD, which could also be incorporated into worked examples. This is what I hope to solve (in part) in my dissertation work.

    • 3. Mark Guzdial  |  June 17, 2014 at 11:11 am

      Briana, did Peter Pirolli’s worked examples show process? I thought that they were static examples.

      • 4. Bri Morrison  |  June 18, 2014 at 9:38 am

        In Pirolli 1991, he evaluated teaching structure of solutions with the process of design of the solutions. The explanation of structure was found to reduce training time when compared with the explanation of process. HOWEVER, if you look at his definition of teaching “process” it really is just tracing recursive functions. It’s not the overall “how would we design this function”.

        In Recker & Pirolli 1995 their system included a “design” feature which would allow students to examine the design of the recursive function, but they don’t report on how often the subjects used that button or if it affected the results. They also never give an example of what was included in the “design” explanations.

    • 5. Bonnie  |  June 17, 2014 at 1:36 pm

      Writing functions and procedures that meet a precise specification is a necessary but not sufficient skill for a would-be software developer who wants to be employed. Real life software development is unfortunately a lot messier and complex than that.

      Since 95% of my students are CS majors who dream of a software dev job when they finish, I really have not much opinion on what non-CS majors might need. I would think, though, that problem solving from scratch kind of defines the core of what computer science is about, no? If they don’t learn to do that, have they really learned anything about our field?

      I do teach one course where we use AppInventor with non-majors to teach a little about UI design. AppInventor, of course, is very heavily scaffolded. I have no illusions that my students have learned anything important about computer science when they finish, though I hope they know a little more about human factors when designing a UI.

      • 6. KDecker  |  June 17, 2014 at 2:49 pm

        I wonder if you are using the word “scaffold” in the same sense as “template” in the PBD design recipe. Most people talk about the Process dimension of the Design Recipe (including the writing down good examples before coding step from TDD @Briana), but not always about the data design dimension, including the development of templates (skeleton function bodies to fill in later) for each new class of data design.

        In that sense, Program By Design is teaching students to build their own scaffolding (in the template/skeleton sense) when building a system from scratch (as well as how to fill in the blanks of that template by, for example, careful selection of unit tests, and when to just abandon the template). Sometimes people ask for the IDE to support this directly (why not just build a fill-in-the-blanks GUI for each function based on its type signature?) but the answer is exactly that students need to internalize that process, not have the IDE do it for them.

        On the other hand, I interpreted Mark’s use of “scaffolding” more at the concept level (I can’t teach someone about (or motivate) structures/classes/”compound” data types until they are good with functions that consume/produce a few different “atomic”/primitive/builtin data types). Another example from HTDP2e is “mixtures”/itemizations/type unions lead to lists, trees, etc. because they are themselves just itemizations with one little twist—self reference.

        • 7. Mark Guzdial  |  June 17, 2014 at 3:25 pm

          Templates can be a kind of scaffolding. I mean scaffolding like described here.

          • 8. KDecker  |  June 17, 2014 at 4:21 pm

            Ah, got it. Also the “fading” part of that paper reminded me you’ve also used the DrRacket *SL language levels as an example of faded scaffolding, where the IDE limits fewer and fewer language features (and reports more complex error messages) as students progress. The http://www.wescheme.org browser IDE for the Bootstrap curriculum (for middle school kids) does “coaching” for each part of the (simplified) design recipe used there.

      • 9. Bri Morrison  |  June 18, 2014 at 9:44 am

        I agree that writing functions and procedures that meet a precise specification is a necessary but not sufficient skill for a would-be software developer who wants to be employed. But I’m also talking about _introductory_ programming. I don’t think at the end of a first course in programming (for either future software developers or non-majors) that they need to be able write code from a “blank page”. For the future software developers that can be in a second or third or later course. (Honestly, I worked at IBM for 8 years and never once started development on a blank page…everything had to fit into the existing system. Even the classes we wrote had a pre-defined template to start from to ensure standards.)

        For the non-majors, I want them comfortable with what the computer can do. If they fall back to the old COBOL adage “copy and adapt” I’m great with it. If they have one program that they can change and change again to accomplish what they want I’ve succeeded. No blank page syndrome.

  • 10. Kathi Fisler  |  June 19, 2014 at 7:05 am

    I note the contrast between Bonnie’s “problem solving from scratch” with Briana’s “write code from a ‘blank page'”: when the goal of intro is to teach coding, these two get conflated. We all know that there are rich problem solving skills that (should!) precede writing code. I think we often scale down the computational problems in CS1 (to make the coding manageable) so far that the problem solving skills become much too subtle for intro students to appreciate.

    I want to see students coming out of intro able to look at a problem and think through some of its computational requirements: what data is involved, what tasks are involved, how should a solution to this problem behave, etc. I see these as the “transferable” skills for non-majors. Coding is a medium for writing down this understanding in a precise way. I agree it’s a highly unforgiving medium (that’s a big part of our challenge). A student can pass my CS1 by showing the ability to articulate data, produce test cases, and produce Program by Design code skeletons (even if they can’t fill in those skeletons to get to working code). Still working on the task decomposition part.

    Overall, many intro courses/approaches/tools are still too driven by the code, which I suspect contributes to our problems.


    • 11. Mark Guzdial  |  June 19, 2014 at 12:02 pm

      I need to work on a declaration of beliefs about computing education.

      We hold these truths to be…supported by cognitive and situative learning theory and empirical evidence.

      1. Students take more than one semester to learn to code. Trying to teach enough of a language to be a successful developer in a single semester means that less is learned and it will take longer to reach some level of literacy.
      2. Students learn to design when they want to build something. Students don’t learn design skills about software until they learn enough programming to want to build things. Any “design skills” they learn without programming will be brittle (see last belief).
      3. No one learns general problem solving skills by learning to program. It is possible to teach general problem solving skills through programming, but then, you will cover even less programming. (See belief #1.)
      4. Students do learn to solve computational problems when programming. But we don’t have evidence yet that most people can apply their computational problem solving skills to everyday problems (i.e., computational thinking may not exist except for really smart computer scientists). Transfer is hard in all directions.
      5. Students who enter a computer science course want to learn to code. Ignoring code is ignoring their desire to join a community of practice.
      6. Students do not enter our classes as blank slates. There is no “first.” They have conceptions about computing, about programming, and about why they’re in this class. Their conceptions may be ill-formed or “alternate” or even wrong, but if you ignore those conceptions, you disrespect the students and they will not learn from you. They will have “brittle knowledge” — they might pass a test, but they will consider the knowledge irrelevant and unusable.
      • 12. Kathi Fisler  |  June 19, 2014 at 3:32 pm

        Thanks for sharing this — several good reminders within this list.

        To clarify, I certainly didn’t mean my comment to suggest that we shouldn’t be teaching coding from the start. My concern is with “coding for the sake of coding”, rather than “coding with an eye towards broader and articulated pedagogic goals”. I agree we have to put students in situations where they appreciate the need for design and the other tools we might teach them. Part of our challenge is to design experiences that lead students into this appreciation while (at first) letting them think they are “just” learning how to code … and without letting them cement habits before they become too hard to undo later.



Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Trackback this post  |  Subscribe to the comments via RSS Feed

Enter your email address to follow this blog and receive notifications of new posts by email.

Join 10,185 other subscribers


Recent Posts

Blog Stats

  • 2,060,306 hits
June 2014

CS Teaching Tips

%d bloggers like this: