CSE 341 -- Scheme Predicates; Commenting Style

Some operators are predicates, that is, they are truth tests. In Scheme, they return #f or #t. Peculiarity: in R4 (the previous version of Scheme) the empty list is equivalent to #f, and everything else is equivalent to #t. However, in R5 (the current version) the empty list is also equivalent to #t! Moral: only use #f and #t for boolean constants.

Equality and Identity: equal?, eqv?, eq?

Scheme provides three primitives for equality and identity testing:
  1. eq? is pointer comparison. It returns #t iff its arguments literally refer to the same objects in memory. Symbols are unique ('fred always evaluates to the same object). Two symbols that look the same are eq. Two variables that refer to the same object are eq.
  2. eqv? is like eq? but does the right thing when comparing numbers. eqv? returns #t iff its arguments are eq or if its arguments are numbers that have the same value. eqv? does not convert integers to floats when comparing integers and floats though.
  3. equal? returns true if its arguments have the same structure. Formally, we can define equal? recursively. equal? returns #t iff its arguments are eqv, or if its arguments are lists whose corresponding elements are equal (note the recursion). Two objects that are eq are both eqv and equal. Two objects that are eqv are equal, but not necessarily eq. Two objects that are equal are not necessarily eqv or eq. eq is sometimes called an identity comparison and equal is called an equality comparison.
Examples:
(define clam '(1 2 3))
(define octopus clam)              ; clam and octopus refer to the same list

(eq? 'clam 'clam)            => #t
(eq? clam clam)              => #t  
(eq? clam octopus)           => #t
(eq? clam '(1 2 3))          => #f ; (or (), in MIT Scheme)
(eq? '(1 2 3) '(1 2 3))      => #f 
(eq? 10 10)                  => #t ; (generally, but implementation-dependent)
(eq? 10.0 10.0)              => #f ; (generally, but implementation-dependent)
(eqv? 10 10)                 => #t ; always
(eqv? 10.0 10.0)             => #t ; always
(eqv? 10.0 10)               => #f ; no conversion between types
(equal? clam '(1 2 3))       => #t
(equal? '(1 2 3) '(1 2 3))   => #t
Scheme provides = for comparing two numbers, and will coerce one type to another. For example, (equal? 0 0.0) returns #f, but (= 0 0.0) returns #t.

Commenting Style

If Scheme finds a line of text with a semicolon, the rest of the line (after the semicolon) is treated as whitespace. However, a frequently used convention is that one semicolon is used for a short comment on a line of code, two semicolons are used for a comment within a function on its own line, and three semicolons are used for an introductory or global comment (outside a function definition).