Name binding, Recursion, Iteration, and Continuations |
In Section 8.1 we saw how to bind names globally, at top level, by use of define. In this chapter we will study local name binding constructs - let constructs - and we will se how they are made by means of lambda expressions.
9.1. The let name binding expression
Contents Up Previous Next Slide Subject index Program index Exercise index
Let us first define what we mean by name binding constructs.
|
The syntax a let form follows.
| |||
|
|
The idea of simultaneous name binding is especially important to understand. Take a close look at the second example of Table 9.1 If you understand the result of the let expression in this example, you probably understand simultaneous name binding.
9.2. The equivalent meaning of let
Contents Up Previous Next Slide Subject index Program index Exercise index
A let construct can be defined by use of the name binding features of a lambda expression. In the rest of this section, we will see how it is done.
We will here understand the underlying, equivalent form of a let name binding construct |
Below we show a syntactic equivalence. The let form in Syntax 9.2 is fully equivalent with the lambda expression in Syntax 9.3
Whenever a form like Syntax 9.2 is encountered it is transformed to the equivalent, but more basic form of Syntax 9.3. The syntactic transformation is done by a Scheme macro.
| |||
|
| |||
|
9.3. Examples with let name binding
Contents Up Previous Next Slide Subject index Program index Exercise index
We provide a couple of examples of name binding with let. The examples are drawn from the web domain.
Expression | Value after rendering |
(let ((anchor "An anchor text") (url "http://www.cs.auc.dk") (tag a) ) (tag 'href url anchor)) | An anchor text |
(let ((f b)) (let ((f em) (g f)) (p (f "Text 1") (g "Text 2")))) | Text 1 Text 2 |
(let ((phrase-elements (list em strong dfn code samp kbd var cite abbr acronym)) ) (ul (map (lambda (f) (li (f "foo"))) phrase-elements))) |
|
Table 9.1 Examples of namebindings with let. The first example shows that all constituents of a function call can be bound to local names - in the example both the function object referred to by a, and two string parameters. The second example illustrates that alternative names, aliases, can be defined for a couple of functions. Notice in particular that g is bound to b (the bold face function), not em (the emphasis function). This can also be seen in the second column. The third example is a little more advanced, and it can first be understood fully on the ground of the material in the lecture about higher-order functions. We bind the name phrase-elements to a list of ten functions. Via mapping, we apply each function to foo, and we present the results in an ul list. |
9.4. The let* name binding construct
Contents Up Previous Next Slide Subject index Program index Exercise index
It is often useful to use a sequential alternative to simultaneous name binding, ala let. In this section we will study let*, which provides for sequential name binding.
It is often useful to be able to use previous name bindings in a let construct, which binds several names |
The syntax of let*, as shown in Syntax 9.4 is very close to the syntax of let, which we saw in Syntax 9.1.
| |||
|
|
Take a moment to understand the last item above. Thus, try to understand that it is possible to obtain the effect of sequential name bindings by nesting a number of ordinary let constructs. In that way, we can devise a rewriting of a let* construct to a construct with nested lambda expressions.
9.5. An example with let*
Contents Up Previous Next Slide Subject index Program index Exercise index
In the example on this page we show a function from the LAML time library. There is access to this library from the web material, cf. [timelib].
1 2 3 4 5 6 7 8 9 | (define (how-many-days-hours-minutes-seconds n) (let* ((days (quotient n seconds-in-a-day)) (n-rest-1 (modulo n seconds-in-a-day)) (hours (quotient n-rest-1 seconds-in-an-hour)) (n-rest-2 (modulo n-rest-1 seconds-in-an-hour)) (minutes (quotient n-rest-2 60)) (seconds (modulo n-rest-2 60)) ) (list days hours minutes seconds))) | |||
|
A set of functions for handling of time. |
Examples that illustrate uses of the LAML time functions are given later in the material, in Section 9.7.
9.6. The letrec namebinding construct
Contents Up Previous Next Slide Subject index Program index Exercise index
There exists a third local name binding form, called letrec. It is used for local definition of mutually recursive functions, as sketched in Program 9.2.
The letrec name binding construct allows for definition of mutually recursive functions |
| |||
|
1 2 3 4 | (letrec ((f1 (lambda (...) ... (f2 ...))) (f2 (lambda (...) ... (f1 ...))) ) body-expr) | |||
|
|
9.7. LAML time functions
Contents Up Previous Next Slide Subject index Program index Exercise index
In section Section 9.5 we discussed the function how-many-days-hours-minutes-second. We will now illustrate some other useful LAML time functions.
Expression | Value |
(current-time) | 999789132 |
(time-decode 1000000000) | (2001 9 9 3 46 40) |
(time-decode 0) | (1970 1 1 2 0 0) |
(time-interval 1000000000) | (31 8 2 5 1 46 40) |
(weekday (current-time)) | Thursday |
(danish-week-number (current-time)) | 36 |
Table 9.2 Example use of some of the LAML time library functions |
Strictly speaking, the abstractions which are applied in the example above, are not functions. They all depend on some state, which is updated every second due to the fact that time does not stand still.
9.8. References
[Timelib] | Manual of the LAML time library http://www.cs.auc.dk/~normark/scheme/distribution/laml/lib/man/time.html |