HOME | 4. Defining Functions | Yet Another Scheme Tutorial | 6. Local Variables | Post Messages |

(If theifpredicatethen_valueelse_value)

In R^{5}RS, the false (`#f`) and the empty list (`'()`) are different
object. However, in MIT-Scheme they are the same. This difference may be due to a historical reason;
in R^{4}RS, the previous standard, `#f` and `'()` are defined as the same object.

Thus, you should not use lists directory as predicates for the compatibility. Use function null? to see if the list is empty.

```
(null? '())
;Value: #t
(null? '(a b c))
;Value: () ;#f
```

Function not is available to negate predicates.
This function takes exactly one argument and returns #t if the argument is #f otherwise #t.
The if expression is a special form because
it does not evaluate all arguments.
If the `predicate` is true, only `then_value` is evaluated.
On the other hand, if the `predicate` is false, only `else_value` is evaluated.

Example: sum of geometric progression, whose first term, geometric ratio, and number of terms are
`a0`, `r`, and `n`.

```
(define (sum-gp a0 r n)
(* a0
(if (= r 1)
n
(/ (- 1 (expt r n)) (- 1 r))))) ; !!
```

In general, the sum of geometric progression is calculated by:
a0 * (1 - rIf the^{n}) / (1 - r) (r ≠ 1) a0 * n (r = 1)

You can omit the `else_value` term. In this case the returned value
when the `predicate` is false is not specified.
If you need `#f` when the `predicate` is false,
you should write it explicitly.

The `then_value` and `else_value` should be one S-expression.
If you need side effects, you should use
begin expression.
I will mention about `begin` in a later chapter.

- A function to return the absolute value of a real number.
- A function to return the reciprocal of a real number. Make it return
`#f`if the argument is 0. - A function to convert a integer to a graphical character of ASCII characters.
The integers that can be converted to graphical characters are 33 – 126.
Use integer->char to convert a integer to a character.
Make it return
`#f`if the given integer can not be converted to a graphical character.

(and #f 0) ;Value: () (and 1 2 3) ;Value: 3 (and 1 2 3 #f) ;Value: ()

(or #f 0) ;Value: 0 (or 1 2 3) ;Value: 1 (or #f 1 2 3) ;Value: 1 (or #f #f #f) ;Value: ()

- A function that takes three real numbers as arguments. It returns the product of these three numbers if all them is positive.
- A function that takes three real numbers as arguments. It returns the product of these three numbers if at least one of them is negative.

(cond (In the cond expression,predicate_1clauses_1) (predicate_2clauses_2) ...... (predicate_nclauses_n) (elseclauses_else))

Example: Fee of a city-run swimming pool

The fee of a city-run swimming pool of Foo city depends on the age of users (`age`):

- free if
`age`≤ 3 or`age`≥ 65. - 0.5 dollars for 4 ≤
`age`≤ 6. - 1.0 dollars for 7 ≤
`age`≤ 12. - 1.5 dollars for 13 ≤
`age`≤ 15. - 1.8 dollars for 16 ≤
`age`≤ 18. - 2.0 dollars for others.

(define (fee age) (cond ((or (<= age 3) (>= age 65)) 0) ((<= 4 age 6) 0.5) ((<= 7 age 12) 1.0) ((<= 13 age 15) 1.5) ((<= 16 age 18) 1.8) (else 2.0)))

- The grade (A – D) of exam is determined by the score (
`score`). Write a function that takes a score as an argument and returns a grade.- A if
`score`≥ 80 - B if 60 ≤
`score`≤ 79 - C if 40 ≤
`score`≤ 59 - D if
`score`< 40

- A if

- eq?
- It compares addresses of two objects and returns
`#t`if they are same. In the following example, the function returns`#t`as`str`has the same address as itself. On the contrary, as "hello" and "hello" are stored in the different address, the function returns`#f`. Don't use`eq?`to compare numbers because it is not specified in R^{5}RS even it works in MIT-Scheme. Use eqv? or = instead.(define str "hello") ;Value: str (eq? str str) ;Value: #t (eq? "hello" "hello") ;Value: () ← It should be #f in R

^{5}RS ;;; comparing numbers depends on implementations (eq? 1 1) ;Value: #t (eq? 1.0 1.0) ;Value: () - eqv?
- It compares types and values of two object stored in the memory space.
If both types and values are same, it returns
`#t`. Comparing procedure (lambda expression) depends on implementations. This function cannot be used for sequences such as lists or string, because the value stored in the first address are different even the sequences looks same.(eqv? 1.0 1.0) ;Value: #t (eqv? 1 1.0) ;Value: () ;;; don't use it to compare sequences (eqv? (list 1 2 3) (list 1 2 3)) ;Value: () (eqv? "hello" "hello") ;Value: () ;;; the following depends on implementations (eqv? (lambda(x) x) (lambda (x) x)) ;Value: ()

- equal?
- It is used to compare sequences such as list or string.
(equal? (list 1 2 3) (list 1 2 3)) ;Value: #t (equal? "hello" "hello") ;Value: #t

- pair?
- It returns
`#t`if the object consists of cons cells (or a cons cell). - list?
- It returns
`#t`if the object is a list. Be careful in that`'()`is a list but not a pair. - null?
- It returns
`#t`if the object is`'()`. - symbol?
- It returns
`#t`if the object is a symbol. - char?
- It returns
`#t`if the object is a character. - string?
- It returns
`#t`if the object is a string. - number?
- It returns
`#t`if the object is a number. - complex?
- It returns
`#t`if the object is a complex number. - real?
- It returns
`#t`if the object is a real number - rational?
- It returns
`#t`if the object is a rational number. - integer?
- It returns
`#t`if the object is an integral - exact?
- It returns
`#t`if the object is**not**a floating point number. - inexact?
- It returns
`#t`if the object is a floating point number.

- =, <, >, <=, >=
- These functions takes arbitrary number of arguments.
If arguments are ordered properly indicated by the function name,
the functions return
`#t`.(= 1 1 1.0) ;Value: #t (< 1 2 3) ;Value: #t (< 1) ;Value: #t (<) ;Value: #t (= 2 2 2) ;Value: #t (< 2 3 3.1) ;Value: #t (> 4 1 -0.2) ;Value: #t (<= 1 1 1.1) ;Value: #t (>= 2 1 1.0) ;Value: #t (< 3 4 3.9) ;Value: ()

- odd?, even?, positive?, negative?, zero?
- These functions take exactly one argument and return
`#t`if the argument satisfies the property indicated by the function name.

I will explain about the local variables in the next chapter.

; 1 (define (my-abs n) (* n (if (positive? n) 1 -1))) ; 2 (define (inv n) (if (not (zero? n)) (/ n))) ; 3 (define (i2a n) (if (<= 33 n 126) (integer->char n)))

; 1 (define (pro3and a b c) (and (positive? a) (positive? b) (positive? c) (* a b c))) ; 2 (define (pro3or a b c) (if (or (negative? a) (negative? b) (negative? c)) (* a b c)))

(define (score n) (cond ((>= n 80) 'A) ((<= 60 n 79) 'B) ((<= 40 n 59) 'C) (else 'D)))

HOME | 4. Defining Functions | Yet Another Scheme Tutorial | 6. Local Variables | Post Messages |