From 7b0cc54a306486e2ca09b7863f7330f85bf6531c Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Tue, 29 Jul 2014 07:27:38 -0700 Subject: * eval.c (eval_init): Register nconc as intrinsic. * lib.c (nconcv): New function. * lib.h (nconcv): Declared. * txr.1: Documented nconc. --- ChangeLog | 10 ++++++++++ eval.c | 1 + lib.c | 12 ++++++++++++ lib.h | 1 + txr.1 | 11 ++++++++--- 5 files changed, 32 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2e3a0e50..ef3197ba 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2014-07-29 Kaz Kylheku + + * eval.c (eval_init): Register nconc as intrinsic. + + * lib.c (nconcv): New function. + + * lib.h (nconcv): Declared. + + * txr.1: Documented nconc. + 2014-07-29 Kaz Kylheku * lib.c (reduce_left, reduce_right): Nullify incoming sequence diff --git a/eval.c b/eval.c index 1c9724cd..dabb40bf 100644 --- a/eval.c +++ b/eval.c @@ -3598,6 +3598,7 @@ void eval_init(void) reg_fun(intern(lit("replace-list"), user_package), func_n4o(replace_list, 2)); reg_fun(append_s, func_n0v(appendv)); reg_fun(intern(lit("append*"), user_package), func_n0v(lazy_appendv)); + reg_fun(intern(lit("nconc"), user_package), func_n0v(nconcv)); reg_fun(list_s, list_f); reg_fun(intern(lit("list*"), user_package), func_n0v(list_star_intrinsic)); reg_fun(identity_s, identity_f); diff --git a/lib.c b/lib.c index 2b209b77..afb134b8 100644 --- a/lib.c +++ b/lib.c @@ -727,6 +727,18 @@ val nappend2(val list1, val list2) return out; } +val nconcv(val lists) +{ + list_collect_decl (out, ptail); + + for (; lists; lists = cdr(lists)) { + val item = car(lists); + ptail = list_collect_nconc(ptail, item); + } + + return out; +} + val sub_list(val list, val from, val to) { val len = nil; diff --git a/lib.h b/lib.h index 157a7994..b6051100 100644 --- a/lib.h +++ b/lib.h @@ -436,6 +436,7 @@ val reverse(val in); val append2(val list1, val list2); val nappend2(val list1, val list2); val appendv(val lists); +val nconcv(val lists); val sub_list(val list, val from, val to); val replace_list(val list, val items, val from, val to); val lazy_appendv(val lists); diff --git a/txr.1 b/txr.1 index e8da4242..7fda0ce7 100644 --- a/txr.1 +++ b/txr.1 @@ -7331,13 +7331,14 @@ Examples: (second '(1 2)) -> 2 (third '(1 2 . 3)) -> **error** -.SS Functions append and append* +.SS Functions append, nconc and append* .TP Syntax: -(append [* ]) -(append* [* ]) + (append [* ]) + (nconc [* ]) + (append* [* ]) .TP Description: @@ -7357,6 +7358,10 @@ Thus, if argument N is also a list, it is catenated onto the resulting list, but without being copied. Argument N may be an atom other than nil; in that case append produces an improper list. +The nconc function works like append, but avoids consing. It destructively +manipulates (that is to say, mutates) incoming lists to catenate them, and so +must be used with care. + The append* function works like append, but returns a lazy list which produces the catenation of the lists on demand. If some of the arguments are themselves lazy lists which are infinite, then append* can return immediately, -- cgit v1.2.3