var p = pair(1, 2);
head(p)
tail(p)
pair(1,
     pair(2,
          pair(3,
               pair(4, []))))
pair(1,
     pair(2,
          pair(3,
               pair(4, []))))
list(1, 2, 3, 4)
[1,[2,[3,[4,[]]]]]
is_empty_list([])
is_empty_list( list(1,2,3) )
function length(xs) {
    if (is_empty_list(xs)) {
	return 0;
    } else {
	return 1 + length(tail(xs));
    }
}
function length_iter(xs) {
    function len(xs, counted_so_far) {
        if (is_empty_list(xs)) {
            return counted_so_far;
        } else {
            return len(tail(xs), counted_so_far + 1);
        }
    }
    return len(xs, 0);
}
function append(xs, ys) {
    if (is_empty_list(xs)) {
	return ys;
    } else {
	return pair(head(xs),
		    append(tail(xs), ys));
    }
}
var list1 = pair( list(1,2,3), list(4,5,6) );
var list2 = append( list(1,2,3), list(4,5,6) );
function reverse(lst) {
    if (is_empty_list(lst)) {
        return [];
    } else {
        return pair(reverse(tail(lst)), 
                    head(lst));
    }
}
function reverse(lst) {
    if (is_empty_list(lst)) {
        return [];
    } else {
        return append(reverse(tail(lst)), 
                      list(head(lst)));
    }
}
function reverse(xs) {
    function rev(original, reversed) {
	if (is_empty_list(original)) {
	    return reversed;
	} else {
	    return rev(tail(original), 
		       pair(head(original), 
                            reversed));
	}
    }
    return rev(xs,[]);
}
function scale_list(items, factor) {
    if (is_empty_list(items)) {
        return [];
    } else {
        return pair(factor * head(items),
                    scale_list(tail(items), 
                               factor)
                   );
    }
}
function square_list(items) {
    if (is_empty_list(items)) {
        return [];
    } else {
        return pair(square(head(items)),
                    square_list(tail(items))
                   );
    }
}
map( square, list(1,2,3) );
function scale_list(items, factor) {
    return map(function(x) { return factor * x; }, 
               items);
}
function map(fun, items) {
    if (is_empty_list(items)) {
        return [];
    } else {
        return pair(fun(head(items)),
                    map(fun, tail(items)));
    }
}
var tree = pair(list(1,2), list(3, 4));
length(tree)?
var tree = pair(list(1,2), list(3, 4));
count_leaves( tree )?
function count_leaves(tree) {
    function count_leaves_in_list(xs) {
        return (is_empty_list(xs)) ? 0
               : count_leaves(head(xs)) 
                 + count_leaves_in_list(tail(xs));
    }
    if (is_list(tree)) {
        return count_leaves_in_list(tree);
    } else {
        return 1;
    }
}
var my_tree = list(1, list(2, list(3,4), 5), list(6, 7));
scale_tree(my_tree, 10)
list(10, list(20, list(30,40), 50), list(60, 70));
function scale_tree(tree, factor) {
    return map(function(sub_tree) {
                   return (is_number(sub_tree)) 
                          ? factor * sub_tree
                          : scale_tree(sub_tree,
                                       factor);
               },
               tree);
}
function scale_tree(tree, factor) {
    return map(function(sub_tree) {
                   return (! is_list(sub_tree)) 
                          ? factor * sub_tree
                          : scale_tree(sub_tree,
                                       factor);
               },
               tree);
}
function map_tree(tree, f) {
    return map(function(sub_tree) {
                   return (! is_list(sub_tree)) 
                          ? f(sub_tree)
                          : map_tree(sub_tree, f);
               },
               tree);
}
var big = Math.pow(2, 53);
big === big + 1;
equal( list( list(1,2,3), list(4,5)),
       list( list(1,2,3), list(4,5)) )    => true
equal( list( list(1,2,3), list(4,5)),
       list( list(1,2,8), list(4,5)) )    => false
function copy(xs) {
    return map(function(x) { return x; }, xs);
}
var squares = build_list(10,square)
filter(is_even, squares)
map( square, list(1,2,3) );
accumulate(plus, 0, squares)
var squares = build_list(10, square);
var even_squares = filter(is_even, squares);
var half_even_squares 
= map(function(x) { return x / 2; },
      even_squares);
var result = accumulate(plus, 0, half_even_squares);
/
#