summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--eval.c5
-rw-r--r--lib.c17
-rw-r--r--lib.h3
-rw-r--r--txr.162
4 files changed, 81 insertions, 6 deletions
diff --git a/eval.c b/eval.c
index 89e3d18c..a5f823a7 100644
--- a/eval.c
+++ b/eval.c
@@ -6343,8 +6343,11 @@ void eval_init(void)
reg_mac(intern(lit("load-for"), user_package), func_n2(me_load_for));
reg_fun(cons_s, func_n2(cons));
- reg_fun(intern(lit("make-lazy-cons"), user_package), func_n1(make_lazy_cons));
+ reg_fun(intern(lit("make-lazy-cons"), user_package),
+ func_n3o(make_lazy_cons_pub, 1));
reg_fun(intern(lit("lcons-fun"), user_package), func_n1(lcons_fun));
+ reg_fun(intern(lit("lcons-car"), user_package), func_n1(lcons_car));
+ reg_fun(intern(lit("lcons-cdr"), user_package), func_n1(lcons_cdr));
reg_fun(car_s, car_f);
reg_fun(cdr_s, cdr_f);
reg_fun(rplaca_s, func_n2(rplaca));
diff --git a/lib.c b/lib.c
index 1ca81fc8..06cd37c1 100644
--- a/lib.c
+++ b/lib.c
@@ -3022,6 +3022,23 @@ val make_lazy_cons_car_cdr(val func, val car, val cdr)
return obj;
}
+val make_lazy_cons_pub(val func, val car, val cdr)
+{
+ return make_lazy_cons_car_cdr(func, default_null_arg(car), default_null_arg(cdr));
+}
+
+val lcons_car(val lcons)
+{
+ type_check(lit("lcons-car"), lcons, LCONS);
+ return lcons->lc.car;
+}
+
+val lcons_cdr(val lcons)
+{
+ type_check(lit("lcons-cdr"), lcons, LCONS);
+ return lcons->lc.cdr;
+}
+
void rcyc_cons(val cons)
{
cons->c.cdr = recycled_conses;
diff --git a/lib.h b/lib.h
index 1bbbfe35..6b8c0b0a 100644
--- a/lib.h
+++ b/lib.h
@@ -665,6 +665,9 @@ val cons(val car, val cdr);
val make_lazy_cons(val func);
val make_lazy_cons_car(val func, val car);
val make_lazy_cons_car_cdr(val func, val car, val cdr);
+val make_lazy_cons_pub(val func, val car, val cdr);
+val lcons_car(val lcons);
+val lcons_cdr(val lcons);
void rcyc_cons(val cons);
void rcyc_list(val list);
void rcyc_empty(void);
diff --git a/txr.1 b/txr.1
index fffd41b2..f8da8350 100644
--- a/txr.1
+++ b/txr.1
@@ -20137,7 +20137,7 @@ functions than less functions, the excess key functions are ignored.
.SS* Lazy Lists and Lazy Evaluation
.coNP Function @ make-lazy-cons
.synb
-.mets (make-lazy-cons << function )
+.mets (make-lazy-cons < function >> [ car <> [ cdr ]])
.syne
.desc
The function
@@ -20155,9 +20155,15 @@ A lazy cons has
and
.code cdr
fields like a regular cons, and those
-fields are initialized to
-.code nil
-when the lazy cons is created. A lazy cons also
+fields are initialized to the values of the
+.meta car
+and
+.meta cdr
+arguments of
+.code make-lazy-cons
+when the lazy cons is created. These arguments default to
+.meta nil
+if omitted. A lazy cons also
has an update function, which is specified by the
.meta function
argument to
@@ -20182,13 +20188,20 @@ and
.code cdr
fields. Once the function is called, it is removed
from the lazy cons: the lazy cons no longer has an update function.
-If the function attempts to retrieve the value of the
+If the update function itself attempts to retrieve the value of the
lazy cons cell's
.code car
or
.code cdr
field, it will be recursively invoked.
+The functions
+.code lcons-car
+and
+.code lcons-cdr
+may be used to access the fields of a lazy cons without
+triggering the update function.
+
Storing a value into either the
.code car
or
@@ -20271,6 +20284,45 @@ to retrieve a reference to itself and propagate itself into
another lazy cons (as in the example under
.codn make-lazy-cons ).
+.coNP Functions @ lcons-car and @ lcons-cdr
+.synb
+.mets (lcons-car << lazy-cons )
+.mets (lcons-cdr << lazy-cons )
+.syne
+.desc
+The functions
+.code lcons-car
+and
+.code lcons-cdr
+retrieve the
+.code car
+and
+.code cdr
+fields of
+.metn lazy-cons ,
+without triggering the invocation of its associated update function.
+
+The
+.meta lazy-cons
+argument must be an object of type
+.codn lcons .
+Unlike the functions
+.code car
+and
+.codn cdr ,
+These functions cannot be applied to any other type of object.
+
+Note: these functions may be used by the update function to retrieve
+the values which were stored into
+.meta lazy-cons
+by the
+.code make-lazy-cons
+constructor, without triggering recursion. The function may then
+overwrite either or both of these values. This allows the fields of the lazy
+cons to store state information necessary for the propagation of a lazy list.
+If that state information consists of no more than two values, then
+no additional context object need be allocated.
+
.coNP Macro @ lcons
.synb
.mets (lcons < car-expression << cdr-expression )