For Development HEAD DRAFTSearch (procedure/syntax/module):

11.48 srfi.197 - Pipeline operators

Module: srfi.197

This module provides a set of macros to compose multiple operations. It is similar to Clojure’s “threading macro”.

When you’re passing a result of some procedure to another procedure and so on, sometimes you get a deeply nested expression:

(g (f (e (d (c (b (a arg)))))))

In Gauche, you can also write the above expression with $ macro (see Making procedures):

($ g $ f $ e $ d $ c $ b $ a arg)

Deep nesting is avoided, but it’s still right-to-left, and the placement of argument to receive the previous result is limited to the last position.

With chain macro in this module, you can write it from left to right:

(chain (a arg) (b _) (c _) (d _) (e _) (f _) (g _))

The _ in the second expressions and after indicates the place where previous result is passed. It is conceptually expanded to the following:

(let* ((tmp (a arg))
       (tmp (b tmp))
       (tmp (c tmp))
       (tmp (d tmp))
       (tmp (e tmp)))
  (g tmp))

Because the placeholder is explicit, you can pass additional arguments:

(chain x (y a _) (z _ b))
 ≡
 (let* ((tmp x)
        (tmp (y a tmp)))
   (z tmp b))

Or even use multiple values:

(chain mv-expr (f _ _) (g _ _))
 ≡
 (let*-values (((tmp1 tmp2) mv-expr)
               ((tmp1 tmp2) (f tmp1 tmp2)))
   (g tmp1 tmp2))
Macro: chain initial-value [placeholder [ellipsis]] step …

[SRFI-197]{srfi.197} The optional placeholder and ellipsis are, if given, literal symbols. It replaces the default placeholder and ellipsis symbols, _ and ..., respectively.

Each step is (datum …), where each datum must be either an expression, placeholder symbol, or the ellipsis symbol. The ellipsis symbol must appear in the last position, if any, and must immediately follow the placeholder symbol.

Conceptually, each step becomes a procedure that takes as many arguments as the placeholders. If the step ends with ellipsis symbol, the last placeholder works as the “rest” arguments.

If a step expects more than one value, the previous step or initial-value is expected to yield that many values.

(chain expr (f _ a _ ...))
  ≡
  (let*-values (((tmp1 . tmp2) expr))
    (apply f tmp1 a tmp2))
Macro: chain-and initial-value [placeholder] step …

[SRFI-197]{srfi.197} A variant of chain that stops and returns #f immedialy when the intermediate result becomes #f.

The initial-value is an expression that yields one value. The placeholder is a literal symbol to be used as the placeholder in step; if omitted, _ is used.

Unlike chain, a step can only contain zero or one placeholder symbol. If step doesn’t contain placeholder symbol, the previous step’s result isn’t passed, but it is still checked if it’s #f.

Macro: chain-when initial-value [placeholder] ([guard] step) …

[SRFI-197]{srfi.197} A variant of chain where you can select whether each step is applied or skipped.

Each step can have at most one placeholder symbol, just as chain-and.

Each guard is an expression. For each step, guard is evaluated, and if it yields a true value, the previous result is passed to the placeholder in the corresponding step. If guard yields #f, however, step is skipped and the previous value is passed through to the next step.

(chain-when expr ((p? x) (f _)) ((q? x) (g _)))
 ≡
 (let* ([tmp expr]
        [tmp (if (p? x) (f tmp) tmp)])
   (if (q? x) (g tmp) tmp))
Macro: chain-lambda [placeholder [ellipsis]] step …

[SRFI-197]{srfi.197}

(chain-lambda step ...)
  ≡ (lambda args (chain (apply values args) step ...))
Macro: nest [placeholder] step … initial-value

[SRFI-197]{srfi.197} Similar to chain, except the order of steps is right-to-left.

Each step must have exactly one placeholder symbol, for this macro simply nests the steps:

(nest (f a _) (g _ b) (h _) expr)
 ≡ (f a (g (h expr) b))
Macro: nest-reverse initial-value [placeholder] step …

[SRFI-197]{srfi.197} Similar to nest except the nesting is in reverse order.

Each step must have exactly one placeholder symbol, for this macro simply nests the steps:

(nest expr (h _) (g _ b) (f a _))
 ≡ (f a (g (h expr) b))


For Development HEAD DRAFTSearch (procedure/syntax/module):
DRAFT