Typing system vs. Java

Donn Cave donn at u.washington.edu
Wed Aug 1 18:49:12 EDT 2001


Quoth <brueckd at tbye.com>:
...
| Right. My assertion is that this causes more problems than it solves
| because you seldom know your "intent" in that much detail, much less your
| future intent. Seems like ultra strict type checking might work well in
| cases where you have very precise requirements and once built, your
| software won't be changing any time soon (a la space shuttle software).
| Most programs don't fall into that category.

OK, another example, happy to be able to accommodate your request.
>From today's comp.lang.python, someone asks, how come my program
doesn't work?  His case seems a ways away from space station control.

His point of failure looks like this,

    arg = parse(data)
    if arg[0] == 'privmsg':
      ...
    elif arg[0] == 'ping':
      ...

And the run time error is a TypeError: unsubscriptable object.
He's baffled enough by this to post to comp.lang.python instead
of figure it out himself.

Here's his code:
 -----
    def parse(self, data):
        if string.find(string.lower(data), 'privmsg') >= 0:
            garbage,middle,msg = string.split(data,':')
            sender,cmd,rcpt = string.split(middle)
            arg=[string.lower(cmd),sender,rcpt,msg]
            return arg
        elif string.find(string.lower(data), 'ping') >= 0:
             sender,cmd,pong = string.split(data[1:])
             arg=[string.lower(cmd),sender,pong]
             return arg
 -----

And similar in OCaml:
 -----
let ulfind str data =
  try
    let n = Str.search_forward (Str.regexp_case_fold str) data 0 in
      true
  with Not_found ->
    false

let parse data =
  if ulfind "privmsg" data then
    let wl = Str.split (Str.regexp ":") data in
      match wl with
        garbage::middle::msg::[] ->
          let wl = Str.split (Str.regexp "[ \t]+") middle in
            begin
            match wl with
              sender::cmd::rcpt::[] ->
                Some [(String.lowercase cmd); sender; rcpt; msg]
            | _ -> None
            end
      | _ -> None
  else if ulfind "ping" data then
    let wl = Str.split (Str.regexp "[ \t]+") (Str.string_after data 1) in
      match wl with
        sender::cmd::pong::[] ->
          Some [(String.lowercase cmd); sender; pong]
      | _ -> None
  else
    None

let main () =
  let data = begin print_string "parse me: "; read_line () end in
    let argl = parse data in
      match argl with
        Some [] -> Printf.printf "Empty\n"
      | None -> Printf.printf "unexpected input \"%s\"\n" data
      | Some (cmd::argtl) -> Printf.printf "Command \"%s\"\n" cmd
;;
main ()
 -----

It's probably a suboptimal expression of the idea, as I am very
new to OCaml.  OCaml's type checking catches his error - if I
leave the last "else" out of the parse function, the compiler
notices the void return, in a context where void is not accounted
for.

I used a None/Some option for the return just to show how that
would work, but that one bit of explicit typing isn't really
necessary, an empty list or an exception would have worked fine.
That's a complete, working program.

Hope you find this useful.

	Donn Cave, donn at u.washington.edu



More information about the Python-list mailing list