This is an incomplete set of tests that exercise parts of the
functional PHP extension. With any luck, they'll all work :)

id: Passed.
Lambda function composition: Passed.
Using a lambda functions to express more lambda functions: Passed.
range creation: Passed.
map(id()): Passed.
map($times2, $vector): Passed.
map() preserves keys: Passed.
compose(): Passed.
grep(): Passed.
concat($letters): Passed.
concat($letters, "-"): Passed.
concat(array(), "foo"): Passed.
concat(array(""), "foo"): Passed.
reduce(max, hash): Passed.
reduce(min, hash, current(hash)): Passed.
freduce("min", ...): Passed.
Any.: Passed.
Any.: Passed.
transpose($matrix) with hash for outside: Passed.
fx('expression in $x') shortcut: Passed.
reverse: Passed.
flatten: Passed.
asprintf: Passed.
celcius to farenheight 1: Passed.
celcius to farenheight 2: Passed.
celcius to farenheight 3: Passed.


If you got here with no warnings, then all tests passed.
There should probably be more tests, though. Here are all the functions:

function def_fun($name, $args, $code) {
function lam($args, $expr) {
function gensym() {
function partial($func) {
function rPartial($func, $skip=1) {
function _FP_arg($id) {
function _FP_arglist($count) {
function _FP_argQuote($arg) {
function id($x) {
function not($x) {
function _FP_Guard($guards) {
function metameta($name, $args, $result, $guards, $body) {
function metafold($name, $args, $imperative, $init="", $guards="") {
function metamap($name, $args, $imperative, $guards="") {
function metascan($name, $args, $imperative, $default) {
function collect($arr) {
function concat($arr, $sep="") {
function freduce($func, $arr) {
function transpose($matrix) {
function first($func, $arr) {
function first_key($func, $arr) {
function unroll(&$object, $method, $test='id') {
function cons($val, $list) {
function cons_hash($key, $val, $hash) {
function pair($keys, $values) {
function fx($body) {
function set_difference($a, $b) {
function pr($x) {
function qw($x) {
function fv($expression) {
function _dot_($f, $g) {	// as in function compostion by dot operator: f.g(x) == f(g(x))
function _not_($func) {
function _and_($f, $g) {
function _or_($f, $g) {

Also, now that I've started down the path of metafunctions, it's worthwhile
to list the definitions concisely here:

metamap('map', '$func, $in', '$out[$k] = $func($v)', array('!is_array($in)' => 'array()'));
metamap('asprintf', '$fmt, $in', '$out[$k] = sprintf($fmt, $v)', array('!is_array($in)' => 'array()'));
metamap('map_hash', '$func, $in', '$out[$k] = $func($k, $v)', array('!is_array($in)' => 'array()'));
metamap('grep', '$func, $in', 'if ($func($v)) $out[$k] = $v');
metamap('reject', '$func, $in', 'if (!$func($v)) $out[$k] = $v');
metafold('sum', '$in', '$a += $v', '$a = 0');
metafold('reduce', '$func, $in, $a=""', '$a = $func($a, $v)');
metafold('reduce_hash', '$func, $in, $a=""', '$a = $func($a, $k, $v)');
metamap('map_apply', '$func, $in', '$out[$k] = apply($func, $v)');
metascan('any', '$func, $in', 'if ($func($v)) return TRUE', 'FALSE');
metascan('all', '$func, $in', 'if (!$func($v)) return FALSE', 'TRUE');
metascan('none', '$func, $in', 'if ($func($v)) return FALSE', 'TRUE');
metamap('inject', '&$object, $method, $in', '$out[$k] = $object->$method($v)');
metamap('inject_hash', '&$object, $method, $in', '$out[$k] = $object->$method($k, $v)');
metamap('compose', '$f, $in', '$out[$k] = $f[$v]');
metamap('reverse', '$in', 'array_unshift($out, $v)');
metamap('flatten', '$in', '$out = array_merge($out, $v)');
metamap('histogram', '$in', '$out[$v]++');