Name binding, Recursion, Iteration, and Continuations |
In this chapter we will be interested in conditional expressions ala if and cond.
10.1 Conditional expressions | 10.4 Example with cond: american-time |
10.2 Examples with if | 10.5 Example with cond: as-string |
10.3 Example with cond: leap-year? |
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 |
| |||
|
| |||
|
|
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.
It means that ((header 3) "Header text") is equal to (h3 "Header text") and that ((h 0) "Header text") is just "Header text".
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))) | |||
|
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))) | |||
|
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)))) | |||
|
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 "??"))) | |||
|
10.6. References
[Generallib] | Manual of the LAML general library http://www.cs.auc.dk/~normark/scheme/distribution/laml/lib/man/general.html |