[plt-scheme] The perfect teaching language--Is this too much to ask for?

From: Todd O'Bryan (toddobryan at gmail.com)
Date: Sun Jun 14 10:37:30 EDT 2009

On Sun, Jun 14, 2009 at 9:26 AM, Marco Morazan<morazanm at gmail.com> wrote:
>
> Hmmm.....I am sorry to say that I do not find this yelling for types
> in a beginner's course. As a dedicated and caring instructor, I
> suggest that you accept these "growing pains" students must go
> through. Getting types right can be a tricky proposition for those
> that are taking their first steps in programming. Let's think about
> the whole process students go through to produce a working function.
> There is that rather "giant" step of designing the function correctly
> (giant eventhough HtDP makes it as easy as it can be) and there is the
> other "giant" step of getting the syntax right. Do we want to pile on
> top of these getting the types right? I think students are better
> served without static types at the beginning. Let them run into
> dynamic type errors and think through their design which is where the
> focus should be.

See, I think that the problems that students have with design are
because they don't pay enough attention to the types. The example I
cited of returning "" instead of empty is quite common. Part of
getting the design right is figuring out how the pieces *have* to fit
together because of the types that they have. I think this is why
writing the contract is the first step in the design recipe. If you
don't know what kinds of things your function is supposed to consume
and produce, you have no hope of getting the function right. And if
you get the types wrong and program to the contract, you're guaranteed
to get a function that won't work.

> They can learn a lot from such errors and growing
> pains. One of the valuable lessons may be that errors are usually in
> the design. One of the bad habits they may not pick up is to simply
> try to get a type "right" that allows the program to run. I have seen
> my fair share of students that do not dare to change the types in
> their programs, because "the program runs with them." Forget the fact
> that they really have the design wrong and, therefore, the wrong
> types.

This is a valid point, but I much more often see students who have
test cases that don't match contracts and refuse to change the test
cases that work.

> If the above is not convincing, how about getting beginning students
> to write typed programs for abstract functions that manipulate
> compound data structures? How about getting the types right for
> programs that use encapsulation? All of the sudden, types get in the
> way of undertsanding fundamental concepts. Be careful for what you
> wish for!

I disagree completely with this. When we get to abstract list
functions, I think it's the types that keep students sane. To use
build-list, map, filter, and the folds correctly, I think students
*have* to consciously think about the types. Now, whether they have to
get the fully abstracted types with type variables correct is
something I'm not too insistent about, but I don't have them write
lots of functions that require those. Mostly I want them to use the
abstract list functions to solve particular problems in terser ways.

On the other hand, correctly figuring out the types of abstract list
functions is almost mechanical. After we go through the examples in
Part IV, we develop the following "algorithm" for abstraction:

If you notice a similarity between structures, abstract a more general form:
 a. For everything that is the same, keep it the same.
 b. For everything that is different, introduce a variable.

You can just as easily apply (b) to types in contracts as to values
within functions. When we abstract fold from sum and product, we get

;; fold:(number number -> number) number (listof number) -> number
(define (fold op val-for-empty alon)
  (cond
    [(empty? alon) val-for-empty]
    [(cons? alon) (op (first alon) (fold op val-for-empty (rest alon)))]))

I then push this, asking students if this function only works for
numbers. We figure out what the type would be if we didn't limit
ourselves to numbers, and we notice that the first and second
arguments to the op don't have to be the same type, but that there's a
dependency relationship between the types of val-for-empty and the
return type.

> Just one more note, do you really like Python as a language for
> beginners? Not only is it typed, but it has objects! Objects without
> understanding abstraction is a recipe for developing poor programming
> habits IMHO. I fully expect to get some noses out of joint with this
> last comment, but it is meant to stimulate thought not controversy.

Yes and no. I actually switch to Python with a few weeks left in the
year and re-visit many of the same concepts we did in Scheme. Python
doesn't have static type-checking, so it's no more useful than Scheme
at getting students to be less muddle-headed about their contracts,
but the syntax sets them up for Java, which I have to teach the next
year because of AP concerns.

Your concern about introducing OO is a valid one, and it's one reason
that I love to do Python before Java. I have a series of assignments
where I introduce classes as equivalent to Scheme structures--boxes
that can hold a number of values with labels. We then write a bunch of
functions on these classes--functions, not methods.

The next step is to move the functions inside the classes.

class Foo:
     pass

def fun_for_foo(foo, arg1, arg2):
     blah

becomes

class Foo:
     def method(self, arg1, arg2):
          blah

Here, Python's explicitness in requiring "self" for the first argument
to a method lets me point out the equivalence of

fun_for_foo(foo, arg1, arg2) and
foo.method(arg1, arg2)

The last assignment involves finding similarities in methods across
classes and then abstracting these out into a super-class.

I find that hitting all the same concepts in another
language--conditionals, function definitions, lists, strings,
recursion, abstraction--drives home to students that these are general
concepts that all languages share. They just express them in different
ways. I also use Python to introduce mutation and looping constructs,
since the AP committee seems to be greatly enamored of those things
and it helps if my students have seen them before I have to hit them
hard in the AP course.

So, no, I wouldn't do Python (in its current form) as a student's
first language. But if it were given the kind of treatment that HtDP
has applied to Scheme, so that the language was tailored to what
students should be able to do at a particular point, I don't think it
would be awful. Yes, the syntax is more complicated than Scheme, but
the fact that indentation is meaningful means that getting the syntax
right also forces students to write code that's relatively easy to
read. And the syntax is terser and more regular than Java, which is a
huge plus.

Todd


Posted on the users mailing list.