Lazy Evaluation
This post is about lazy evaluation in Motto. As everything else, lazy evaluation can be accomplished without adding new syntax to the language. Code blocks and the bang (!) procedure is all that we need. As an example, consider the following procedure that generates an infinite sequence of numbers:
> [def n [n n 1 + integers]] def integers
integers is a procedure that returns a
procedure.
The returned procedure, when executed, will leave a copy of the
argument on the stack and call
integers again with the argument incremented by 1. This will leave
a new procedure on the stack
that will return this incremented value and so on. All this happens
with no explicit management and
modification of state. Let us see how integers can be used to
produce a sequence, given a value to
start with:
> 10 integers ! ! ! ! ! ! .p 10 11 12 13 14 15 > .c ;; or using the `times` procedure: > 0 integers [!] 10 times .p 0 1 2 3 4 5 6 7 8 9
The following procedure shows how we could transform a lazy sequence by filtering out elements using a predicate:
> [def predic
[! def n def i self def next-i
i predic ? [i @n] [@n next-i]]] def filter
;; Filter even integers out:
> 0 integers @is-odd filter def p [p] 10 times .p
1 3 5 7 9 11 13 15 17 19
> .c
;; Filter odd integers out:
> 0 integers @is-even filter def p [p] 10 times .p
0 2 4 6 8 10 12 14 16 18(This example is based on the code in Section 4.2.5 of R7RS.).