diff options
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | eval.c | 10 | ||||
-rw-r--r-- | txr.1 | 17 |
3 files changed, 21 insertions, 15 deletions
@@ -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. @@ -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; } } @@ -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 |