#|           The General Outline of a Program Design Recipe
------------------------------------------------------------------------
An S-expression for the General Outline

Data Format: 
 steps   = (listof section)
 section = (list <title> <purpose> (list <question> <answer>) ...)
------------------------------------------------------------------------
|#

(
 ("Before you start \\ldots"
  "\\ldots\\ remember the basics"

  ("Do you remember the basic steps involved in program design?"
   "Every program needs 
   \\begin{enumerate}
   \\item a description of the data it consumes and produces
   \\item a statement of purpose, including examples of expected behavior
   \\item a definition or several definitions 
   \\item a test suite, relative to its contract
   \\end{enumerate}")
)

("How to Approach Program Design"

 "to understand the nature of the program" 

 ("Is the program a simple or a complex task?" 

  "If the program obviously consists of two (or more) tasks, consider
   developing two (or more) functions. For example, to compute the average
   of a bunch of numbers, we add them up, count them, and then divide the
   sum by the count.  This simple observation suggests the design of two
   auxiliary programs, one for adding up the numbers, and one for counting
   them.")

 ("Is the program a ``structural'' problem?"

  "Try a structural approach first. It works in most cases. Do not get
   stuck, however. If a structural approach doesn't work easily {\\em
   after\\/} you have worked through the template, consider
   \\begin{enumerate} 
   \\item breaking it up into smaller, more managable programs; 
   this is the most often overlooked idea!

   \\item using generative recursion; 

   \\item using an accumulator; 

   \\item using a history-sensitive approach.
   \\end{enumerate}
   ")

 ("Does Scheme provide programs that help? Have we defined programs before
   that help?"

  "To compute the average of a list of numbers, we should certainly reuse
   Scheme's length function. If we convert a list of euro amounts to
   dollars and we already have a function that converts euros to dollars,
   we reuse the latter.")

 ("If the solution is based on ``structural'' design, can it be
   solved with some existing {\\em abstract program\\/}?"

  "For example, when the task is to process each item on a list, 
   use iterators like map, for-each, or fold.")

 ("Are we done?" 
  "After testing and arguing for termination, consider abstracting 
   similar-looking programs. If the program is going to be used again, 
   or if there is even the slightest chance that it is going to be 
   changed in the future, edit the program like a paper and use abstraction 
   where it is obvious!")
)

("Choosing a Design Recipe"
 
 "to choose the appropriate design recipe"

 ("Did you consider the questions above?" "If not, do so now.")

 ("Is the program all about domain knowledge?" "If so, study the domain
   well. Even if it is all about numbers, do not forget \\aref{num}{the basic design
   steps}.")

 ("Does the program consume a novel form of data?" 
  "Remind yourself of the \\aref{structural0}{structural design steps} and their purpose. 
   Then go through the  \\aref{structural1}{question-and-answer game}
   to develop the program, step by step. Use it carefully; don't forget the 
   template step. It pays off!")

 ("Are the several data definitions with mutual references to each other?" 
  "Design the programs in parallel.")

 ("Does the program consume more than one argument?" "If all but one of them
   are atomic, stick to a plain structural design.")

 ("Does the program consume two arguments? Do both of these belong to
   classes with complex data definitions?" 
  "If so, consider a \\aref{structuralN}{multi-argument design}.")

 ("Does the problem statement suggest a process? Does the process consist
   of generating new problems, solving them, and using their solutions to
   solve the original problem?" 
  "If so, it is time to consider a design based on
   \\aref{generative}{generative recursion}. Use the 
   \\aref{generative1}{question-and-answer game} to guide the
   development.") 

 ("Does the data analysis or the finished program contain similar
   definitions?" 

  "If so, consider the recipes for abstracting 
   \\aref{data-abs}{data definitions}
   and 
   \\aref{prog-abs}{program definitions}.")

 ("Should something change that is not a part of the argument or result of
   the program?" "Consider \\aref{state}{designing for history}.")

 ("Does none of the above sound quite right?" "It may be time to consider a
  variation of one of the recipes or for the design of a whole new
  recipe. Send email to matthias@rice.edu.")
 )
)
