When selecting given names for their future child, expectant parents often study long lists of names and their derivations and pronunciations, hoping to express and guide the child's development through his or her name. One limitation of the method of scanning a list, however, is that parents sometimes don't pay enough attention to how their chosen names will sound in combination with each other and with the surname. By the time Jim and Susan Doyle send out the cards announcing the birth of their daughter, Lindsey, it's too late to point out the homonymy with ``linseed oil.'' This is depressing all around.
The exercise is to define and test a procedure full-names
that will help parents avoid such unintended clashes by listing, in full,
every possible first-name/surname and first-name/middle-name/surname
combination that can be formed from the names that the parents are actively
considering. For instance, let's suppose that the Doyles' list of possible
first names included Emily, Lindsey, Carrie, and Sarah, and the possible
middle names are Anne, Lynn, and Lucy. Your procedure should take three
arguments: the list of first names, the list of middle names, and the
surname, thus:
(full-names (list "Emily" "Lindsey" "Carrie" "Sarah")
(list "Anne" "Lynn" "Lucy")
"Doyle")
We should use strings rather than symbols in this context because of the
fact that a few surnames contain apostrophes. Scheme has no problem
dealing with the string "O'Brien", but would read
'O'Brien as two separate quoted symbols, 'O and
'Brien.
The preceding invocation of the full-names procedure should
construct and return a list that looks something like this:
("Emily Doyle"
"Lindsey Doyle"
"Carrie Doyle"
"Sarah Doyle"
"Emily Anne Doyle"
"Emily Lynn Doyle"
"Emily Lucy Doyle"
"Lindsey Anne Doyle"
"Lindsey Lynn Doyle"
"Lindsey Lucy Doyle"
"Carrie Anne Doyle"
"Carrie Lynn Doyle"
"Carrie Lucy Doyle"
"Sarah Anne Doyle"
"Sarah Lynn Doyle"
"Sarah Lucy Doyle")
In other words, the list should have as its elements every possible combination of a first name and the surname, and also every possible combination of first name, middle name, and surname. The order in which these full names are listed is not important.
You can assemble full names like these from their parts using the primitive
Scheme procedure string-append, which takes any number of
strings as arguments and lines up the characters they contain into one long
string:
> (string-append "sop" "his" "try") "sophistry" > (define spacer " ") > (string-append "alpha" spacer "beta" spacer "gamma" spacer "delta") "alpha beta gamma delta"
The problem is easier if you define several procedures to deal with various
special cases or intermediate steps, and then use calls to these procedures
in your definition of the full-names procedure. Finding the
best way to divide a complicated problem into simpler subproblems is a
large part of the creative work of the programmer.
This exercise is due at 9 a.m. on Wednesday, February 9, 2000. Here is what you should turn in:
The source code for your program, comprising the definition of the
full-names procedure and the definitions of any non-primitive
procedures that it depends on, along with your explanatory comments.
A selection of test cases -- invocations of the full-names
procedure, with various combinations of arguments, each followed by the
value returned by the procedure. It's probably most convenient to type the
invocations into the DrScheme interactions window, noting the results, and
then to save the contents of that window.
You can submit these items either by printing the files and turning in the paper copies or by sending me the files by e-mail. The on-line document ``Sending solutions by e-mail'' gives step-by-step instructions for the latter method.
This document is available on the World Wide Web as
http://www.cs.grinnell.edu/~stone/courses/scheme/exercise-1.xhtml
created January 31, 2000
last revised March 17, 2000