cs3110 / textbook

The CS 3110 Textbook, "OCaml Programming: Correct + Efficient + Beautiful"
Other
740 stars 134 forks source link

Clarify OUnit2 assert_raises. #122

Closed justhsu closed 1 year ago

justhsu commented 1 year ago

Previous explanation wasn't quite right: leaving the function out doesn't lead to an exception, it leads to a type error.

clarksmr commented 1 year ago

The previous explanation was stated in an overly strong way, but it actually corresponds to a situation I see frequently when helping students debug code. For example, leaving the thunk out here leads to an exception, not a type error:

# OUnit2.assert_raises (Failure "") (List.hd []);;
Exception: Failure "hd".

That's because the thunk argument to assert_raises has type 'a, so it can be instantiated at unit -> 'b.

I admit that won't always happen:

OUnit2.assert_raises (Failure "") (1 / 0);;
Error: This expression has type int but an expression was expected of type
         unit -> 'a
       Hint: Did you forget to wrap the expression using `fun () ->'?

But I'd really like to leave the old tip in the book because of how often I've had to explain this.

Perhaps it could be weakened. It used to say: "If you do, the OUnit test case will fail..." That could be changed to: "If you do, the OUnit test case might fail..."

UPDATE: Or, "If you do, and the program happens to type check, then the OUnit test case will fail...".

justhsu commented 1 year ago

Ah, I see... this is because [] and List.hd [] have polymorphic type, I hadn't considered that. I was actually looking at this part because a student asked me what the tip meant, and I couldn't understand on the spot. How about we move the new tip material that I added into the main text, and restore the old tip as a tip? It seems like kind of an unusual interaction of types, which is still like a common pitfall.

clarksmr commented 1 year ago

Sure, that could work. Would be nice to add a forward reference for "thunk", since that comes up in a later chapter.