Using Plumb

Plumb is a simple language for defining simple functions. This page describes Plumb’s syntax and semantics, wherever they differ from those of the host language.

Declaring Functions

Plumb exists to make function definition easy: just use [square brackets]. Functions will return their argument by default, so an empty pair of brackets is an identity function: []

$id = plumb([]);
echo "Called {$id(__FUNCTION__)} at  {$id(time())}";
$compose_all = function() {
                 return array_reduce(func_get_args(),
id = plumb([])
for handler in [str, str, id, repr]

Returning Values

To return a value explicitly, just write it inside the brackets. Plumb will try interpreting the expression according to the rules on this page; if it fails, the host language’s semantics will be used. This makes it trivial to write thunks:

var func = plumb(['hello world!']);
public function testInvalidThrowsException() {
  try {
         ->handleWith(plumb([false]), rand());
    $this->fail('Threw exception');
  } catch (InvalidException $e) {}

Function Arguments

Every Plumb function takes a single argument. Multi-argument functions can be simulated using currying.

Plumb doesn’t give arguments absolute names when they’re introduced. Instead, arguments are referred to numerically, based on their position relative to the reference. For example:

This naming scheme is known as de Bruijn indexing. Scope is lexical: references are looked up relative to where they’re defined, not where they’re used.

If there is no argument at a given position, for example plumb([1]), the resulting function will cause a (host-specific) error.

Notice that [0] is an identity function, just like [].

$f = plumb([0]);

$f("baz") === "baz";
f = plumb([1])

f("baz") == Error
f = plumb([[0]]);

f("baz", "quux") == "quux";
$f = plumb([[1]])

$f("baz", "quux") === "baz"

Calling Functions

We can call a function using the infix “,” operator, with the function on the left and the argument on the right. This makes it easy to delay function calls, the second half of laziness:

$count = plumb(["strlen" , "baz"]);

$count(null) === 3;
count = plumb([len , "baz"])

count(None) == 3

Chaining Function Calls

Plumb functions are unary, so it’s easy to chain function calls. The comma operator associates to the left, so we can imagine that:

0 , 1 , 2 , 3

Is equivalent to:

((0 , 1) , 2) , 3

Grouping Syntax

Chained commas cannot implement right-associative nesting patterns, like:

0 , (1 , 2)

To define these, Plumb provides grouping syntax, which is equivalent to writing the parentheses above. We use the name “grouping syntax” since some host languages don’t allow us to use parentheses in this way. For example, the PHP implementation uses __( instead of an opening parenthesis.

That’s It!

Plumb implementations should conform to the behaviour described here; everything else may vary from host to host.

If you have any ideas for improving Plumb, let me know!