summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2023-11-08 21:06:57 -0800
committerKaz Kylheku <kaz@kylheku.com>2023-11-08 21:06:57 -0800
commit7215b52357ee6cff03ea6c52a2c58f4f21f05add (patch)
treec88be5cc7807a8afc8d11289aa3cf0f089bc5cc9
parentf6ce49bf236f58f6d9c84428c4081ebe2620a9c4 (diff)
downloadtxr-7215b52357ee6cff03ea6c52a2c58f4f21f05add.tar.gz
txr-7215b52357ee6cff03ea6c52a2c58f4f21f05add.tar.bz2
txr-7215b52357ee6cff03ea6c52a2c58f4f21f05add.zip
New macro: tap.
* autoload.c (op_set_entries): Add tap symbol as autoload trigger for op module. * stdlib/op.tl (tap): New macro. * tests/012/op.tl: New test. * txr.1: Documented.
-rw-r--r--autoload.c2
-rw-r--r--stdlib/op.tl3
-rw-r--r--tests/012/op.tl12
-rw-r--r--txr.166
4 files changed, 82 insertions, 1 deletions
diff --git a/autoload.c b/autoload.c
index a4a6ff28..2b2b8f27 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("opf"), lit("lopf"), lit("flow"), lit("lflow"),
+ lit("opf"), lit("lopf"), lit("flow"), lit("lflow"), lit("tap"),
nil
};
autoload_set(al_fun, name, fun);
diff --git a/stdlib/op.tl b/stdlib/op.tl
index 79786f20..6c3966b1 100644
--- a/stdlib/op.tl
+++ b/stdlib/op.tl
@@ -276,3 +276,6 @@
(defmacro lflow (val . opip-args)
^(call (lopip ,*opip-args) ,val))
+
+(defmacro tap (. args)
+ ^(prog1 @1 ,args))
diff --git a/tests/012/op.tl b/tests/012/op.tl
index 1652b3c8..47f1f80d 100644
--- a/tests/012/op.tl
+++ b/tests/012/op.tl
@@ -113,3 +113,15 @@
(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))
+
+(test
+ (let ((x 0) (y 0))
+ (list (flow x
+ (+ 2)
+ (tap inc y @1)
+ (* 4)
+ (tap inc y @1)
+ (+ 5)
+ (tap inc y @1))
+ y))
+ (13 23))
diff --git a/txr.1 b/txr.1
index 31b2644f..12cbf370 100644
--- a/txr.1
+++ b/txr.1
@@ -59934,6 +59934,72 @@ and the expression
returns a function similar to
.codn "(lambda (. rest) 42)" .
+.coNP Macro @ tap
+.synb
+.mets (tap << arg +)
+.syne
+.desc
+The
+.code tap
+macro is intended for use in conjunction with
+.codn opip ,
+.code flow
+and other macros in that family. It is a short-hand for writing a pipeline
+element which performs a side-effecting operation, but unconditionally returns
+the original input value.
+
+The exact expansion of
+.code tap
+is unspecified, but the following equivalence indicates a possible
+expansion strategy:
+
+.verb
+ (tap ...) <--> (prog1 @1 (...))
+.brev
+
+Assuming that expansion strategy, the expression
+.code "(tap put-line `foo: @1`)"
+would expand to
+.codn "(prog1 @1 (put-line `foo: @1`))" .
+
+Note:
+.codn tap ,
+in addition to being useful for inserting necessary
+side effects into pipelines, is also
+useful for inserting temporary debug print forms. For that purpose, inserting
+the `prinl` function is often enough:
+
+.verb
+ (flow 10 (+ 2) print (* 4))
+.brev
+
+Here, the pipeline will calculate
+.code "(* 4 (+ 2 10))"
+with the side effect of the value of
+.code "(+ 2 10)"
+being printed. With
+.codn tap ,
+the output can be customized, allowing multiple output
+points to be distinguished.
+
+.verb
+ (flow 10
+ (tap put-line `input: @1`)
+ (+ 2)
+ (tap put-line `+ 2: @1`)
+ (* 4)
+ (tap put-line `* 4: @1`))
+ -> 48
+.brev
+
+Output produced:
+
+.verb
+ input: 10
+ + 2: 12
+ * 4: 48
+.brev
+
.coNP Function @ dup
.synb
.mets (dup << func )