summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2014-06-19 21:43:45 -0700
committerKaz Kylheku <kaz@kylheku.com>2014-06-19 21:43:45 -0700
commitd8e75887b3d2bc103bd66238d250a596eae83092 (patch)
treee8ef083bc3b9f2caa4f661a81bcf0b2ed6da245a
parentce943667b2aabb2821a0d1f61025ace9f1c146dc (diff)
downloadtxr-d8e75887b3d2bc103bd66238d250a596eae83092.tar.gz
txr-d8e75887b3d2bc103bd66238d250a596eae83092.tar.bz2
txr-d8e75887b3d2bc103bd66238d250a596eae83092.zip
* eval.c (identity_s): New global variable.
(me_ret, tf, nilf, do_retf, retf): New static functions. (eval_init): Initialize identity_s, and use it for registration of identity. Register ret macro, and the retf, tf and nilf functions. * txr.1: Documentation for ret, retf, tf and nilf.
-rw-r--r--ChangeLog10
-rw-r--r--eval.c37
-rw-r--r--txr.182
3 files changed, 127 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index f92dd991..262fed90 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
2014-06-19 Kaz Kylheku <kaz@kylheku.com>
+ * eval.c (identity_s): New global variable.
+ (me_ret, tf, nilf, do_retf, retf): New static functions.
+ (eval_init): Initialize identity_s, and use it for registration
+ of identity. Register ret macro, and the retf, tf and nilf
+ functions.
+
+ * txr.1: Documentation for ret, retf, tf and nilf.
+
+2014-06-19 Kaz Kylheku <kaz@kylheku.com>
+
Bugfix: dwim operator contradicts the documentation
and intended design.
diff --git a/eval.c b/eval.c
index ed3f70b7..aa33a6d2 100644
--- a/eval.c
+++ b/eval.c
@@ -79,7 +79,7 @@ val append_each_s, append_each_star_s;
val dohash_s;
val uw_protect_s, return_s, return_from_s;
val list_s, append_s, apply_s, gen_s, gun_s, generate_s, rest_s, plus_s;
-val promise_s, op_s;
+val promise_s, op_s, identity_s;
val hash_lit_s, hash_construct_s;
val vector_lit_s, vector_list_s;
val macro_time_s, with_saved_vars_s, macrolet_s;
@@ -2377,6 +2377,11 @@ static val me_ap(val form, val menv)
list(apply_s, cons(op_s, rest(form)), args, nao), nao);
}
+static val me_ret(val form, val menv)
+{
+ return cons(op_s, cons(identity_s, rest(form)));
+}
+
static val expand_catch_clause(val form, val menv)
{
val sym = first(form);
@@ -3072,6 +3077,29 @@ static val not_null(val obj)
return if3(nilp(obj), nil, t);
}
+static val tf(val args)
+{
+ (void) args;
+ return t;
+}
+
+static val nilf(val args)
+{
+ (void) args;
+ return nil;
+}
+
+static val do_retf(val ret, val args)
+{
+ (void) args;
+ return ret;
+}
+
+static val retf(val ret)
+{
+ return func_f0v(ret, do_retf);
+}
+
static val prinl(val obj, val stream)
{
val ret = obj_print(obj, stream);
@@ -3144,6 +3172,7 @@ void eval_init(void)
promise_s = intern(lit("promise"), system_package);
op_s = intern(lit("op"), user_package);
do_s = intern(lit("do"), user_package);
+ identity_s = intern(lit("identity"), user_package);
rest_s = intern(lit("rest"), user_package);
hash_lit_s = intern(lit("hash-construct"), system_package);
hash_construct_s = intern(lit("hash-construct"), user_package);
@@ -3212,6 +3241,7 @@ void eval_init(void)
reg_mac(op_s, me_op);
reg_mac(do_s, me_op);
reg_mac(intern(lit("ap"), user_package), me_ap);
+ reg_mac(intern(lit("ret"), user_package), me_ret);
reg_mac(qquote_s, me_qquote);
reg_mac(sys_qquote_s, me_qquote);
reg_mac(intern(lit("pprof"), user_package), me_pprof);
@@ -3236,7 +3266,7 @@ void eval_init(void)
reg_fun(intern(lit("append*"), user_package), func_n0v(lazy_appendv));
reg_fun(list_s, list_f);
reg_fun(intern(lit("list*"), user_package), func_n0v(list_star_intrinsic));
- reg_fun(intern(lit("identity"), user_package), identity_f);
+ reg_fun(identity_s, identity_f);
reg_fun(intern(lit("typeof"), user_package), func_n1(typeof));
reg_fun(intern(lit("atom"), user_package), func_n1(atom));
@@ -3421,6 +3451,9 @@ void eval_init(void)
reg_fun(intern(lit("if"), user_package), func_n3o(if_fun, 2));
reg_fun(intern(lit("or"), user_package), func_n0v(or_fun));
reg_fun(intern(lit("and"), user_package), func_n0v(and_fun));
+ reg_fun(intern(lit("retf"), user_package), func_n1(retf));
+ reg_fun(intern(lit("tf"), user_package), func_n0v(tf));
+ reg_fun(intern(lit("nilf"), user_package), func_n0v(nilf));
reg_fun(intern(lit("print"), user_package), func_n2o(obj_print, 1));
reg_fun(intern(lit("pprint"), user_package), func_n2o(obj_pprint, 1));
diff --git a/txr.1 b/txr.1
index 8389f9ab..7d443afb 100644
--- a/txr.1
+++ b/txr.1
@@ -11957,6 +11957,34 @@ except that the symbol args is to be understood as a generated symbol (gensym).
The ap macro nests properly with op and do, in any combination, in regard
to the @@n notation.
+.SS Macro ret
+
+.TP
+Syntax:
+
+ (ret <form>)
+
+.TP
+Description:
+
+The ret macro's argument is treated similarly to the arguments of the op
+operator, except that the first form of the op operator denotes
+a function to be called where as the one and only argument form of the
+ret operator denotes a value.
+
+The ret macro produces a function which takes any number of arguments,
+and returns the value specified by <form>.
+
+The following equivalence holds:
+
+ (ret x) <--> (op identity x)
+
+The expression (ret @2) returns a function similar to
+(lambda (x y . z) y).
+
+The expression (ret 42) returns a function similar to
+(lambda (. rest) 42).
+
.SS Function chain
.TP
@@ -12075,6 +12103,60 @@ The iffi function defaults to the identity function when <else-func> is
omitted or nil, and therefore is useful in situations when one value is to be
replaced with another one when the condition is true, otherwise left alone.
+.SH Functions tf and nilf
+
+.TP
+Syntax:
+
+ (tf <arg>*)
+ (nilf <arg>*)
+
+.TP
+Description:
+
+The tf and nilf functions take zero or more arguments, and ignore them.
+The tf function returns t, and the nilf function returns nil.
+
+.TP
+Example:
+
+ ;; tf and nilf are useful when functions are chained together.
+ ;; test whether (trunc n 2) is odd.
+
+ (defun trunc-n-2-odd (n)
+ [[chain (op trunc @1 2) [iff oddp tf nilf]] n)
+
+In this example, two functions are chained together, and n is passed
+through the chain such that it is first divided by two via the
+function denoted by (op trunc @1 2) and then the result is passed into the
+function denoted by [iff oddp tf nilf]. The iff function passes its
+argument into oddp, and if oddp yields true, it passes the same argument to tf.
+Here tf proves its utility by ignoring that value and returning t.
+If the argument (the divided value) passed into iff is even, then
+iff passes it into the nilf function, which ignores the value and
+returns nil.
+
+.SH Function retf
+
+.TP
+Syntax:
+
+ (retf <value>)
+
+.TP
+Description:
+
+The retf function returns a function. That function can take zero or
+more arguments. When called, it ignores its arguments and returns <value>.
+
+See also: the ret macro.
+
+.TP
+Example:
+
+ ;; the function returned by (retf 42) ignores 1 2 3 and returns 42.
+ (call (retf 42) 1 2 3) -> 42
+
.SH INPUT AND OUTPUT (STREAMS)
TXR Lisp supports input and output streams of various kinds, with