What If..... Strong Types

Donn Cave donn at u.washington.edu
Wed Jun 19 17:01:10 EDT 2002

Quoth Don Garrett <garrett at bgb.cc>:
| brueckd at tbye.com wrote:
|>   Worse, to make it be "good code" I'll
|> probably define -1 to be NOT_WEIGHED or something, and check against it so
|> I'm not using magic numbers. 
|    I might suggest the use of None over -1, since it has a real meaning of 
| 'not really there'. But not defining the member would have the same meaning as
| well. I do get your point here.

The statically typed languages I've been fooling around with, like Haskell,
allow for this with a type that's basically a union of whatever value, or
Nothing.  You can have a non-value, but you can't write code that treats
it as a value without resolving that ambiguity.

|> It's sometimes hard for me to model my objects this way because of having
|> had to always do it the other (completely statically defined) way, but
|> when this approach works the solutions are often quite elegant and
|> straightforward (btw - I believe that a good portion of bugs and program
|> cruftiness is related to forcing the programmer to clearly define, up
|> front, what the complete type of the object is. In many cases this forces
|> the programmer to make decisions without enough information, in others it
|> is too constricting, and in others it's just too tedious to make the
|> programmer worry about all those details, and in all cases general
|> hackiness ensues).

|    The point about programmers having to make decisions about the data before 
| they are ready is a very good one. I've certainly run into that myself, but 
| I've never heard it phrased that way, so it never clicked the way it just did.
|    Don't you find that you miss the advantages of a clear definition of what a
| class is and/or does? That's more important with group development, but even 
| when it's just me.... I need memory aids.

Some languages, again like Haskell, manage to infer types and don't
require declarations.  In this case, you might actually add declarations
later in the development process, for the kind of clarity you're talking
about - Haskell software already tends to be pretty damned abstract.
It also can help clarify the source of the problem when there's an error.

I'm not in a position to be writing big projects in Haskell, but in my
casual experiments with static type inferring languages so far, I like it.
I'm no big picture architect, any software more than the simplest thing
usually takes me several general rewrites.  Static typing catches a very
large number of errors in my program, and in fact that helps me rewrite
more rapidly, because the compiler is doing work that I would otherwise
have to do myself.  Type inference makes the compiler do a lot more of
that work, and allows me to express functions at an appropriate level
of abstraction.  Put together, the result is much stricter and more type
safe than a language like C, which allows all kinds of casting and promotion
and so forth, and yet more convenient to work with.  (Note that I'm talking
strictly about typing here, and not making any more general claim about
Haskell or other similar languages.)

The place I find dynamic typing particularly annoying is in exception
handling.  The handler receives this parameter that is of some type,
whose value may or may not be a tuple, may or may not have an 'errno'
attribute, etc.  Even qualified by exception, for example the structure
of a socket exception is somewhat variable.  And of course one would
like to avoid raising an exception from the damned exception handler.
Wouldn't it be nice if there were some way for the socket module to
export the complete type information for its exception, and for the
interpreter to check your operations on the exception value against
that type?  Like,

    except socket.error, v:
        # socket.error :: { args :: (Int, String) | (String,) }
        # phrase = v.args[1]
        # ^ oops!  Here v.args is (a, String, ...)
        #          but was declared as (Int, String) | (String,)
        phrase = v.args[-1]
        # ... ahh, that's better.
        sys.stderr.write('ouch: ' + phrase + '\n')

Maybe an interpreter flag meaning "compile this module to byte-code
and check against exported type signatures."

	Donn Cave, donn at u.washington.edu

More information about the Python-list mailing list