CSC151.02, Class 19: Documentation, Preconditions, and Postconditions Admin * Homework: Writeup 2 (tomorrow's lab). Due a week from tomorrow. * Read "Numeric Recursion" * Note that you will probably have to work on today's lab on your own * Questions on the Exam? * Extra credit: Talk on Thursday (7pm?) on Feminism and Science. Overview * Why document? * Documentation as contract * The six Ps * Verifying preconditions * Husk-and-kernel programming * Lab (maybe) Q: What is program documentation? A: Notes inserted in the program for the human reader rather than for the computer reader. Q: Why document? A: So that other people can take over your project. (Which makes it easier to fire you.) Q: Why is it useful that other people can take over your project? A: They might make it better. A: They might adapt it for another project. A: You might be an idiot and include lots of errors that have to be fixed. A: And we can fire you. A: After about six months, you've probably forgotten everything that you've written. Q: Why else? A: Because you'll fail my class if you don't. Q: What kinds of documentation might you put in a program? * Overall structure/design * Particular choices of how to do things. * Expectations about your data. * Details of what a procedure is supposed to do. Programmers often write procedures that other programmers use. * For such use to be successful ... * The user of a procedure needs to "know what it does" * The implementer of a procedure needs to know what kinds of input to expect * Cynical view: The documentation for a procedure is like a legal contract * Specify input * Specify output * More cynical views * The user of a procedure will try to break it * The implementer of a procedure will try to do the simplest possible thing that meets the contract For example, consider finding the smallest thing in a list Input, a non-empty list of numbers (n1 ... nk) Output: "the smallest thing in the list" s, s.t. s <= n1 and s <= n2 and ... s <= nk Lazy programmer might * Choose a dumb definition of "smallest" to make his life easier. * Try to avoid recursing through the whole list, so just choose something really small. Nasty user might: * Choose non-numbers (violates requirement) * Write out the names of numbers, e.g., "one", "two", "three" * Those still aren't numbers. * Repeat a number. * Carefully write output so that it guarantees that any copy is okay. * Use an empty list of numbers. * Require that the list be non-empty. * Use complex numbers Our goal as designers is to specify both sides as carefully as possible. * Characters are important ;;; Procedure: [NAME] ;;; smallest-in-list ;;; Parameters: [NAMES, TYPES] ;;; numbers, a list of numbers ;;; Purpose: [INFORMAL CONTRACT] ;;; Find the smallest value in numbers. ;;; Produces: [NAME OF OUTPUT VALUE] ;;; smallest, a number ;;; Preconditions: [REQUIREMENTS ON INPUT VALUES, WORLD, OUTPUT VALUES; FORMAL] ;;; numbers is not empty. ;;; numbers has the form (n1 n2 ... nk) ;;; numbers contains only Scheme real numbers. That is, (number? ni) and ;;; (real? i) hold for i between 1 and k. ;;; Postconditions: ;;; smallest is a member of numbers. ;;; (<= smallest ni) holds for i between 1 and k. (define smallest-in-list (lambda (numbers) ; If there's only one element, (if (null? (cdr numbers)) ; It must be the smallest element (car numbers) ; Otherwise, take the smaller of the first and the smallest ; remaining element. (min (car numbers) (smallest-in-list (cdr numbers)))))) A big debate in software design: If the client fails to meet the preconditions, what should you do? * Check if the preconditions are met and, if not, tell the client. * Easier to use: Helps diagnose errors. * Pretend that they are met and crash (or give a bad result) when they are not. * It's fun to be me[an]. * It's inefficient to have to check preconditions. What's the solution? There is no perfect solution. One possibility: Provide two versions of each procedure. * One checks the preconditions and reports errors. * One does not.