summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2014-07-20 11:06:17 -0700
committerKaz Kylheku <kaz@kylheku.com>2014-07-20 11:06:17 -0700
commit0d29bebdc195800fc416d6bea57d84140d54e7a3 (patch)
tree22808d93cd773cb4158c78bcb47b23da87d55700
parent7da23010b2afbaae4dc4b8f01d1f8950e2c878be (diff)
downloadtxr-0d29bebdc195800fc416d6bea57d84140d54e7a3.tar.gz
txr-0d29bebdc195800fc416d6bea57d84140d54e7a3.tar.bz2
txr-0d29bebdc195800fc416d6bea57d84140d54e7a3.zip
* eval.c (eval_init): Register juxt as intrinsic.
* lib.c (do_juxt): New static function. (juxtv): New function. * lib.h (juxtv): Declared. * txr.1: Documented juxt.
-rw-r--r--ChangeLog11
-rw-r--r--eval.c1
-rw-r--r--lib.c10
-rw-r--r--lib.h1
-rw-r--r--txr.135
5 files changed, 58 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index ae8e9302..970b8825 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,16 @@
2014-07-20 Kaz Kylheku <kaz@kylheku.com>
+ * eval.c (eval_init): Register juxt as intrinsic.
+
+ * lib.c (do_juxt): New static function.
+ (juxtv): New function.
+
+ * lib.h (juxtv): Declared.
+
+ * txr.1: Documented juxt.
+
+2014-07-20 Kaz Kylheku <kaz@kylheku.com>
+
* arith.c (divi): Support one-argument form.
Use "/" name in error reporting, not "divi".
diff --git a/eval.c b/eval.c
index 0cd9b73d..dc344da1 100644
--- a/eval.c
+++ b/eval.c
@@ -3699,6 +3699,7 @@ void eval_init(void)
reg_fun(intern(lit("env-fbind"), user_package), func_n3(env_fbind));
reg_fun(intern(lit("env-vbind"), user_package), func_n3(env_vbind));
reg_fun(intern(lit("chain"), user_package), func_n0v(chainv));
+ reg_fun(intern(lit("juxt"), user_package), func_n0v(juxtv));
reg_fun(intern(lit("andf"), user_package), func_n0v(andv));
reg_fun(intern(lit("orf"), user_package), func_n0v(orv));
reg_fun(intern(lit("iff"), user_package), func_n3o(iff, 2));
diff --git a/lib.c b/lib.c
index 3f38ab97..9443fb88 100644
--- a/lib.c
+++ b/lib.c
@@ -4093,6 +4093,16 @@ val chainv(val funlist)
return func_f0v(nullify(funlist), do_chain);
}
+static val do_juxt(val funcs, val args)
+{
+ return mapcar(curry_123_1(func_n3(apply), args, nil), funcs);
+}
+
+val juxtv(val funlist)
+{
+ return func_f0v(nullify(funlist), do_juxt);
+}
+
static val do_and(val fun1_list, val args)
{
fun1_list = nullify(fun1_list);
diff --git a/lib.h b/lib.h
index 30931b4b..3ac0b1e4 100644
--- a/lib.h
+++ b/lib.h
@@ -691,6 +691,7 @@ val curry_123_23(val fun3, val arg1);
val curry_1234_34(val fun3, val arg1, val arg2);
val chain(val first_fun, ...);
val chainv(val funlist);
+val juxtv(val funlist);
val andf(val first_fun, ...);
val andv(val funlist);
val orf(val first_fun, ...);
diff --git a/txr.1 b/txr.1
index 5ffacc85..ca0d5529 100644
--- a/txr.1
+++ b/txr.1
@@ -12394,6 +12394,41 @@ op operator is this:
(call (chain (fun +) (lambda (x) (* 2 x))) 3 4)
+.SS Function juxt
+
+.TP
+Syntax:
+
+ (juxt <func>*)
+
+.TP
+Description:
+
+The juxt function accepts a variable number of arguments which are functions.
+It combines these into a single function which, when invoked, passes its arguments
+to each of the functions, and collects the results into a list. The results
+
+Note: the juxt function can be understood in terms of the following reference
+implementation:
+
+ (defun juxt (funcs)
+ (lambda (. args)
+ (mapcar (lambda (fun)
+ (apply fun args))
+ funcs)))
+
+.TP
+Example:
+
+ ;; separate list (1 2 3 4 5 6) into lists of evens and odds, which end up
+ ;; juxtaposed in the output list:
+
+ [(op [juxt keep-if remove-if] evenp) '(1 2 3 4 5 6)] -> ((2 4 6) (1 3 5))
+
+ ;; call several functions on 1, collecting their results:
+ [[juxt (op + 1) (op - 1) evenp sin cos] 1]'
+ -> (2 0 nil 0.841470984807897 0.54030230586814)
+
.SS Functions andf and orf
.TP