pair = cons(1, 2) # => Proc
pair.call(:car) == car(pair) == 1
pair.call(:cdr) == cdr(pair) == 2
list = make_list(1, 2, 3, 4, 5) # => Proc
list_to_string(list) # => "(1, 2, 3, 4, 5)"
length(list) # => 5
list2 = make_list(6, 7)
list3 = append(list1, list2) # => Proc
list_to_string(list3) # => "(1, 2, 3, 4, 5, 6, 7)"
list4 = map(list) { |e| e**2 } # => Proc
list_to_string(list4) # => "(1, 4, 9, 16, 25, 36, 49)"
list5 = filter(list) { |e| e.odd? } # => Proc
list_to_string(list5) # => "(1, 3, 5)"
reduce(list, 0) { |a, e| a + e } # => 21tree = make_list(1, 2, make_list(3, 4), make_list(5, 6, make_list(7, 8))) # => Proc
list_to_string(tree) # => "(1, 2, (3, 4), (5, 6, (7, 8)))"
  root of a sub-tree
         |
         |  node of a sub-tree
         |  |    
         |  |   root of a sub-tree
         |  |    |
         |  |    |  nodes of a sub-tree
         |  |    |  |  |
         v  v    v  v  v
"(1, 2, (3, 4), (5, 6, (7, 8)))"
  ^  ^  ^       ^
  |  |  |       |
root  \  \     /
       \  \   /
        \  \ /
         nodes 
          (1)
      _____|_____
    /      |      \
  (2)     (3)     (5)
           |      _|_
          (4)   /     \
              (6)     (7)
                       |
                      (8)