summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2014-07-29 06:57:00 -0700
committerKaz Kylheku <kaz@kylheku.com>2014-07-29 06:57:00 -0700
commit73e7fd1df88999b02e89cd497e9baeb9a1a6bb40 (patch)
tree0376dc71ff41e8e9136c915b34aef6a2d4d028bf
parent2014daea4ca5a4f92afc07bbc08dfdcb6c095a12 (diff)
downloadtxr-73e7fd1df88999b02e89cd497e9baeb9a1a6bb40.tar.gz
txr-73e7fd1df88999b02e89cd497e9baeb9a1a6bb40.tar.bz2
txr-73e7fd1df88999b02e89cd497e9baeb9a1a6bb40.zip
* 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.
-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