Exploring Languages
with Interpreters
and Functional Programming
– Section 6.3 –
Modular Design and Programming
(Procedural Abstraction)

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.

Modular Design and Programming

Lecture Goals

Module

Goals of Modular Design

  1. Enable programmers to understand system by focusing on one module at time (comprehensibility)

  2. Shorten development time by minimizing required communication among groups (independent development)

  3. Make system flexible by limiting number of modules affected by significant changes (changeability)

Information-Hiding Module

Secret of Square Root Module

Contracts

Contract specifies how function (e.g. within module) behaves

Precondition

Precondition:

Logical assertion that caller (client) must ensure holds before function call

Postcondition

Postcondition:

If precondition holds, then function must terminate with this logical assertion satisfied

Factorial Contracts (1)

    fact3 :: Int -> Int
    fact3 0 = 1 
    fact3 n = n * fact3 (n-1) 

Precondition: n >= 0 (to avoid infinite recursion)

Postcondition: fact n == fact(n)fact'(n) (math definition)

Same for fact1 and fact2

Factorial Contracts (2)

    fact4 :: Int -> Int 
    fact4 n 
      | n == 0 =  1 
      | n >= 1 =  n * fact4 (n-1)

Precondition: n >= 0 (to avoid failing pattern match)

Postcondition: fact4 n == fact(n)fact'(n)

Same for fact4'

Factorial Contracts (3)

    fact5 :: Int -> Int 
    fact5 n = product [1..n]

Precondition: True — “weaker” than others

Postcondition: fact5 n == if n >= 0 then fact’(n) else 1 — “stronger” than others

Square Root Contract

Precondition sqrt' x: x >= 0 — undefined for negatives

Postcondition: sqrt' x:

    (sqrt x - 0.001)^2 < (sqrt x)^2 < (sqrt x + 0.001)^2

Module Interface

Interface:

Interface for Sqrt Module

Abstract Interface for Module

Abstract interface:

Information hiding with abstract interfaces supports software reuse

Abstract Interface for Sqrt Module

Client-Supplier Relationship (1)

Design from two points of view simultaneously:

supplier
developers of the module—providers of the services
client

users of the module—users of the services (e.g. designers of other modules)

   ________________             ________________ 
  |                |           |                |
  |     Client     |===USES===>|    Supplier    |
  |________________|           |________________|

    (module user)                   (module)

Client-Supplier Relationship (2)

Supplier’s concerns:

Client-Supplier Relationship (3)

Clients’ concerns:

Client-Supplier Contract (1)

  1. Gives responsibilities of client

    Conditions under which supplier must deliver results

    When preconditions of operations satisfied

  2. Gives the responsibilities of the supplier

    Benefits supplier must deliver

    make the postconditions hold

Client-Supplier Contract (2)

Criteria for Good Interfaces (1)

Cohesion:
Fit all operations together to support single, coherent purpose
Consistency:
Provide internally consistent set of operations (naming, arguments, return, behavior) — avoid surprises!
Simplicity:
Avoid needless features
No redundancy:
Avoid offering same service in multiple ways

Criteria for Good Interfaces (2)

Atomicity:
Do not combine several operations if needed individually — each primitive, not decomposable into others
Completeness:
Include all primitive operations that make sense for abstraction
Reusability:
Make general for use beyond initial context
Robustness:
Keep interface stable even if implementation changes

Criteria for Good Interfaces (3)

Convenience:
Provide additional operations for user convenience — after careful study

Defining Haskell Modules

Key Ideas