summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2014-07-29 07:27:38 -0700
committerKaz Kylheku <kaz@kylheku.com>2014-07-29 07:27:38 -0700
commit7b0cc54a306486e2ca09b7863f7330f85bf6531c (patch)
tree9c0c8036f676bb73cb68d89d1e02eaa10142c8f5
parente25ae2d57a7b7a5252d9a13441d963b7dd2b8c1a (diff)
downloadtxr-7b0cc54a306486e2ca09b7863f7330f85bf6531c.tar.gz
txr-7b0cc54a306486e2ca09b7863f7330f85bf6531c.tar.bz2
txr-7b0cc54a306486e2ca09b7863f7330f85bf6531c.zip
* eval.c (eval_init): Register nconc as intrinsic.
* lib.c (nconcv): New function. * lib.h (nconcv): Declared. * txr.1: Documented nconc.
-rw-r--r--ChangeLog10
-rw-r--r--eval.c1
-rw-r--r--lib.c12
-rw-r--r--lib.h1
-rw-r--r--txr.111
5 files changed, 32 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 2e3a0e50..ef3197ba 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
2014-07-29 Kaz Kylheku <kaz@kylheku.com>
+ * 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 <kaz@kylheku.com>
+
* lib.c (reduce_left, reduce_right): Nullify incoming sequence
argument so empty vectors and strings can be processed.
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 [<list>* <last-arg>])
-(append* [<list>* <last-arg>])
+ (append [<list>* <last-arg>])
+ (nconc [<list>* <last-arg>])
+ (append* [<list>* <last-arg>])
.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,