CISC-280 Program Development Techniques

Problem Set 1: Introduction

Due: Thursday, September 18, 2008

Reading:

The purpose of the exercises below is to familiarize you with the basics of Scheme language and interpreter. Spending a little time on simple mechanics now will save you a great deal of time over the rest of the semester.

1. Before Using the Computer

Read through section 1.1. Then, predict what the interpreter will print in response to evaluation of each of the following expressions. Assume that the sequence is evaluated in the order in which it is presented here.

(- 8 9)

(> 3.7 4.4)

(- (if (> 3 4) 7 10) (/ 16 10))

(define b 13)

13

b

>

(define (square x) (* x x))

(square 13)

(square b)

(square (square (/ b 1.3)))

(define a b)

(= a b)

(if (= (* b a) (square 13))
(< a b)
(- a b))

(cond ((>= a 2) b)
((< (square b) (square a)) (/ 1 0))
(else (abs (- (square a) b))))

2. Getting started with DrScheme

You should either download DrScheme and set it up on your home pc, or read the instructions on the website (created by the TA) for running scheme on the composers.

In the DrScheme environment, you will use a text-editing system which incorporates an editor closely resembling the widely used editor Emacs. Even if you are already familiar with Emacs, you should take some time now to look at the simple documentation. Clicking on the ``Help'' button will bring this up (under ``Help Desk''). Glance over the Help Desk, sections:

At least skim these topics so you know what's there. You'll need to gain reasonable facility with the editor in order to complete the exercises below. Note that the Help Window is actually a web browser. Also remember that the entire DrScheme environment is written in Scheme itself.

Evaluating expressions

After you have learned something about DrScheme, go to the Scheme interactions buffer. (If you don't know how to do this, go back and learn more about DrScheme.) As with any buffer, you can type Scheme expressions, or any other text into this buffer. What distinguishes the Scheme buffer from other buffers is the fact that underlying this buffer is a Scheme evaluator, which you can ask to evaluate expressions, as explained in class.

Type in and evaluate (one by one) the expressions from section 1 of this assignment to see how well you predicted what the system would print.

Observe that some of the examples printed above in section 1 are indented and displayed over several lines for readability. An expression may be typed on a single line or on several lines; the Scheme interpreter ignores redundant spaces and carriage returns. It is to your advantage to format your work so that you (and others) can read it easily. It is also helpful in detecting errors introduced by incorrectly placed parentheses. For example the two expressions

 (* 5 (- 2 (/ 4 2)) (/ 8 3))

look deceptively similar but have different values. Properly indented, however, the difference is obvious.

(* 5 
(- 2
(/ 4 2)
(/ 8 3)))

(* 5
(- 2
(/ 4 2))
(/ 8 3))

DrScheme provides several commands that ``pretty-print'' your code, e.g., indents lines to reflect the inherent structure of the Scheme expressions. Typing RETURN will indent the next line correctly, and TAB will fix the indentation of the current line. Homeworks will be graded for clarity, incuding proper indentation!

Creating a file

Since the Scheme interaction buffer will chronologically list all the expressions you evaluate, and since you will generally have to try more than one version of the same procedure as part of the coding and debugging process, it is usually better to keep your procedure definitions in a separate editing buffer, rather than to work only in the Scheme buffer. You can save this other buffer in a file on your disk so you can split your work over more than one session.

The basic idea is that you type your programs into the editor buffer, and then use the Check Syntax button to see if they have correct syntax. The Check Syntax button will also highlight your code with colors indicating which words are function names (by virtue of their position), which are variable names, etc. It will also create a variable flow overlay that shows where variable values come from in a function, and where they are going to. This happens whenever you pass your mouse over the variable name. You don't have to click. NOTE: the feedback that you get depends on what you have the language level set to.

After Check Syntax, you would then click on Run. This loads the editing buffer into the Scheme Interaction buffer. You can then start running your program by typing into the Interaction buffer.

To practice these ideas, go to the empty editing buffer. In this buffer, create a definition for a simple procedure, by typing in the following (verbatim):

Now, click on Check Syntax.

If you actually typed in the definition exactly as printed above, you should see a bright red Check Syntax Error Message  saying ``*x'' (with no space) has a problem. This is not a syntax error, but DrScheme is warning you that ``*x'' is currently undefined (it's a perfectly valid identifier name). Let's see what happens when we try to run this code. Click on Run to load this incorrect definition into the Scheme Interpreter buffer. You will see that you get a red error message here too.  Ignore it and type ``(square 4)'' and return. The interpreter prints ``reference to an identifier before its definition: square''. At this point we see that the definition of square did not work because of the problem with *x.

Edit the definition to insert a space between * and x. Re-Syntax-Check and Re-run the definition.  You will notice that the scheme window prints a message that says: This program should be tested. Ignore this for a moment, and try evaluating (square 4) again. Save this working definition in a file called ``hw1-answers.scm''. You can put all of your later answers in this file to print out and turn in.

Now, let's talk about the error message.  The scheme language version you are using tries to instill good programming practice by making you think about testing BEFORE you actually write a function (program) like square. So it provides a function called check-expect that takes two arguments: a function call to be evaluated and the expected value of that function call.  Add to your file the following line:

(check-expect (square 4) 16)

and hit Run. This time you should receive a message that says:  All tests passed!

Printing a File

You can print either the definitions buffer or the interactions buffer, under the FILE menu. 

Stepped Evaluation: Using The Foot

Copy the file hw1-0.scm onto your computer (or composers account) and load it into scheme. This simply contains several of the lines you evaluated earlier. After doing a Check-Syntax, press the Step button to bring up The Foot, Dr.Scheme's evaluation stepper. The Foot will show exactly how Dr.Scheme evaluates each line of code. Since the first couple of  lines are Scheme define's, these do not evaluate to anything (define is a special form, remember??!!). The other lines can be evaluated one expression at a time by pressing the Step > button. Make sure that you understand exactly what is happening at each point in the evaluation!!

Another Debugging example

While you work, you will often need to debug programs.

Copy and load the code for this problem set from hw1-1.scm. This will load definitions of the following three procedures p1, p2, and p3:

;;; This is the code for ps1.

(define (p1 x y)
(+ (p2 x y) (p3 x y)))

(define (p2 z w)
(* z w))

(define (p3 a b)
(+ (p2 a) (p2 b)))

Click on Check Syntax. Check out the flow of information display---move your cursor over, for example, the various occurrences of p2 in the code. Click on Execute to load the code into the interpreter.

In the Scheme buffer, evaluate the expression (p1 1 2). This should signal an error, with the message:

 hw1-1.scm:10:7: p2: this procedure expects 2 arguments, here it is provided 1 argument in: #f
You can fix the error and re-execute the code. Note: if you fix the code, and forget to click ``Run'' and try to re-run (p1 1 2) in the interpreter window, you'll see that DrScheme warns you that you've changed the code but haven't re-loaded it by printing a yellow-and black warning message "WARNING: The definitions window has changed. Click Run." Place a fixed version of the code in your hw1-answers.scm buffer.

Quitting DrScheme

PLEASE BE CAREFUL TO QUIT DRSCHEME COMPLETELY!! If you are kicked off, make sure you kill the process from elsewhere, or have the help staff do it. Some stray processes have used up all the account money of some students, which may make you late or miss an assignment.

To see all of your processes on Unix, do

That will show the PID (numeric Process ID) and what's running. DrScheme is a MrEd script, so ps will show "mred" as running.

To kill a job, do

where PID is the Process ID of the job you want
to kill.

Please check to make sure each time you logout or are accidentally booted off of the system. It could take several days to restore the account, and late homeworks are not accepted.

3. Exploring the system

The following exercises are meant to help you practice editing and debugging, and using on-line documentation. You may hand in all of your answers in one big (printed out) file.  Do not forget your documentation or to write your check-expect test cases!

Exercise 1: More debugging

The file hw1-2.scm defines three other procedures, called fold, spindle, and mutilate. One of these procedures contains an error.  Use the methods introduced above to identify what the error is.

Exercise 2: Still more debugging

The file hw1-fact.scm contains a buggy definition of a procedure meant to take a positive integer, n, and to compute its factorial: n! = n * (n-1) * (n-2) ... 3 * 2 * 1. Write the comments for this function, a couple of check-expect expressions (think about how many you need... boundary conditions, a small one, and a large on just for fun), and correct the code. 

Exercise 3: Defining a simple procedure

The number of combinations of n things taken k at a time is given by n! / k! (n-k)!. Define a procedure (comb n k) that computes the number of combinations, and find the number of combinations of 243 things taken 90 at a time. Include a check-expect expression for that case.

Exercise 4: Learning to use Help

How can you comment and uncomment out blocks of code in the DrScheme editor?

Exercise 5:

NOTE: MUST USE #i1.0 notation in Beginner/Intermediate mode

Write a procedure (cube-root x), similar to sqrt as done in class and the book. Use the improvement formula

(( x / g2) + 2g) / 3

where g is the guess and x is the input whose cube-root is to be found.

Like the sqrt formula, (x/g + g)/2, this formula is an instance of Newton's method.

Assume the input x is a real number (which may be negative). Make sure to include appropriate check-expect expressions to adequately test out both your main function and any helping functions that you write. Remember to use inexact number notation (i.e., #i1.0 )

Exercise 6:

Suppose + were not defined, but the more primitive procedures INC and DEC were. (INC n) returns the integer one greater than n, and (DEC n) returns the number one less than n. The following are two possible definitions of +, written using INC and DEC and using + recursively.

(define (+ a b) 
(if (= a 0)
b
(inc (+ (dec a) b))))

(define (+ a b)
(if (= a 0)
b
(+ (dec a) (inc b))))

Assignment: Write the steps of the evolution of the evaluation of (+ 4 5) for each of the two definitions of +. Are these processes iterative or recursive?

For example, the steps of the first version of + for (+ 3 6) are

(+ 3 6)
(inc (+ 2 6))
(inc (inc (+ 1 6)))
(inc (inc (inc (+ 0 6))))
(inc (inc (inc 6 )))
(inc (inc 7))
(inc 8)
9

Note: this is a pencil and paper exercise, no online computing required.

Exercise 7: Binomial Coefficients. (Exercise 1.12 in book)

Pascal's triangle presents the binomial coefficients as follows

    0 1 2 3 4 5 6
----------------------------
1 | 1 1
2 | 1 2 1
3 | 1 3 3 1
4 | 1 4 6 4 1
5 | 1 5 10 10 5 1
6 | 1 6 15 20 15 6 1
7 | 1 7 21 35 ...
8 | ...

Note that the row numbers start from 1 while the column numbers start from 0.

Among the interpretations is that the number in the row i, column j is the coefficient of xj in the expansion of (x + 1)i. For example, row three shows the coefficients of (x + 1)3 = 1 + 3x + 3x2 + x3.

Another interpretation is that the number in row i, column j is the number of ways to choose a subset of size j out of a set of size i. For example, there are 6 distinct ways to choose 2 items out of a set of 4 items.

In general

  1. the number in column 0 is a 1,
  2. for any i, the number in row i, column i is also a 1, and
  3. for 0 < j < i, the number in row i column j is the sum of the number above (position i-1, j) and the number above left (position i-1, j-1).

Assignment: Write a recursive procedure binomial-coefficient so that (binomial-coefficient i j) returns the value in row i column j of Pascal's triangle. You do not have to consider invalid inputs, that is, you may assume that the arguments i and j are integers such that 0 <= j <= i.

Please use tree recursion. Test out your function in DrScheme using appropriate check-expect expressions (which, of course, are best written before functions are written).