Scheme vs. CLISP
Submission Instructions
Accessing Scheme Solutions on mars
To access the Scheme solutions to Lisp Assignments 3, 4, and 5, you will need to use the kawa Scheme interpreter, which is available to you on mars.
To start the kawa Scheme interpreter on mars, enter:
scm
at the xxxxx_yyyy316@mars:~$ prompt. This will only work if you followed the instructions regarding 316setup in the Lisp Assignment 1 document.
You can exit Scheme by entering (exit) at Scheme’s prompt; this is a function call, so you must type the ( and ).
Important: Enter scm and NOT scheme to start the kawa Scheme interpreter. If you enter scheme, you will start a different Scheme interpreter that is NOT able to read the solutions to the Assignments!
Scheme to Common Lisp Translation Guide
The table below can be used to “translate” simple Scheme code (e.g., the Scheme code in the solutions to assignments or in Ch. 10 of Sethi) into Common Lisp:
| Scheme | Common Lisp |
|---|---|
(define x 3) |
(setf x 3) |
(define (f x y z) ...) |
(defun f (x y z) ...) |
#f (means “false”) |
nil or () |
#t |
t |
() (empty list) |
nil or () |
else (final guard of COND) |
t |
null? |
null |
equal? |
equal |
even? |
evenp |
odd? |
oddp |
symbol? |
symbolp |
number? |
numberp |
integer? |
integerp |
pair? |
consp |
zero? |
zerop |
Important Notes
-
Whereas
(car nil)and(cdr nil)returnNILin Common Lisp—which is illogical but can be convenient—(cdr ())and(car ())are undefined in Scheme. -
()is NOT equivalent to#fin Scheme;()is a TRUE value! The symbolNILis NOT equivalent to(), nor to#f;NILhas no special meaning in Scheme.
Differences Between Scheme and Common Lisp for Functions as Arguments
This is a critical distinction when working with higher-order functions (functions that take other functions as arguments):
In Common Lisp:
- If
Fis the name of a function, then the value of#'Fis that same function, butFitself may have any value or no value. (DEFUN F ...)makesFthe name of a function but does NOT affect the value (if any) ofF.- If
Fis the name of a function, then(F ...)calls that function. - If the value of
Fis a function, then(FUNCALL F ...)calls that function.
In Scheme:
- The value of
Fis a function just ifFis the name of that same function. - Accordingly:
(FUNCALL F ...)is NOT used: A Common Lisp call(FUNCALL F ...)is written as(F ...)in Scheme.#'Fis NOT used: A Scheme programmer would writeFwhere a Common Lisp programmer writes#'F.
When translating from Scheme to Common Lisp:
- Replace
(F x y)(where F holds a function) with(FUNCALL F x y) - Add
#'before function names passed as arguments:(MAPCAR F L)becomes(MAPCAR #'F L)
Technical Notes
Case Sensitivity in kawa Scheme
Lowercase letters in kawa Scheme symbol names are NOT automatically converted to upper case when they are read in. Most predefined functions and the functions defined in the solutions have lowercase names, and these names must be entered in lowercase when you call the functions.
Real Number Testing
Some of the solutions use a test (real? x). The Scheme predicate real? tests whether or not its argument is a real number, and is analogous to the predicate REALP in Common Lisp. As we are not using complex numbers in this course, points will not be deducted if you called NUMBERP instead of REALP.
Safe-CDR Helper Function
The Scheme solution to the multiple-member problem uses a helping function safe-cdr that is like cdr but satisfies (safe-cdr #f) => ().
The reason safe-cdr was used is that the Common Lisp solution uses the fact that (cdr nil) => nil, but Scheme produces an error when it evaluates (cdr #f). So safe-cdr serves as a Scheme analog of Common Lisp’s cdr in this problem—in Common Lisp, you can just use cdr or rest.