Get the students to propose each element before it is taught.
There seems to be two major approaches to CS1 courses.
CS1: and introductory course in computer science;
typically a programming course.
One side teaches the programming language,
the other teaches the programming practice.
In the former, you hear things like
“A for
loop can be re-written as a while
loop”;
there is usually an explicit discussion of scope and stack frames
and the difference between creating and constructing an object, etc.
In the latter you see intricate topics like recursion
being taught with inexact words like
“And then we do it again, but with 3 instead of 4”;
programming concepts are assumed in explanations
instead of being explicitly identified,
and are learned intuitively.
The difference is similar to that
in deconstructive versus immersive foreign language classes.
I usually think dichotomies are bunk. Either-or questions are too simple to contain much meaning. I think this dichotomy is more harmful than meaningful. I could talk about the unification of the two, but instead I’ll address a third possibility.
One advantage programming languages have over natural languages is they are designed. Which means they make sense (to somebody). It is my postulate that students will design them anew if they are given a little guidance.
Introduce some language form for string input and output. Feel free to call it “magic” even if you favor deconstruction. Assign as homework a 1-page proposal of how to extend the language to do addition.
Review some of the student proposals for addition in class, probably by describing groups of similar proposals. Talk about some pros and cons of each design (with student input), then have the students vote on which one they like most.
Depending on what they vote for and how willing the instructor is to extend the course language, either help them define all aspects of their voted-for element or show them the one the designers of the chosen language selected. Talk about any ideas, such as type, assignment, stringification, etc., that come naturally from this discussion (if none do, they will later).
Assign the students to proposes extensions for the other core arithmetic operators. Make sure they have to think about precedence and decimal values. Again, discuss their proposals and talk about any ideas that come naturally from that discussion.
Tell the students that inside the computer it is easier to a fixed amount of information for any given thing, and that integers are easier to handle than decimals. Ask them to propose what should happen with integer division, integer overflow, decimal overflow, and decimal underflow.
Discuss their answers. Talk about the idea of type, and where it is stored. If x ÷ y sometimes gives an integer and sometimes a decimal than which one it is needs to be stored in memory; if it always gives the same thing, though, it can be inferred from context and not stored at all.
Then go back to strings and talk about how this applies to them too. In a statically typed language, talk about the type of a variable. Ask the students to come up with what ought to happen when you divide a number and a string.
With each new construct from here on out, follow the following structure:
Presumably, each such exercise would be followed up with reinforcing examples and homework assignments.
What I am proposing can be generalized as f : L → L, where L is the set of lesson plans. The function f identifies the novel concepts in the input lesson and creates an example problem using each one. Those example problems are assigned prior to the new lesson, the results are discussed in class, and that discussion is used to guide the presentation of the novel concepts.
For example, if the new concept was sending objects messages the example problem might be “Someone wrote a bunch of code that handles keyboard input and named it a ‘Scanner’; how should we be able to get at the things a ‘Scanner’ knows?”
Because it is the current CS AP test topic, many schools use Java as their introductory language. Java’s a pretty bad language for the first few weeks because it has so much boilerplate code.
I’d start by creating a program Bootstrap.java
which has public static methods input
wrapping the nextLine
method
of a java.util.Scanner
reading java.lang.System.in
and display
wrapping the println
method of java.lang.System.out
.
I’d call necessary boilerplate “magic”
and promise to explain it all at a later date:
public class ProgramName extends Bootstrap {
public static void main( String[] args ) {
// code goes here
}
}
The first programs I’d show would be things like
display( "Hi" );
and print( input() );
and display( "Type something:" );
I’d then ask them how they’d change the language
to allow them to display the line they type twice in a row,
first showing them that
display( "You typed " + input() );display( "Type something:" );
does not work.
display( "Once: " + input() );
display( "Twice: " + input() );
I’d use the resulting proposals to introduce the idea of variables as well as the word “String”, being the Oxford English’s definition II.15.c “a sequence of symbols or linguistic elements in a definite order”. I’d discuss having multiple variables, re-assigning variables, assigning concatenations to variables, and possibly also the swap operation.
Next I’d introduce static methods
since the earlier the big ideas appear
the less time students have to get used to them not existing.
I’d show a program with a lot of bits of the form
display( somePrompt );
and ask them to come up with a way to make this all one statment,
like
someVar = input();someVar = prompt( someText );
.
I’d also ask for a few others, like
someVar = twolines( prompt );
to give them a feel for what should be possible.
someVar = polite( request, acknowledge );
echo();
The discussion of their static method proposals
will lead to more “magic”,
such as the meaning of the keyword static
itself.
To kill magic quickly
I’d next move into an example with lots of people
each with a surname and a given name
and ask for some way to have a Person
, like I have a String
.
We’d discuss in class some of the things I’d want from a Person
(to get/set individual names, get “last, first” and “first last” full names, etc)
and ask the students to come up with proposals
about how to make Persons addable to our language.
I’d then lecture on classes.
I’d talk about static and non-static methods
(getName
versus getSpecies
),
constructors, overloading,
the toString
method, etc.
I’d show System.out and System.in and Scanner
and get rid of all the magic.
Then I’d proceed as outlined earlier,
asking them to propose a technique for handling addition,
other arithmetic operators,
conditional computation,
and repetition.
Along the way I’d mention other classes and their methods.
Once int
s exist I’d talk about most of the String
methods.
I’d not introduce boolean
until I asked them to think about conditional computation.
My proposal for bootstrapping Java has one shortcoming: it is not aimed at interesting example programs early on in the semester. I implicitly assume that students will find programming interesting in its own right and not just as a means to an end. Personally, I think every topic ought to be taught as desirable in its own right, but that’s another matter. This assumption seems to run counter to the results of CS education studies. Adding in graphics early on and fleshing out some more interesting example programs could help.
Looking for comments…