summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--eval.c10
-rw-r--r--txr.117
3 files changed, 21 insertions, 15 deletions
diff --git a/ChangeLog b/ChangeLog
index c01eea05..a5036e15 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2014-07-29 Kaz Kylheku <kaz@kylheku.com>
+
+ * eval.c (giterate_func, giterate): Adjusting semantics of giterate to
+ include seed item in the sequence. The while test is applied to
+ each item before it is passed through the function. Also,
+ eliminated useless rplacd operation.
+
+ * txr.1: Updated documentation of giterate.
+
2014-07-28 Kaz Kylheku <kaz@kylheku.com>
* eval.c (eval_init): Register partition-by intrinsic.
diff --git a/eval.c b/eval.c
index e44d132f..1c9724cd 100644
--- a/eval.c
+++ b/eval.c
@@ -3160,12 +3160,9 @@ val generate(val while_pred, val gen_fun)
static val giterate_func(val env, val lcons)
{
cons_bind (while_pred, gen_fun, env);
- val value = lcons->lc.car;
+ val next_item = funcall1(gen_fun, lcons->lc.car);
- if (!funcall1(while_pred, value)) {
- rplacd(lcons, nil);
- } else {
- val next_item = funcall1(gen_fun, value);
+ if (funcall1(while_pred, next_item)) {
val lcons_next = make_lazy_cons(lcons_fun(lcons));
rplacd(lcons, lcons_next);
rplaca(lcons_next, next_item);
@@ -3180,9 +3177,8 @@ static val giterate(val while_pred, val gen_fun, val init_val)
if (!funcall1(while_pred, init_val)) {
return nil;
} else {
- val first_item = funcall1(gen_fun, init_val);
val lc = make_lazy_cons(func_f1(cons(while_pred, gen_fun), giterate_func));
- rplaca(lc, first_item);
+ rplaca(lc, init_val);
return lc;
}
}
diff --git a/txr.1 b/txr.1
index 560f359f..e8da4242 100644
--- a/txr.1
+++ b/txr.1
@@ -9033,23 +9033,24 @@ the gen-func to populate it with the first item.
The giterate function is similar to generate, except that <while-fun>
and <gen-fun> are functions of one argument rather than functions of
no arguments. The optional <value> argument defaults to nil and
-is threaded through the function calls. Prior to producing the first item,
-the lazy list returned by giterate invokes <while-fun> on <value>.
-If the call yields true, then <gen-fun> is invoked on <value> and the
-resulting value is added to the sequence. That resulting value also becomes the
-value for the next iteration: when <while-fun> is invoked again, that
-value is used, rather than the original value.
+is threaded through the function calls. That is to say, the lazy
+list returned is (<value> [<gen-fun <value>] [<gen-fun> [<gen-fun> <value>]] ...).
+
+The lazy list terminates when a value fails to satsify <while-fun>.
+That is to say, prior to generating each value, the lazy list tests
+the value using <while-fun>. If that function returns false, then
+the item is not added, and the sequence terminates.
Note: the giterate function could be written in terms of generate
like this:
(defun giterate (w g v)
- (generate (lambda () [w v]) (lambda () (set v [g v]))))
+ (generate (lambda () [w v]) (lambda () (prog1 v (set v [g v])))))
.SS
Example:
- (giterate (op > 5) (op + 1) 0) -> (1 2 3 4 5)
+ (giterate (op > 5) (op + 1) 0) -> (0 1 2 3 4)
.SS Function repeat