[plt-scheme] The perfect teaching language--Is this too much to ask for?
On Sat, Jun 13, 2009 at 05:45:42PM -0400, Todd O'Bryan wrote:
> I'm starting to get really frustrated, because there are lots of
> languages that have some of what I want in a beginning language, but
> nothing that has everything. I'm beginning to worry that I'm going to
> have to design my own language--worry because I have neither the time
> nor background to do a good job of it. Here's what I'm looking for and
> I'm beginning to be afraid that the intersection of this set is empty,
> not just because no one's thought to do it, but because I'm
> convoluting language layers in an impossible way.
>
> Here are my desiderata for a language to teach introductory
> programming, through at least data structures:
>
> -------------------------
>
> 1. Language Levels
> The PLT/HtDP people are the only group I've seen who realize how
> important this is, especially with sufficiently powerful languages,
> and after seeing how useful it is for my students, I wouldn't trade
> the idea for anything. Giving students access to only the stuff they
> understand and tailoring error messages for the kinds of programs that
> they should be writing is just too useful. This, of course, leaves out
> every language but Scheme and Java as implemented in the HtDP and HtDC
> language levels.
>
> 2. Types in the Language
> Here's a sample Python interaction:
> (For the uninitiated, >>> is the Python REPL prompt, the next line is
> the result.)
>
> >>> int
> <type 'int'>
> >>> type(int)
> <type 'type'>
> >>> type(3)
> <type 'int'>
> >>> isinstance(3, int)
> True
> >>> isinstance(3, float)
> False
> >>> class Foo:
> ... pass
> ...
> >>> Foo
> <class __main__.Foo at 0xb7db262c>
> >>> x = Foo()
> >>> isinstance(x, Foo)
> True
> >>> type(isinstance)
> <type 'builtin_function_or_method'>
>
> OK, the last line is not particularly useful, but every Python value
> knows what it is, these types are real objects in the language, and
> programs can manipulate and ask questions about them.
>
> The contract is the first step of the design recipe for a very good
> reason--students need to think about what kinds of values a function
> consumes and what kind(s) of value it should produce. The problem is
> that, in HtDP, contracts are just comments, and students figure this
> out very quickly. I want types to impact students' programming,
> because a huge proportion of the mistakes my students make have to do
> with muddy thinking about types, and I think the programming
> environment should make them be explicit about what they think is
> going on and help them when they're wrong. Too many type-caused errors
> don't get caught until several layers of redirection, leaving students
> with stack traces that are, if not hard to follow, at least
> intimidating. Even if Typed Scheme were all done and perfect, it
> wouldn't provide this kind of support, mostly because that's not what
> it's designed to do.
>
> 3. Static Typing
> Yea for Python--I can play with types in the language. Boo for
> Python--I can only find typing problems once I let the program run and
> only if I happen to create a type problem. A program could be
> completely brittle in terms of types and I'd never realize it. This is
> exactly what statically-typed languages are designed to prevent, and
> what Typed Scheme seems to be doing a really good job of.
> (Unfortunately, I'm discovering just how many unfounded assumptions
> about types I make as I'm writing in Typed Scheme, but I'm sure it's
> on a par with how many unfounded assumptions I make in general.) I
> want a language that screams bloody murder if the pieces don't fit
> together right, even if some lazy student hasn't provided test cases
> that trigger a problem.
If you have static types, you can check them at compile time. And
operations like typeod(foo) will be computed at compile time.
It you have what you're asking in "types in the language", the things
you call types are actually part of the data and, here's the important
thing, they don't carry the same information.
If I have a function, say (lambda(x) x), I can think of any number of
static types for it. For example, int->int, f(int->int)->(int->int).
And with static typing, you have to specify which you mean.
But if you have so-called dynamic typing, you don't get this
fine-grained information. You just find out it's a function. If you're
elaborate, you might find it takes one argument and not two.
-- hendrik