   Name binding, Recursion, Iteration, and Continuations
10.  Conditional expressions

In this chapter we will be interested in conditional expressions ala if and cond.

10.1.  Conditional expressions
Contents   Up Previous Next   Slide    Subject index Program index Exercise index

In this section we introduce if and cond , both at the syntactic level (through Syntax 10.1 and Syntax 10.2) and at the semantic level (below the syntax boxes).

 if and cond are special forms which evaluate their expressions according to the value of one or more boolean selectors if and cond are not control structures when applied in the functional paradigm

 ``` (if bool-expr expr1 expr2)```
 Syntax 10.1

 ``` (cond (bool-expr1 expr1) ... (bool-exprk exprk) (else exprk+1))```
 Syntax 10.2

 if evaluates expr1 if bool-expr is true, and expr2 if bool-expr is falsecond evaluates the first expression expri whose guarding bool-expri is true. If bool-expr1, ..., bool-exprkare all false, the value of cond becomes the value of exprk+1

This is a small exercise that aims at construction of slightly different header functions than those provided by the native header functions h1, ..., h6.

Define a function (header level) which takes a parameter level. The header function should return the similar basic header function provided that n is between one and six. If n is outside this interval, we want header to return the identity function of one parameter.

Hint: Arrange the header functions in a list, and let header select the appropriate header function from this list.

Define a variant of header which returns a native header function if it receives a single parameter (level), and which returns the value, such as, ((header 3) "Header text"), if it receives both a level parameter and a header text string.Solution

10.2.  Examples with if
Contents   Up Previous Next   Slide    Subject index Program index Exercise index

The examples in the table below gives web-related examples of if.

Expression

Value

```(body
(if (string=?
(weekday (current-time))
"Wednesday")
(p (em "Remember Thursday meeting!"))
'( ))

(h1 "Schedule")

(p "..."))```

Remember the Thursday meeting tomorrow!

# Schedule

...

```(body
(p (if (string=?
(weekday (current-time))
"Wednesday")
(em "Remember Thursday meeting!")
'( )))

(h1 "Schedule")

(p "..."))```

Remember the Thursday meeting tomorrow!

# Schedule

...

 Table 10.1    Examples using an if conditional expression on a Wednesday. In both examples we extract the weekday (a string) from the current time. If it is a Wednesday we emit a paragraph which serves as a reminder of a meeting the following day. If not executed on a Wednesday, we do not want any special text. We achieve this by returning the empty list, which is spliced into the the body context (in the first example) and into the paragraph context (in the second example). The splicing is a result of the handling of lists by the HTML mirror functions in LAML. The two examples differ slightly. In the first example the if is placed on the outer level, feeding information to body. In the second row, the if is placed at an inner level, feeding information to the p function. The two examples also give slightly different results. Can you characterize the results?

10.3.  Example with cond: leap-year?
Contents   Up Previous Next   Slide    Subject index Program index Exercise index

The leap year function is a good example of a function, which calls for use of a cond conditional. It would, of course, also be possible to program the function with nested if expressions.

```1
2
3
4
5
```
```(define (leap-year? y)
(cond ((= (modulo y 400) 0) #t)
((= (modulo y 100) 0) #f)
((= (modulo y 4) 0) #t)
(else #f)))```
 Program 10.1    The function leap-year?.

It is also possible to program the leap year function with simple, boolean arithmetic. This is shown below. It is probably easier for most of us to understand the version in Program 10.1 because it is closer to the way we use to formulate the leap year rules.

```1
2
3
4
5
6
7
8
9
10
11
```
```(define (leap-year? y)
(or (= (modulo y 400) 0)
(and (= (modulo y 4) 0)
(not (= (modulo y 100) 0)))))

(define (original-leap-year? y)
(cond ((= (modulo y 400) 0) #t)
((= (modulo y 100) 0) #f)
((= (modulo y 4) 0) #t)
(else #f)))```
 Program 10.2    The function leap year programmed without a conditional. A complete program for handling of time

10.4.  Example with cond: american-time
Contents   Up Previous Next   Slide    Subject index Program index Exercise index

In this section we will study an extended example of the use of cond. We carry out a calculation of 'American time', such as 2:30PM given the input of 14 30 00. There are several different cases to consider, as it appears in Program 10.3.

```1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
```
```(define (american-time h m s)
(cond ((< h 0)
(laml-error "Cannot handle this hour:" h))

((and (= h 12) (= m 0) (= s 0))
"noon")

((< h 12)
(string-append
(format-hour-minutes-seconds h m s)
" " "am"))

((= h 12)
(string-append
(format-hour-minutes-seconds h m s)
" " "pm"))

((and (= h 24) (= m 0) (= s 0))
"midnight")

((<= h 24)
(string-append
(format-hour-minutes-seconds (- h 12) m s)
" " "pm"))

(else
(laml-error "Cannot handle this hour:" h))))```
 Program 10.3    The function american-time.

In the web version of the material - slide or annotated slide view - we include a version of the program which includes the helping functions format-hour-minutes-seconds and zero-pad-string.

10.5.  Example with cond: as-string
Contents   Up Previous Next   Slide    Subject index Program index Exercise index

As a final example with cond, we show as-string, which is a function from the general LAML library. Given an almost arbitrary piece of data the function will attempt to convert it to a string. Similar functions named as-number, as-symbol, and as-boolean exist in the library, cf. [generallib].

```1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
```
```(define (as-string x)
(cond ((number? x) (number->string x))
((symbol? x) (symbol->string x))
((string? x) x)
((boolean? x)
(if x "true" "false"))   ; consider "#t" and "#f" as alternatives
((char? x) (char->string x))
((list? x)
(string-append "("
(string-merge (map as-string x) (make-list (- (length x) 1) " "))
")"))
((vector? x)
(let ((lst (vector->list x)))
(string-append "#("
(string-merge (map as-string lst) (make-list (- (length lst) 1) " "))
")")))
((pair? x)
(string-append "("
(apply string-append
(map (lambda (y) (string-append (as-string y) " ")) (proper-part x))
)
" . " (as-string (first-improper-part x))
")"))
(else "??")))```
 Program 10.4    The function as-string converts a variety of Scheme data types to a string.

10.6.  References
 [Generallib] Manual of the LAML general libraryhttp://www.cs.auc.dk/~normark/scheme/distribution/laml/lib/man/general.html

 Generated: Tuesday July 2, 2013, 09:15:16   