H. Conrad Cunningham
12 September 2018
Copyright (C) 2017, 2018, H. Conrad Cunningham
Acknowledgements: I originally created these slides in Fall 2017 to accompany what is now Section 6.3, Modular Design and Programming, in the 2018 version of the textbook Exploring Languages with Interpreters and Functional Programming. This is part of Chapter 6, Procedural Abstraction.
Browser Advisory: The HTML version of this document may require use of a browser that supports the display of MathML. A good choice as of September 2018 is a recent version of Firefox from Mozilla.
Introduce modular development methods for
Describe how to use Haskell modules effectively with these methods
“a work assignment given to a programmer or group of programmers” [Parnas 1978] — software engineering concept
Also program unit defined by convention or construct — programming language concept
Ideally language feature supports software engineering method
Enable programmers to understand system by focusing on one module at time (comprehensibility)
Shorten development time by minimizing required communication among groups (independent development)
Make system flexible by limiting number of modules affected by significant changes (changeability)
Forms cohesive unit of functionality separate from other modules
Hides a design decision (its secret) from other modules
Encapsulates aspect of system likely to change (its secret)
Aspects likely to change independently become secrets of separate modules
Aspects unlikely to change become interactions (connections) among modules
Contract specifies how function (e.g. within module) behaves
Precondition
Postcondition
Invariant (in next chapter)
Logical assertion that caller (client) must ensure holds before function call
Implicitly requires type signature satisfied
Specifies valid combinations of values of arguments and global structures accessed or modified
Means called function expected to terminate with correct result
If precondition holds, then function must terminate with this logical assertion satisfied
Implicitly requires type signature satisfied
Specifies return values (and new state) in terms of arguments and state before call
Precondition: n >= 0
(to avoid infinite recursion)
Postcondition: fact n
(math definition)
Same for fact1
and fact2
Precondition: n >= 0
(to avoid failing pattern match)
Postcondition: fact4 n
Same for fact4'
Precondition: True
— “weaker” than others
Postcondition: fact5 n == if n >= 0 then
fact’(n) else 1
— “stronger” than others
Precondition sqrt' x
: x >= 0
— undefined for negatives
Postcondition: sqrt' x
:
Interface:
“set of assumptions … each programmer needs to make about the other program … to demonstrate the correctness of his own program” [Britton 1981/] (Britton, Parker, and Parnas)
includes public function signatures (name, arguments, return)
includes constraints on environment and argument values (preconditions, postconditions, invariants)
Sqrt
Modulesqrt :: Double -> Double
Precondition and postcondition defined above
Abstract interface:
does not change when one module implementation substituted for another
concentrates on module’s essential aspects and obscures incidental aspects that vary among implementations
Information hiding with abstract interfaces supports software reuse
Sqrt
ModuleSame as concrete interface in this case, not in general (see example in chapter 7)
sqrt :: Double -> Double
Precondition and postcondition defined above
Design from two points of view simultaneously:
users of the module—users of the services (e.g. designers of other modules)
________________ ________________
| | | |
| Client |===USES===>| Supplier |
|________________| |________________|
(module user) (module)
Supplier’s concerns:
efficient and reliable algorithms and data structures
convenient implementation
easy maintenance
Clients’ concerns:
accomplishing their own tasks
using supplier module without effort to understand internals
having sufficient, but not overwhelming, set of operations.
Gives responsibilities of client
Conditions under which supplier must deliver results
When preconditions of operations satisfied
Gives the responsibilities of the supplier
Benefits supplier must deliver
make the postconditions hold
Protects client by specifying how much must be done by supplier
Protects supplier by specifying how little acceptable to client
Tradeoff conflicts among criteria: completeness vs. simplicity, reusability vs. simplicity, convenience vs. { consistency, simplicity, no redundancy, atomicity}
Tradeoff criteria against efficiency and functionality
Define in a separate file — enables separate compilation, reuse
Export public features (functions and data types)
Do not export private features (functions and data types)
Use good software engineering design
Module as unit of work in software engineering
information hiding
secret
abstract interface
contract
Client-supplier relationship and contract
Criteria for good interfaces
Haskell module features