Laboratory Exercises For Computer Science 153

Symbols and Expressions

Symbols and Expressions

Goals: The purposes of this laboratory exercise are to clarify the concepts of symbols, binding, and expressions in Scheme, to introduce Scheme's read-eval-print loop, and to begin a discussion of lambda expressions.

Notes on the History of Scheme: Lisp was invented in the late 1950's and early 1960's at M.I.T. by John McCarthy. Lisp is based in part on the Lambda Calculus, a mathematical formalism developed by Alonzo Church (1903-1995).

Lisp is the second-oldest language still in widespread use (the oldest is Fortran). Two dialects of Lisp are widely used today: Scheme and Common Lisp. Scheme is a small, uniform dialect that is good for teaching because of its simplicity. Common Lisp is a large, ``industrial-strength'' dialect that is standardized and is available in several commercial versions. In this course, we will use an implementation of Scheme called Chez Scheme .

Most programming languages require learning the syntax of many different kinds of statements. In contrast, Scheme (and Lisp) syntax is simple and uniform. Much of the work in learning Scheme is learning the names and effects of the system functions that form the core of the language. This course presents the system functions and covers other functions that are present in Common Lisp.

Lisp is especially used for work in Artificial Intelligence. For example, CS 261, Artificial Intelligence, uses programming in LISP in its study of expert systems.

Steps for this Lab:

  1. Prepare to run the Chez Scheme programming environment, following the steps you used in the previous lab.

  2. Numeric Procedures: In Scheme, we apply operations to data using a prefix notation with parentheses. For example, the function f(x) would be written (f x). Also, all operation names are listed as the first component within the parentheses. Observe what happens when you type the following operations into Scheme:
        (- 27 3)
        (/ 17 2)
        (/ 17 -2)
        (/ 17 2.0)
        (truncate (/ 17 4))
        (modulo 17 3)
        (sqrt 4)
        (sin 0.5)
        (sqrt -2)
        (+ (* 3 2) (/ 8 4))
    

  3. Symbols are Scheme's analog of words; symbols are sequences of characters, such as
    hi TwoBeOrNot2Be This-is-a-symbol.
    In Scheme, symbols may act as variable names, but they do not have a value until we give them one. Describe what happens when you type one of the above symbols into Scheme.

  4. We may give a symbol a value using a define operation. For example, give the symbol pi the value 3.141592 as follows:
         (define pi 3.141592)
    
    Now enter pi into Scheme and determine what happens.

  5. Check if work with symbols within Chez Scheme is case sensitive. What happens if you type Pi or PI.

  6. Check whether Scheme allows you to redefine the value of a symbol. For example, following the 1897 Indiana House, try to declare that the value of pi is three:
         (define pi 3)
    
    Now what happens if you type the symbol pi?

  7. Determine what happens if you make a typographical error. For example, try misspelling define or leaving out a left or right parentheses. In each case, make a note describing what happens.

  8. Binding: The define operation binds a symbol to a value, based on the current values of its operands. For example, consider the following sequence of definitions from Program 1-4 of the textbook:
       (define a 4)
       (define b 5)
       (define c 1)
       (define discriminant 
             (- (* b b) (* 4 (* a c))))
       (define root1
             (/ (+ (- b) (sqrt discriminant))
                (* 2 a)))
       (define root2
             (/ (- (- b) (sqrt discriminant))
                (* 2 a)))
    
    Determine the values for a, b, c, discriminant, root1, and root2 .

    Now, redefine the values of a, b and c . Do the values of root1 and root2 change?

  9. Helpful Hint: In working on an HP workstation, you can select and paste material from one window to another. Through this semester, this can be particularly helpful, when you want to work with material that appears on the lab directions in the Netscape viewer.

    To select material from Netscape, move the cursor to the beginning of a section and push down the left mouse button. Then, holding the button down, move the mouse to the end of the section. (The entire section now should be highlighted.) When the desired section is highlighted, stop pressing on the left mouse button -- the section should stay highlighted. Now move the mouse to where you want to paste the material, and click the middle mouse button.

    For practice, select and paste the above sequence of define statements into Scheme within the dtterm window.

  10. Multiplication * as an n-ary operation: In the definition of discriminant, the multiplication operator * is used as a binary operator -- applying only to 2 operands. Scheme, however, defines the multiplication operator * as applying to as many operands as desired. For example, the above expression could be written:
       (define discriminant 
             (- (* b b) (* 4 a c)))
    
    Check the values Scheme returns for each of the following expressions:
       (* 2)
       (* 2 2)
       (* 2 2 2)
       (* 2 2 2 2)
       (* 2 2 2 2 2)
    
    What happens if you do not supply any operands?
       (*)
    
    Hypothesize why you get this result.

  11. The Quote Procedure: Sometimes we want Scheme to print the symbol, not its value (e.g., pi, not 3.141592). This is done with the quote procedure. To try this out, type
        (quote pi)
    
    (quote pi) may be abbreviated 'pi . Try typing this at the keyboard as well.

  12. Lambda Expressions: A lambda expression is a way of defining a mathematical function in Scheme. For example, the squaring function could be written:
        (lambda (x) (* x x))
    
    This expression indicates that the input parameter is x and the result of the function will be computed as (* x x).

    Apply this function to the values 1, 3, -2 by typing:

        ((lambda (x) (* x x)) 1)
        ((lambda (x) (* x x)) 3)
        ((lambda (x) (* x x))-2)
    
    What happens if you try to apply the function to all three values at once?
        ((lambda (x) (* x x)) 1 3 -2)
    
    In Scheme, a lambda expression is called a procedure.

  13. Naming Procedures: As the previous example shows, lambda expressions operate on the expression that follows them. However, in the example, the lambda expression was defined only for a single expression, and we had to type the lambda expression each time we used it. Since this is inconvenient, we often want to give the procedure a name, which we then can use repeatedly. More formally, we use define to bind a lambda expression to a symbol. If we call the above function f, then the above computations could be done as follows:
        (define f
            (lambda (x) (* x x)))
        (f 1)
        (f 3)
        (f -2)
    

  14. Write a Scheme procedure (add2 a) that returns the sum a+2.

  15. Define a procedure f(x) = x² - 3x + 2 and evaluate it for x = 0, 1, 2, 3, 4 .

This document is available on the World Wide Web as

http://www.math.grin.edu/~walker/courses/153/lab-symbols.html

created January 9, 1998
last revised January 12, 1998