CS 275

Lab 01

The BasicsDue: Thursday, February 15

In this assignment you will create programs which put to use some of the week's topics. You'll aso be introduced to some useful new constructs. By the end of the assignment, you will have become comfortable with

The Dr. Racket Scheme interpreter

Writing Scheme functions

Using recursion with lists

Your solutions to the following exercises should all be placed in a single Scheme file with name hw1 (with Scheme extension .ss or Racket extension .rkt). The first line of your file shouldl be #lang racket Use Handin to submit your solutions.

Part 1 - Lists of Atoms

Some of the most intuitive Scheme functions work with lists of atoms such as the list (2 3 4). In this part we will write some of these functions. First, we need to rectify an omission. Some versions of Scheme have a primitive function atom? that returns #t if its argument is an atom and #f if it isn't. Since Racket has a primitive list? that returns #t if its argument is a list--i.e, either null or the result of a cons operation-- we can easily write atom?. Every expression is either an atom or a list. Use this to define function atom?. Here is some test data:

(atom? 3) returns #t

(atom? '(1 2) ) returns #f

(atom? null ) returns #f

Write the lat? function from The Little Schemer. This takes an argument and returns #t if it is the empty list or a list whose every element is an atom.

Write the function not-lat? that returns #t if its argument is NOT a list of atoms. Of course, you could write this as (define not-lat? (lambda (s) (not (lat? s))) ), but write it directly using cond.

Write the function list-of-ints? that returns #t if its argument is empty or if its argument is a list, each of whose entries is an integer. You can use the primitive function integer? for this.

Compare functions lat? and list-of-ints?. The structures of these functions should look very similar. Write function list-of-same? that takes two arguments: a predicate (which tests a condition) and a list. (list-of-same? kind-of-element s) returns #t if s is empty or if every element causes kind-of-element to return #t. (list-of-same? atom? s) should be the same as (lat? s), and (list-of-same? integer? s) should be the same as (list-of-ints? s).

Now rewrite list-of-same? as list-of-same2 so that it takes only one argument, a predicate, and returns a function that takes an argument and says if the predicate returns #t for each element of the argument. Now (list-of-same2 atom?) is the same as lat? and (list-of-same2 integer?) is the same as list-of-ints? This process of taking a function of two arguments and rewriting it as a fuction of one argument that returns another function of one argument is called currying the original function, named after Haskell Curry, and important American mathematician who worked in the foundations of logic and programming languages.

Write (mymember a lat), which returns #t if atom a is one of the elements of lat and #f if it isn't.

(mymember 'x '(a b x c x d) ) returns #t

/(mymember 'x '(a b c) ) returns #f

(mymember 'x '( ) ) returns #f

Write (rember2 a lat), which removes the second occurence of a from lat, if there is one.

(rember2 'x '(a b x c x d) ) returns (a b x c d)

(rember2 'x '(a b x c x d x e) ) returns (a b x c d x e)

(rember2 'x '(a b x c) )) returns (a b x c)

Write (rember-pair a lat), which removes every occurence of two consecutive instances of a in lat: