diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2023-08-23 19:59:38 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2023-08-23 19:59:38 -0700 |
commit | d6e02ceea56644dea341e64a1f46f8fbe43ca6b5 (patch) | |
tree | de7345d67de93291489fae1f726e73991b057cf9 | |
parent | 33cd4b10aca2e097e1d03fe4d5ee725f4f207131 (diff) | |
download | txr-d6e02ceea56644dea341e64a1f46f8fbe43ca6b5.tar.gz txr-d6e02ceea56644dea341e64a1f46f8fbe43ca6b5.tar.bz2 txr-d6e02ceea56644dea341e64a1f46f8fbe43ca6b5.zip |
New macros opf and lopf.
These remove repetitive (op ...) syntax from
the arguments of functional combinators.
* stdlib/opt.tl (opf, lopf): New macros.
* autoload.c (op_set_entries): Register opf and
lopf as autoload triggers.
* tests/012/op.tl: New tests.
* txr.1: Documented.
-rw-r--r-- | autoload.c | 2 | ||||
-rw-r--r-- | stdlib/op.tl | 6 | ||||
-rw-r--r-- | tests/012/op.tl | 4 | ||||
-rw-r--r-- | txr.1 | 78 |
4 files changed, 89 insertions, 1 deletions
@@ -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)) @@ -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 *) |