summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2015-01-25 16:35:34 -0800
committerKaz Kylheku <kaz@kylheku.com>2015-01-25 16:35:34 -0800
commit0515d6ee6af5f16a951f7dd61ddc3f3e2cd0e562 (patch)
tree0dd6c287ca0eef9646446fa7e65d5532a4ff826b
parent4ec024cdc9544c244cbd8b630e8f631fc05c6075 (diff)
downloadtxr-0515d6ee6af5f16a951f7dd61ddc3f3e2cd0e562.tar.gz
txr-0515d6ee6af5f16a951f7dd61ddc3f3e2cd0e562.tar.bz2
txr-0515d6ee6af5f16a951f7dd61ddc3f3e2cd0e562.zip
* eval.c (call_f): new global variable.
(do_mapf, mapf): new static functions. (eval_init): protect call_f from gc, and initialize it. re-register call function using call_f. register mapf intrinsic. * txr.1: Documented mapf.
-rw-r--r--ChangeLog10
-rw-r--r--eval.c21
-rw-r--r--txr.145
3 files changed, 74 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 5d6958b3..d8be7df6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
2015-01-25 Kaz Kylheku <kaz@kylheku.com>
+ * eval.c (call_f): New global variable.
+ (do_mapf, mapf): New static functions.
+ (eval_init): Protect call_f from gc, and initialize it.
+ Re-register call function using call_f.
+ Register mapf intrinsic.
+
+ * txr.1: Documented mapf.
+
+2015-01-25 Kaz Kylheku <kaz@kylheku.com>
+
* eval.c (eval_init): Register dupl and swap_12_21 as
the dup and flip intrinsics.
diff --git a/eval.c b/eval.c
index 4929973a..48925f79 100644
--- a/eval.c
+++ b/eval.c
@@ -89,6 +89,8 @@ val special_s, whole_k;
val last_form_evaled;
+val call_f;
+
val make_env(val vbindings, val fbindings, val up_env)
{
val env = make_obj();
@@ -3462,6 +3464,18 @@ static val callf(val func, val funlist)
return chain(juxt_fun, apf_fun, nao);
}
+static val do_mapf(val env, val args)
+{
+ cons_bind (fun, funlist, env);
+ val mapped_args = mapcarv(call_f, cons(funlist, cons(args, nil)));
+ return apply(fun, mapped_args, nil);
+}
+
+static val mapf(val fun, val funlist)
+{
+ return func_f0v(cons(fun, funlist), do_mapf);
+}
+
static val prinl(val obj, val stream)
{
val ret = obj_print(obj, stream);
@@ -3500,7 +3514,7 @@ static val merge_wrap(val seq1, val seq2, val lessfun, val keyfun)
void eval_init(void)
{
protect(&top_vb, &top_fb, &top_mb, &top_smb, &special, &dyn_env,
- &op_table, &last_form_evaled, convert(val *, 0));
+ &op_table, &last_form_evaled, &call_f, convert(val *, 0));
top_fb = make_hash(t, nil, nil);
top_vb = make_hash(t, nil, nil);
top_mb = make_hash(t, nil, nil);
@@ -3508,6 +3522,8 @@ void eval_init(void)
special = make_hash(t, nil, nil);
op_table = make_hash(nil, nil, nil);
+ call_f = func_n1v(call);
+
dwim_s = intern(lit("dwim"), user_package);
progn_s = intern(lit("progn"), user_package);
prog1_s = intern(lit("prog1"), user_package);
@@ -3709,7 +3725,7 @@ void eval_init(void)
reg_fun(intern(lit("mapdo"), user_package), func_n1v(mapdov));
reg_fun(apply_s, func_n1v(apply_intrinsic));
reg_fun(iapply_s, func_n1v(iapply));
- reg_fun(call_s, func_n1v(call));
+ reg_fun(call_s, call_f);
reg_fun(intern(lit("reduce-left"), user_package), func_n4o(reduce_left, 2));
reg_fun(intern(lit("reduce-right"), user_package), func_n4o(reduce_right, 2));
reg_fun(intern(lit("transpose"), user_package), func_n1(transpose));
@@ -3912,6 +3928,7 @@ void eval_init(void)
reg_fun(apf_s, func_n1(apf));
reg_fun(ipf_s, func_n1(ipf));
reg_fun(intern(lit("callf"), user_package), func_n1v(callf));
+ reg_fun(intern(lit("mapf"), user_package), func_n1v(mapf));
reg_fun(intern(lit("tf"), user_package), func_n0v(tf));
reg_fun(intern(lit("nilf"), user_package), func_n0v(nilf));
diff --git a/txr.1 b/txr.1
index 29e9fa7b..668a12c9 100644
--- a/txr.1
+++ b/txr.1
@@ -21477,6 +21477,51 @@ arguments:
-> ((1 1) (4 4))
.cble
+.coNP Function @ mapf
+.synb
+.mets (mapf < main-function << arg-function *)
+.syne
+.desc
+The
+.code mapf
+function returns a function which distributes its arguments
+into the
+.metn arg-function -s.
+That is to say, each successive argument of the returned
+function is associated with a successive
+.metn arg-function .
+
+Each
+.metn arg-function
+is called, passed the corresponding argument. The return
+values of these functions are then passd as arguments
+to
+.meta main function
+and the resulting value is returned.
+
+If the returned function is calle with fewer arguments than there
+are
+.metn arg-function -s,
+then only that many functions are used. Conversely, if the function is
+called with more arguments than there are
+.metn arg-function -s, then those arguments are ignored.
+
+The following equivalence holds:
+
+.cblk
+ (mapf fm f0 f1 ...) <--> (lambda (. rest)
+ [apply fm [mapcar call (list f0 f1 ...) rest]])
+.cble
+
+.TP* Example:
+
+.cblk
+ ;; Keep those pairs which are two of a kind
+
+ (keep-if [callf eql first second] '((1 1) (2 3) (4 4) (5 6)))
+ -> ((1 1) (4 4))
+.cble
+
.SS* Input and Output (Streams)
\*(TL supports input and output streams of various kinds, with
generic operations that work across the stream types.