<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body bgcolor="#ffffff" text="#000000">
<br>
<a href="http://sourceforge.net/projects/cl-heresy/">http://sourceforge.net/projects/cl-heresy/</a><br>
<br>
<br>
----<br>
<br>
Structurally, every lazy link, originally a single no-input function,
has been replaced with a 2-function "link" - one being a zero-input
function that returns value/next, the other being same but that accepts
a replacement "end"-link - that is, a value/next generator that is to
be applied when the end of the original list is struck. Since the two
functions are to be near-identical, they are generally created via a
macro which takes the common form. The most useful result of this
feature is that concat/append list actions can be chained up without a
per-element cost.<br>
<br>
For example:<br>
<br>
; a is set to a lazy lazy-list of 1, 2, 3, 4<br>
(setf a (map/ #'identity '(1 2 3 4))) <br>
<i>; (a now traverses to (1 2 3 4))</i><br>
<br>
; a repeatedly put in a lazy-list, which is provided to concat/ (no
material change in result; but lazy-evaluation<br>
; stores up each step)<br>
(loop for i from 1 to 1000000 do (setf a (concat/ (map/ #'identity
(list a)))))<br>
<i>; (a still traverses to (1 2 3 4); but through 1000000 concat/
blocks)</i><br>
<br>
Traversal of <i>a</i> now bears a single cost - once to obtain the
first value, once to discover the end. That is, the cost is borne when
"switching depths" of concatenated lists only. There is no per-element
cost for the 4 numbers, nor does the traversal consume the stack.<br>
<br>
----<br>
<br>
Every call has the choice to return a result of type '<i>unresolved</i>
- which can be created by the macro <i>unresolved</i>. An <i>unresolved</i>
contains a zero-parameter lambda/function that returns the true result,
with the type being used to switch on.<br>
<br>
The rationale for this mechanism is to prevent the problem of functions
calling functions calling functions, and consuming the stack. The
macro <i>resolved</i> repeatedly evaluates an <i>unresolved</i> until
the result is no longer an <i>unresolved</i>. This is leveraged
throughout the library in order to allow a form to return the result of
a call; but being able to subtract its own stack depth from the
equation.<br>
<br>
Here is a simple example of A calling B calling C<br>
<br>
<br>
(defun c ()<br>
(unresolved (+ 3 4))) ; returns unresolved 3 + 4<br>
<br>
(defun b ()<br>
(unresolved (c))) ; returns unresolved call to c<br>
<br>
(defun a ()<br>
(unresolved (b))) ; returns unresolved call to b<br>
<br>
<br>
(print (resolved (a))) ; the <i>resolved</i> macro takes an <i>unresolved</i>
from the call to A, and repeatedly resolves to the final result 7.<br>
; <i>At no point </i>do successive calls to the 3 functions
appear on the same stack.<br>
<br>
The <i>resolved</i> and <i>unresolved </i>macros in heresy.lisp may
explain this better than I can in words.<br>
<br>
The symbols for <i>resolved</i> and <i>unresolved</i> are not
currently exported by Heresy, nor are they documented - they are
currently an unexposed/undocumented internal tool for chaining up
effects expressed via successive function-calls without stack usage.
This will likely change in a future revision, as there are instances
where the user of the library may wish to express a lazy-list or map
function in terms of <i>unresolved</i>, yet still leverage
compatibility through Heresy functions such as <i>filter/</i>
resolving the values on an as-needed basis. (This can be leveraged now
through the unexported symbols).<br>
<br>
----<br>
<br>
A battery of unit-tests have been added, to attempt to gain
code-coverage of lazy-functions that have different code paths
depending upon the type/characteristics of the input list, and tested
in both lazy and eager contexts. Functions that return lazy-lists have
said lists tested both standalone and concatenated, so as to ensure
that the distinct code-paths for each use are tested. This results in
4 x 2 x 2 combinations for each list-returning test. The complexity of
this new structure (number of potential failure combinations) mandate
test-driven development going forward.<br>
<br>
<br>
<br>
</body>
</html>