From 864d1c6fe182661a7bd7d4eda928f8a19318b651 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Wed, 9 Jun 2021 23:35:38 -0700 Subject: reduce-left: rewrite using seq_iter. * lib.c (reduce_left): Use sequence iteration instead of list operations. * txr.1: Add a note to the documentation. --- lib.c | 16 ++++++++++------ tests/012/seq.tl | 10 ++++++++++ txr.1 | 12 ++++++++++++ 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/lib.c b/lib.c index 9e3827d7..9a4f4533 100644 --- a/lib.c +++ b/lib.c @@ -7902,22 +7902,26 @@ val funcall4(val fun, val arg1, val arg2, val arg3, val arg4) wrongargs(fun); } -val reduce_left(val fun, val list, val init, val key) +val reduce_left(val fun, val seq, val init, val key) { + val self = lit("reduce-left"); + seq_iter_t item_iter; + val item; + if (null_or_missing_p(key)) key = identity_f; - list = nullify(list); + seq_iter_init(self, &item_iter, seq); if (missingp(init)) { - if (list) - init = funcall1(key, pop(&list)); + if (seq_get(&item_iter, &item)) + init = funcall1(key, item); else return funcall(fun); } - for (; list; list = cdr(list)) - init = funcall2(fun, init, funcall1(key, car(list))); + while (seq_get(&item_iter, &item)) + init = funcall2(fun, init, funcall1(key, item)); return init; } diff --git a/tests/012/seq.tl b/tests/012/seq.tl index 49d4046b..95ba7b6e 100644 --- a/tests/012/seq.tl +++ b/tests/012/seq.tl @@ -72,3 +72,13 @@ (lambda (. args) (/ (sum args) 5)) #(4 7 9 13 5 1 6 11 10 3 8)] #(4.0 6.6 7.6 7.0 6.8 7.2 6.6 6.2 7.6 6.4 4.2)) + +(mtest + [reduce-left + () 0] 0 + [reduce-left + ()] 0 + [reduce-left cons ()] :error + [reduce-left cons '(1)] 1 + [reduce-left cons #(1)] 1 + [reduce-left cons #(1) : (op * 10)] 10 + [reduce-left cons #(1) 2 (op * 10)] (2 . 10) + [reduce-left cons #(2 3) 10 (op * 10)] ((10 . 20) . 30)) diff --git a/txr.1 b/txr.1 index 80d28239..1a172ca7 100644 --- a/txr.1 +++ b/txr.1 @@ -34308,6 +34308,18 @@ and to a single value by the repeated application of .metn binary-function . +In the case of +.codn reduce-left , +the +.meta list +argument required to be an object which is iterable according to the +.code iter-begin +function. The +.code reduce-right +function treats the +.meta list +argument using list operations. + An effective list of operands is formed by combining .meta list and -- cgit v1.2.3