CISC-280 Program Development Techniques

Problem Set 1: Introduction

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. (There is nothing to turn in for this question!)

(- 8 9)


(> 3.7 4.4)

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

(define b 13)

13

b

>

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

(square 13)

(square b)

(square (square (/ b 1.3)))

(define multiply-by-itself square)

(multiply-by-itself b)

(define a b)

(= a b)

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

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

2. Getting started with DrScheme

Our Composers project number is 2011 (for Fall 2007) . Info on using DrScheme on the Composers is at           http://www.udel.edu/topics/software/special/language/drscheme/

Most of you will just want to download a copy to your own personal computer (Windows, Mac, Linux); see the link on our course webpage.

In the DrScheme environment, you will use a text-editing system which incorporates an editor closely resembling the widely used editor Emacs. The top window is the "definitions" window, and the bottom window is the "interactions" window-- DrScheme's READ-EVAL-PRINT loop. 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.

Language Levels

The first time that you run drscheme it will ask you which langauge level you want. Language levels allow DrScheme to hide some features from the beginner user (it will flag them as errors, even though they are not technically errors). In order to run the examples in teh textbook (which was not written with this feature in mind) you will need the full language, choose Syntax = Pretty Big (includes MrEd and Advanced Student). We will play around with this at the beginning, however.

Evaluating expressions

Go to the Scheme interactions (lower) buffer. 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)))

(* 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 top 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 reserved words, 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.

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, with the error):

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

Now, click on Check Syntax.

If you actually typed in the definition exactly as printed above, you should see ``*x'' (with no space) highlighted in bright red. This is not a syntax error, but DrScheme is warning you that ``*x'' is currently undefined (it's a perfectly valid identifier name).

Edit the definition to insert a space between * and x. Re-Syntax-Check and Re-Run the definition, and return to Scheme and try evaluating (square 4).

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.

As a second method of evaluating expressions, try the following. Go instead to the scheme interpreter buffer, and again type in verbatim :

(define test (lambda (x) (*x x)))

Place the cursor at the end of the line, and type return to evaluate this expression. Note there is no error YET... Try (test 4). When it fails this time, you should type Esc-p several times, until the definition of test that you typed in appears on the screen. Edit this definition to insert a space between * and x, type return to evaluate the new expression, and use Esc-p to get back the expression (test 4). Make a habit of using Esc-p, rather than going back and editing previous expressions in the Scheme buffer in place. That way, the buffer will contain an intact record of your work, line by line. Note however that the entire scheme interpreter buffer is erased each time you click on Execute to load the editor buffer into the interpreter. Even though the buffer is erased, Esc-p will still work (DrScheme retains the past command history---even between invocations!).

Printing a File

You can print either the definitions buffer or the interactions buffer, using PRINT under the FILE menu. After choosing PRINT, you will get a print dialog box.

Stepped Evaluation: Using The Foot

For the rest of this assignment, change your Language Level to "How To Design Programs-->Intermediate Student with Lambda" . This enables the "stepper" and allows you to debug using the Simple Substitution Model.

Load the file ~decker/Class/CISC280/hw1/hw1-0.scm 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 3 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 NEXT 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.

Load the code for this problem set from ~decker/Class/CISC280/hw1/hw1-1.scm This will load definitions of the following three procedures p1, p2, and p3:

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

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

(define p3
  (lambda (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 Run 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:

procedure p2: expects 2 arguments, given 1: 1

DrScheme has also highlighted the location of the error in your source code. You can fix the error (p2 a b) and re-execute the code. Note: if you fix the code, and forget to click "Run" and try to re-run (p1 1 2) (by typing Esc-p), 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: Program has changed. Click Execute.''. Use the Stepper to watch the evaluation of (p1 1 2). Make sure that you understand the Simple Substitution Model of Eval and Apply.

Quitting DrScheme

PLEASE BE CAREFUL TO QUIT DRSCHEME COMPLETELYON THE COMPOSERS!! If you are kicked off of the Composers, 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

kill -9 PID

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.

Exercise 1: More debugging

The file ~decker/Class/CISC280/hw1/hw1-2.scm defines three other procedures, called fold, spindle, and mutilate. One of these procedures contains an error. What is the error?

Exercise 2: Still more debugging

The file ~decker/Class/CISC280/hw1/hw1-fact.scm contains a buggy definition of a procedure meant to compute the factorials of positive integers: n! = n * (n-1) * (n-2) ... 3 * 2 * 1. Evaluate the expression (fact 5) (which is supposed to return 120). Use the debugger to find the bug and correct the definition. Compute the factorial of 243. Copy the corrected definition and the value of (fact 243) into your homework answers buffer.

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 your procedure definition and your answer in your homework.

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 with Language Level "Intermediate Student with Lambda"

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

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). Test out your procedure using DrScheme. Include the answers and your tests in your homework. Remember to use inexact number notation (i.e., #i1.0 )

Exercise 6:

[Note: This is NOT a programming excercise!] 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 + 
  (lambda (a b) 
    (if (= a 0)
        b
        (inc (+ (dec a) b)))))

(define + 
  (lambda (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.

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 procedure using DrScheme.