summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--autoload.c2
-rw-r--r--stdlib/op.tl6
-rw-r--r--tests/012/op.tl4
-rw-r--r--txr.178
4 files changed, 89 insertions, 1 deletions
diff --git a/autoload.c b/autoload.c
index b251ae9e..81641d4e 100644
--- a/autoload.c
+++ b/autoload.c
@@ -712,7 +712,7 @@ static val op_set_entries(val fun)
lit("op"), lit("do"), lit("lop"), lit("ldo"), lit("ap"), lit("ip"),
lit("ado"), lit("ido"), lit("ret"), lit("aret"),
lit("opip"), lit("oand"), lit("lopip"), lit("loand"),
- lit("flow"), lit("lflow"),
+ lit("opf"), lit("lopf"), lit("flow"), lit("lflow"),
nil
};
autoload_set(al_fun, name, fun);
diff --git a/stdlib/op.tl b/stdlib/op.tl
index 4b5b0311..79786f20 100644
--- a/stdlib/op.tl
+++ b/stdlib/op.tl
@@ -265,6 +265,12 @@
(defmacro loand (:env e . clauses)
^[chand ,*(sys:opip-expand e 'lop 'ldo clauses)])
+(defmacro opf (:env e fun . clauses)
+ ^[,fun ,*(sys:opip-expand e 'op 'do clauses)])
+
+(defmacro lopf (:env e fun . clauses)
+ ^[,fun ,*(sys:opip-expand e 'lop 'ldo clauses)])
+
(defmacro flow (val . opip-args)
^(call (opip ,*opip-args) ,val))
diff --git a/tests/012/op.tl b/tests/012/op.tl
index 4e0a8d46..1652b3c8 100644
--- a/tests/012/op.tl
+++ b/tests/012/op.tl
@@ -109,3 +109,7 @@
(mtest
(lflow 10 (- 1) (- 1)) 8
(lflow 10 (op - 100) (+ 1)) 91)
+
+(mtest
+ (remove-if (opf orf (< 10) (> 5)) (range 0 20)) (5 6 7 8 9 10)
+ (remove-if (lopf orf (> 10) (< 5)) (range 0 20)) (5 6 7 8 9 10))
diff --git a/txr.1 b/txr.1
index 5c381ea2..a89ef396 100644
--- a/txr.1
+++ b/txr.1
@@ -59326,6 +59326,84 @@ as well as, implicitly, the value
.code @1
coming from the previous element,
+.coNP Macros @ opf and @ lopf
+.synb
+.mets (opf < function << clause *)
+.mets (lopf < function << clause *)
+.syne
+.desc
+The
+.code opf
+and
+.code lopf
+function make available the
+.codn opip -style
+functional arguments in conjunction with an arbitrary
+.metn function .
+
+The
+.meta clause
+arguments of
+.code opf
+and
+.code lopf
+are processed exactly like those of
+.code opip
+and
+.codn lopip .
+
+The syntax
+.verb
+ (opf f c1 c2 c3 ...)
+.brev
+is converted into a function call of the form:
+.verb
+ [f {c1} {c2} {c3} ...]
+.brev
+where every argument
+.code {cN}
+is converted to a form denoting a function, in exactly the same manner
+as the arguments of
+.codn opip .
+The same remarks apply to code
+.code lopf
+in relation to
+.codn lopip .
+
+Thus, it is possible to express
+.code opip
+using
+.code opf
+by choosing
+.code chain
+as the
+.meta function
+argument, according to this equivalence:
+
+.verb
+ (opip c1 c2 c3 ...) <--> (opf chain c1 c2 c3 ...)
+.brev
+
+.TP* Example:
+
+.verb
+ ;; Remove values greater than 10 or less than five from list
+ (remove-if (lopf orf (> 10) (< 5)) (range 0 20)) -> (5 6 7 8 9 10))
+
+ ;; Note: could be expressed as
+ (remove-if (orf (lop > 10) (lop < 5)) (range 0 20))
+.brev
+
+As the example shows, the
+.code opf
+and
+.code lopf
+macros provide a way to avoid repeating the
+.code op
+and
+.code lop
+syntax in every argument of a functional combinator of a function.
+
.coNP Macros @ flow and @ lflow
.synb
.mets (flow < form << opip-arg *)