Higher-Order Programming » Lab Sessions
Session 4 (Solutions)
Assistant: Steven Keuchel (steven.keuchel@vub.be)
Exercise 1: Iterative sum
Exercise 2: Iterative Map / Filter
The implementation of deep-map
is straightforward. If the list is empty, the
empty list will be returned. If the list is indeed a list (or its more generic
form: a pair), then deep-map
will be applied recursively on the car
and
cdr
of the pair. Otherwise, we assume it to be a number, boolean, or other
non-pair value, and we apply the supplied mapper function on it.
The implementation of deep-filter
is more complicated. It follows the same
pattern: check for empty list, check for pair, otherwise, execute the given
function.
The third case is the most important one: since it can either return 1 or no
values. This is implemented by it either returning a singleton list, or the
empty list. However, we need to take into account the structure of the empty
list. Therefore in the second case there are some additional checks on the type.
If the recursive call on car
is on a non-pair, this wrapped list needs to be
removed via car
.
Depending on whether both car and cdr have, or do not have, items to process, either only car or cdr can be returned, or a new pair.
The last peculiar case is when cdr-result
is the empty list, then (list car-result)
is returned. Since in this case the input element of deep-filter
was a list (or at least a pair), the returned element should again be a list.
Exercise 3: Flatten
By making use of append two lists are concatenated. Therefore, if the recursive calls on car
and cdr
return flattened lists, then they can easily be concatenated to create a larger flattened list. Therefore, in the last case of cond
the elements are wrapped in a singleton list (a flattened list by definition) such that flatten
can only receive flattened lists as arguments.
The implementation of filter
can be reused from previous exercises.
Section 2: Lambda and Let
Exercise 4: Convert to lambdas
let:
let*:
Exercise 5: A Lexical Bug
Conversion to lambda:
The variable x
is a free variable that is not defined outside of lambda
.
Fix:
By modifying the code such that let*
is used instead of let
.
Conversion to lambda (correct version):