From 0d29bebdc195800fc416d6bea57d84140d54e7a3 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Sun, 20 Jul 2014 11:06:17 -0700 Subject: * 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. --- ChangeLog | 11 +++++++++++ eval.c | 1 + lib.c | 10 ++++++++++ lib.h | 1 + txr.1 | 35 +++++++++++++++++++++++++++++++++++ 5 files changed, 58 insertions(+) diff --git a/ChangeLog b/ChangeLog index ae8e9302..970b8825 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2014-07-20 Kaz Kylheku + + * 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 * arith.c (divi): Support one-argument form. 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 *) + +.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 -- cgit v1.2.3