Documentation
Not logged in

Copyright (C) 2009-2010, Trevor Davel <twylite AT crypt DOT co DOT za>
See the file "LICENSE.txt" (Tcl/Tk License) for information on usage and redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.


control::functional 1.x

Overview

Enhanced support for functional programming in Tcl, with implementations of some common higher-order functions.

This module builds on existing Tcl functions and practices (such as apply from TIP #194, and using command prefixes for callbacks).

Related documents

Tcl definition of a 'function'

Higher-order functions take a function as input and/or return a function as output. To work with higher-order functions in Tcl we need an understanding of what 'a function' is and how to work with one.

A 'function' in Tcl is defined here as a command prefix:

A function may thus be built as [list cmd arg1 arg2 ...] for any Tcl command cmd, and any function may be curried by lappending one or more args to the function.

A function (command prefix) may be invoked:

Higher-order functions

General

foldl cmdprefix ?initial? list

A left fold over a list (with or without initial value), returning the output of the last invocation of cmdprefix.
The input function is called with two arguments: cmdprefix accum input. The accumulator is the output of the previous invocation of cmdprefix (or the initial value, or the first element of the input list), and input is the next element of the input list. The function must return a new value for the accumulator.
A left fold of the operation "-" (subtract) over the list {1 2 3 4 5} is equivalent to (((1 - 2) - 3) - 4) - 5, with the result -13.

foldr cmdprefix ?initial? list

A right fold over a list (with or without initial value).
The input function is called with two arguments: cmdprefix input accum. The accumulator is the output of the previous invocation of cmdprefix (or the initial value, or the last element of the input list), and input is the next element of the input list (from the right). The function must return a new value for the accumulator.
A right fold of the operation "-" (subtract) over the list {1 2 3 4 5} is equivalent to 1 - (2 - (3 - (4 - 5))), with the result 3.

filter predicate list

A filter over a list, returning a list of elements from the input set that match a predicate.
predicate is a cmdprefix that returns a boolean, and is called with a single argument: cmdprefix input. input is an element from the input list. If the function returns true then the element input will be included in the output list.
filter is not order-preserving: the order of elements in the output list may not match their order in the input list. In addition filter may process its input list in any order. Any appearance of order preservation is strictly a consequence of the implementation.
A filter of the operator "> 2" (greater than 2) over the list {5 2 3 4 1} will produce {5 3 4} (or {3 4 5}, etc.).

map ?rule? cmdprefix list1 ?list2 ... listN?

A variadic map over N lists, returning a single list. For each index i in the input list(s) (taken in parallel), cmdprefix will be invoked with N arguments (the i'th element of each input list). The result of invoking cmdprefix becomes the i'th element of the output list.
rule is required for 2 or more lists, and indicates how to handle lists of different lengths:
The input function is called with N arguments, as explained above: cmdprefix elem1 ?elem2 ... elemN?. The returned value becomes an element in the output list.
map is order preserving: the i'th element of the output list corresponds to cmdprefix executed over the i'th element(s) of the input list(s). However, map may process its input list(s) in any order. Any appearance of a predictable order of iteration over the input list(s) is strictly a consequence of the implementation.

Helpers

curry cmdprefix arg ?arg ...?

Returns a function created by the partial application of arguments to cmdprefix. This is known as currying.

lambda arglist body ?arg ...?

Constructs and returns a lambda: an anonymous proc that executes in the namespace in which it was constructed. A lambda is a command prefix (and thus a function).
arglist and body are as for proc. Additional arguments (if present) curry the lambda.

lambdaexpr arglist expr ?arg ...?

Constructs and returns a lambda, the body of which is evaluated as an expression (as if by expr). The lambda executes in the namespace in which it was constructed.
arglist is as for proc, and expr is evaluated with expr. Additional arguments (if present) curry the lambda.

compose f g ...

Compose two functions z=f(y) and y=g(x), returning a new function h such that z = h(x) = f(g(x)).
It is possible to compose more than two functions by calling compose with extra arguments. The functions are applied right-to-left, so the function given as the last argument is executed first, and its output is used as input to the second to last argument, and so on.
f and g are both cmdprefixes.

range ?from? to ?step?

Constructs and returns a list of integers ranging from from (default 0) to to (inclusive) in increments of step (default 1). All input arguments are numbers.