Python from Wise Guy's Viewpoint

Dirk Thierbach dthierbach at gmx.de
Sun Oct 26 12:03:18 EST 2003


Brian McNamara! <gt5163b at prism.gatech.edu> wrote:
> Pascal Costanza <costanza at web.de> once said:
>>Brian McNamara! wrote:

> But I suppose you really want this example

>>>(defun f (x)
>>>  (unless (< x 200)
>>>    (cerror "Type another number"
>>>            "You have typed a wrong number")
>>>    (f (read)))
>>>  (* x 2))

> statically typed, huh? 

After quite some time, I think I have finally figured out what Pascal
meant with

>> The type system might test too many cases.

I have the impression that he is confusing dynamic type errors and
runtime errors. In Lisp and Smalltalk they are more or less the same,
and since dynamic type errors map to static type errors, he may think
by analogy that other runtime errors must necessarily also map to
compile errors somehow involved with static typing. Of course this is
nonsense; those two are completely different things. The "too many
cases" referred to some cases of runtime errors he didn't want to be
checked at compile time. As you cannot get "too many test cases" by
type annotations static typing (which was the context where he made
this comment), like you cannot get "too many test cases" by writing too
many of them by hand, I really had a hard time figuring this out.

To sum it up: Unit tests (some, not all!) correspond to type
annotations, static type checking is the same as running the test
suite, dynamic types correspond to data types, runtime errors
correspond to runtime errors (surprise :-).

> Ok, I'll try.  If I come up short, I expect it's because I'm fluent
> in neither Haskell nor Lisp, not because it can't be done.

You don't really need runtime errors for the above example,
but here's a similar version to yours that throws an error in
'cerror' to return to the toplevel. No Maybe types.

cerror :: String -> String -> IO a -> IO a
cerror optmsg errmsg cont = do
  print errmsg 
  print ("1: " ++ optmsg)
  print ("2: Fail")
  s <- getLine
  x <- readIO s
  let choice 1 = cont
      choice 2 = ioError (userError errmsg)
  choice x
  
f :: Integer -> IO (Integer)
f x =
  if (x < 200) 
    then return (x * 2)
    else cerror 
      "Type another number"
      "You have typed a wrong number" 
      (getLine >>= readIO >>= f)

>> I don't want an "approximation of cerror". I want cerror!

And you got it, exactly as you wanted. Perfectly typeable.
(Please don't say now "but I want to use the Lisp code, and
it should run exactly as it is, without any changes in syntax").
You could even assign the very same types in Lisp if any of the 
extensions of Lisp support that. (I didn't try.)

- Dirk




More information about the Python-list mailing list