About SICP The following Lua code is derived from the examples provided in the book:
      "Structure and Interpretation of Computer Programs, Second Edition" by Harold Abelson and Gerald Jay Sussman with Julie Sussman.
      http://mitpress.mit.edu/sicp/

SICP Chapter #01 Examples in Lua

-- 1.1.1 The Elements of Programming - Expressions
print (486)
print (137 + 349)
print (1000 - 334)
print (5 * 99)
print (10 / 5)
print (2.7 + 10)
print (21 + 35 + 12 + 7)
print (25 * 4 * 12)
print (3 * 5 + 10 - 6)
print (3 * (2 * 4 + 3 + 5) + 10 - 7 + 6)

-- 1.1.2 The Elements of Programming - Naming and the Environment
size = 2
print (size)
print (5 * size)
pi = 3.14159
radius = 10
print (pi * radius * radius)
circumference = 2 * pi * radius
print (circumference)

-- 1.1.3 The Elements of Programming - Evaluating Combinations
print ((2 + 4 * 6) * (3 + 5 + 7))

-- 1.1.4 The Elements of Programming - Compound Procedures
function square(x) return x * x end
print (square(21))
print (square(2 + 5))
print (square(square(3)))
function sum_of_squares(x, y) return square(x) + square(y) end
print (sum_of_squares(3, 4))
function f(a) return sum_of_squares(a + 1, a * 2) end
print (f(5))

-- 1.1.5 The Elements of Programming - The Substitution Model for Procedure Application
print (f(5))
print (sum_of_squares(5 + 1, 5 * 2))
print (square(6) + square(10))
print (6 * 6 + 10 * 10)
print (36 + 100)
print (f(5))
print (sum_of_squares(5 + 1, 5 * 2))
print (square(5 + 1) + square(5 * 2))

print (((5 + 1) * (5 + 1)) + ((5 * 2) * (5 * 2)))
print ((6 * 6) + (10 * 10))
print (36 + 100)
print (136)

-- 1.1.6 The Elements of Programming - Conditional Expressions and Predicates
function abs(x)
   if x > 0 then
      return x
   elseif x == 0 then
      return 0
   else
      return -x
   end
end
function abs(x)
   if x < 0 then
      return -x
   else
      return x
   end
end
x = 6
print ((x > 5) and (x < 10))
function ge(x, y)
   return x > y or x == y
end
function ge(x, y)
   return not(x < y)
end

-- Exercise 1.1
print (10)
print (5 + 3 + 4)
print (9 - 1)
print (6 / 2)
print (2 * 4 + 4 - 6)
a = 3
b = a + 1
print (a + b + a * b)
print (a == b)
print (b > a and b < a * b and b or a)
print (a == 4 and 6 or b == 4 and 6 + 7 + a or 25)
print (2 + (b > a and b or a))
print ((a > b and a or a < b and b or -1) * (a + 1))

-- Exercise 1.2
print (((5 + 4 + (2 - (3 - (6 + (4 / 5))))) /
        (3 * (6 - 2) * (2 - 7))))

-- Exercise 1.3
function three_n(n1, n2, n3)
   if n1 > n2 then
      if n1 > n3 then
         if n2 > n3 then
            return n1*n1 + n2*n2
         else
            return n1*n1 + n3*n3
         end
      else
         return n1*n1 + n3*n3
      end
   else
      if n2 > n3 then
         if n1 > n3 then
            return n2*n2 + n1*n1
         else
            return n2*n2 + n3*n3
         end
      else
         return n2*n2 + n3*n3
      end
   end
end

-- Exercise 1.4
function a_plus_abs_b(a, b)
   if b > 0 then
      return a + b
   else
      return a - b
   end
end

-- Exercise 1.5
function p() return p() end
function test(x, y)
   if x == 0 then
      return 0
   else
      return y
   end
end
-- commented out as this is in infinite loop
-- test(0, p())

-- 1.1.7 The Elements of Programming - Example: Square Roots by Newton's Method
function square(x) return x * x end

function good_enough(guess, x)
   return abs(square(guess) - x) < 0.001
end

function average(x, y)
   return (x + y) / 2.0
end

function improve(guess, x)
   return average(guess, x / guess)
end

function sqrt_iter(guess, x)
   if good_enough(guess, x) then
      return guess
   else
      return sqrt_iter(improve(guess, x), x)
   end
end

function sqrt(x)
   return sqrt_iter(1.0, x)
end

print (sqrt(9))
print (sqrt(100 + 37))
print (sqrt(sqrt(2)+sqrt(3)))
print (square(sqrt(1000)))

-- Exercise 1.6
function new_if(predicate, then_clause, else_clause)
   if predicate then
      return then_clause
   else
      return else_clause
   end
end
print (new_if((2==3), 0, 5))
print (new_if((1==1), 0, 5))
function sqrt_iter(guess, x)
   return new_if(
      good_enough(guess, x),
      guess,
      sqrt_iter(improve(guess, x), x))
end

-- Exercse 1.7
function good_enough_gp(guess, prev)
   return abs(guess - prev) / guess < 0.001
end
function sqrt_iter_gp(guess, prev, x)
   if good_enough_gp(guess, prev) then
      return guess
   else
      return sqrt_iter_gp(improve(guess, x), guess, x)
   end
end
function sqrt_gp(x)
   return sqrt_iter_gp(4.0, 1.0, x)
end

-- Exercise 1.8
function improve_cube(guess, x)
   return (2.0*guess + x/(guess * guess)) / 3.0
end
function cube_iter(guess, prev, x)
   if good_enough_gp(guess, prev) then
      return guess
   else
      return cube_iter(improve_cube(guess, x), guess, x)
   end
end
function cube_root_0(x)
   return cube_iter(27.0, 1.0, x)
end

-- 1.1.8 The Elements of Programming - Procedures as Black-Box Abstractions
function square(x) return x * x end

function double(x) return x + x end

function square_real(x) return exp(double(math.log(x))) end

function good_enough(guess, x)
   return abs(square(guess) - x) < 0.001
end

function improve(guess, x)
   return average(guess, x / guess)
end

function sqrt_iter(guess, x)
   if good_enough(guess, x) then
      return guess
   else
      return sqrt_iter(improve(guess, x), x)
   end
end

function sqrt(x)
   return sqrt_iter(1.0, x)
end

print (square(5))

-- Block-structured
function sqrt(x)
   local function good_enough(guess, x)
      return abs(square(guess) - x) < 0.001
   end

   local function improve(guess, x)
      return average(guess, x / guess)
   end

   local function sqrt_iter(guess, x)
      if good_enough(guess, x) then
         return guess
      else
         return sqrt_iter(improve(guess, x), x)
      end
   end

   return sqrt_iter(1.0, x)
end

-- Taking advantage of lexical scoping
function sqrt(x)
   local function good_enough(guess)
      return abs(square(guess) - x) < 0.001
   end

   local function improve(guess)
      return average(guess, x / guess)
   end

   local function sqrt_iter(guess)
      if good_enough(guess) then
         return guess
      else
         return sqrt_iter(improve(guess))
      end
   end

   return sqrt_iter(1.0)
end

-- 1.2.1 Procedures and the Processes They Generate - Linear Recursion and Iteration

-- Recursive
function factorial(n)
   if n == 1 then
      return 1
   else
      return n * factorial(n - 1)
   end
end

print (factorial(6))

-- Iterative
function fact_iter(product, counter, max_count)
   if counter > max_count then
      return product
   else
      return fact_iter(counter * product, counter + 1, max_count)
   end
end

function factorial(n)
   return fact_iter(1, 1, n)
end

-- Iterative, block-structured (from footnote)
function factorial(n)
   local function iter(product, counter)
      if counter > n then
         return product
      else
         return iter(counter * product, counter + 1)
      end
   end
   return iter(1, 1)
end

-- Exercise 1.9
function inc(a) return a + 1 end
function dec(a) return a - 1 end
function plus(a, b)
   if a == 0 then
      return b
   else
      return inc(plus(dec(a), b))
   end
end
function plus(a, b)
   if a == 0 then
      return b
   else
      return plus(dec(a), inc(b))
   end
end

-- Exercise 1.10
function a(x, y)
   if y == 0 then
      return 0
   elseif x == 0 then
      return 2 * y
   elseif y == 1 then
      return 2
   else
      return a(x - 1, a(x, y - 1))
   end
end
print (a(1, 10))
print (a(2, 4))
print (a(3, 3))
function f(n) return a(0, n) end
function g(n) return a(1, n) end
function h(n) return a(2, n) end
function k(n) return 5 * n * n end

-- 1.2.2 Procedures and the Processes They Generate - Tree Recursion

-- Recursive
function fib(n)
   if n == 0 then
      return 0
   elseif n == 1 then
      return 1
   else
      return fib(n - 1) + fib(n - 2)
   end
end

-- Iterative
function fib_iter(a, b, count)
   if count == 0 then
      return b
   else
      return fib_iter(a + b, a, count - 1)
   end
end
function fib(n)
   return fib_iter(1, 0, n)
end

-- Counting change
function first_denomination(x)
   if x == 1 then
      return 1
   elseif x == 2 then
      return 5
   elseif x == 3 then
      return 10
   elseif x == 4 then
      return 25
   elseif x == 5 then
      return 50
   end
end

function cc(amount, kinds_of_coins)
   if amount == 0 then
      return 1
   elseif amount < 0 then
      return 0
   elseif kinds_of_coins == 0 then
      return 0
   else
      return cc(amount, kinds_of_coins - 1) +
             cc(amount - first_denomination(kinds_of_coins), kinds_of_coins)
   end
end

function count_change(amount)
   return cc(amount, 5)
end

print (count_change(100))

-- Exercise 1.11
function f(n)
   if n < 3 then
      return n
   else
      return f(n-1) + 2*f(n-2) + 3*f(n-3)
   end
end
function f_iter(a, b, c, count)
   if count == 0 then
      return c
   else
      return f_iter(a + 2*b + 3*c, a, b, count-1)
   end
end
function f(n)
   return f_iter(2, 1, 0, n)
end

-- Exercise 1.12
function pascals_triangle(n, k)
   if n == 0 then
      return 1
   elseif n == k then
      return 1
   else
      return pascals_triangle(n-1, k-1) + pascals_triangle(n-1, k)
   end
end

-- 1.2.3 Procedures and the Processes They Generate - Orders of Growth
-- Exercise 1.15
function cube(x) return x * x * x end
function p(x) return 3.0 * x - 4.0 * cube(x) end
function sine(angle)
   if not(abs(angle) > 0.1) then
      return angle
   else
      return p(sine(angle / 3.0))
   end
end

-- 1.2.4 Procedures and the Processes They Generate - Exponentiation

-- Linear recursion
function expt(b, n)
   if n == 0 then
      return 1
   else
      return b * expt(b, n - 1)
   end
end

-- Linear iteration
function expt_iter(b, counter, product)
   if counter == 0 then
      return product
   else
      return expt_iter(b, counter - 1, b * product)
   end
end
function expt(b, n)
   return expt_iter(b, n, 1)
end

-- Logarithmic iteration
function even(n) return math.mod(n, 2) == 0 end

function fast_expt(b, n)
   if n == 0 then
      return 1
   else
      if even(n) then
         return square(fast_expt(b, math.floor(n / 2)))
      else
         return b * fast_expt(b, n - 1)
      end
   end
end

-- Exercise 1.17
function multiply(a, b)
   if b == 0 then
      return 0
   else
      return plus(a, multiply(a, dec(b)))
   end
end

-- Exercise 1.19
-- exercise left to reader to solve for p' and q'
function fib_iter(a, b, p, q, count)
   if count == 0 then
      return b
   else
      if even(count) then
         return fib_iter(a, b, p_, q_, math.floor(count / 2))
      else
         return fib_iter(b*q + a*q + a*p, b*p + a*q, p, q, count - 1)
      end
   end
end
function fib(n)
   return fib_iter(1, 0, 0, 1, n)
end

-- 1.2.5 Procedures and the Processes They Generate - Greatest Common Divisors
function gcd(a, b)
   if b == 0 then
      return a
   else
      return gcd(b, math.mod(a, b))
   end
end

print (gcd(40, 6))

-- Exercise 1.20
print (gcd(206, 40))

-- 1.2.6 Procedures and the Processes They Generate - Example: Testing for Primality

-- prime
function divides(a, b) return math.mod(b, a) == 0 end

function find_divisor(n, test_divisor)
   if square(test_divisor) > n then
      return n
   elseif divides(test_divisor, n) then
      return test_divisor
   else
      return find_divisor(n, test_divisor + 1)
   end
end

function smallest_divisor(n)
   return find_divisor(n, 2)
end

function prime(n)
   return n == smallest_divisor(n)
end

-- fast_prime
function expmod(nbase, nexp, m)
   if nexp == 0 then
      return 1
   else
      if even(nexp) then
         return math.mod(square(expmod(nbase, math.floor(nexp / 2), m)), m)
      else
         return math.mod(nbase * (expmod(nbase, (nexp - 1), m)), m)
      end
   end
end

function fermat_test(n)
   local function try_it(a)
      return expmod(a, n, n) == a
   end
   return try_it(1 + math.random(0, n-1))
end

function fast_prime(n, ntimes)
   if ntimes == 0 then
      return true
   else
      if fermat_test(n) then
         return fast_prime(n, ntimes - 1)
      else
         return false
      end
   end
end

-- Exercise 1.21
print (smallest_divisor(199))
print (smallest_divisor(1999))
print (smallest_divisor(19999))

-- Exercise 1.22
function report_prime(elapsed_time)
   print (string.format(" *** %f", elapsed_time))
end
function start_prime_test(n, start_time)
   if prime(n) then
      report_prime(os.clock() - start_time)
   end
end
function timed_prime_test(n)
   print (string.format("\n%d", n))
   start_prime_test(n, os.clock())
end

-- Exercise 1.25
function expmod(nbase, nexp, m)
   return math.mod(fast_expt(nbase, nexp), m)
end

-- Exercise 1.26
function expmod(nbase, nexp, m)
   if nexp == 0 then
      return 1
   else
      if even(nexp) then
         return math.mod(expmod(nbase, math.floor(nexp / 2), m) * expmod(nbase, math.floor(nexp / 2), m), m)
      else
         return math.mod(nbase * expmod(nbase, nexp - 1, m), m)
      end
   end
end

-- Exercise 1.27
function carmichael(n)
   return fast_prime(n, 100) and not(prime(n))
end

print (carmichael(561))
print (carmichael(1105))
print (carmichael(1729))
print (carmichael(2465))
print (carmichael(2821))
print (carmichael(6601))

-- 1.3 Formulating Abstractions with Higher-Order Procedures
function cube(x) return x * x * x end

-- 1.3.1 Formulating Abstractions with Higher-Order Procedures - Procedures as Arguments
function sum_integers(a, b)
   if a > b then
      return 0
   else
      return a + sum_integers(a + 1, b)
   end
end

function sum_cubes(a, b)
   if a > b then
      return 0
   else
      return cube(a) + sum_cubes(a + 1, b)
   end
end

function pi_sum(a, b)
   if a > b then
      return 0.0
   else
      return (1.0 / (a * (a + 2.0))) + pi_sum(a + 4.0, b)
   end
end

function sum(term, a, next, b)
   if a > b then
      return 0
   else
      return term(a) + sum(term, next(a), next, b)
   end
end

-- Using sum
function inc(n) return n + 1 end

function sum_cubes(a, b)
   return sum(cube, a, inc, b)
end

print (sum_cubes(1, 10))

function identity(x) return x end

function sum_integers(a, b)
   return sum(identity, a, inc, b)
end

print (sum_integers(1, 10))

function pi_sum(a, b)
   local function pi_term(x) return 1.0 / (x * (x + 2.0)) end
   local function pi_next(x) return x + 4.0 end
   return sum(pi_term, a, pi_next, b)
end

print (8.0 * pi_sum(1, 1000))

function integral(f, a, b, dx)
   local function add_dx(x) return x + dx end
   return sum(f, a + (dx / 2.0), add_dx, b) * dx
end

function cube(x) return x * x * x end

print (integral(cube, 0.0, 1.0, 0.01))
print (integral(cube, 0.0, 1.0, 0.001))

-- Exercise 1.29
function simpson(f, a, b, n)
   local h = abs(b-a) / n
   local function sum_iter(term, start, next, stop, acc)
      if start > stop then
         return acc
      else
         return sum_iter(term, next(start), next, stop, acc + term(a + start*h))
      end
   end
   return h * sum_iter(f, 1, inc, n, 0)
end
print (simpson(cube, 0, 1, 100))

-- Exercise 1.30
function sum_iter(term, a, next, b, acc)
   if a > b then
      return acc
   else
      return sum_iter(term, next(a), next, b, acc + term(a))
   end
end
function sum_cubes(a, b)
   return sum_iter(cube, a, inc, b, 0)
end
print (sum_cubes(1, 10))

-- Exercise 1.31
function product(term, a, next, b)
   if a > b then
      return 1
   else
      return term(a) * product(term, next(a), next, b)
   end
end
function factorial(n)
   return product(identity, 1, inc, n)
end
function product_iter(term, a, next, b, acc)
   if a > b then
      return acc
   else
      return product_iter(term, next(a), next, b, acc * term(a))
   end
end

-- Exercise 1.32
function accumulate(combiner, null_value, term, a, next, b)
   if a > b then
      return null_value
   else
      return combiner(term(a), accumulate(combiner, null_value, term, next(a), next, b))
   end
end
function sum(a, b)
   return accumulate(function(x,y) return x+y end, 0, identity, a, inc, b)
end
function product(a, b)
   return accumulate(function(x,y) return x*y end, 1, identity, a, inc, b)
end
function accumulate_iter(combiner, term, a, next, b, acc)
   if a > b then
      return acc
   else
      return accumulate_iter(combiner, term, next(a), next, b, combiner(acc, term(a)))
   end
end
function sum(a, b)
   return accumulate_iter(function(x,y) return x+y end, identity, a, inc, b, 0)
end
function product(a, b)
   return accumulate_iter(function(x,y) return x*y end, identity, a, inc, b, 1)
end

-- Exercise 1.33
function filtered_accumulate(combiner, null_value, term, a, next, b, pred)
   if a > b then
      return null_value
   else
      if pred(a) then
         return combiner(term(a), filtered_accumulate(combiner, null_value, term, next(a), next, b, pred))
      else
         return filtered_accumulate(combiner, null_value, term, next(a), next, b, pred)
      end
   end
end
print (filtered_accumulate(function(x,y) return x+y end, 0, square, 1, inc, 5, prime))

-- 1.3.2 Formulating Abstractions with Higher-Order Procedures - Constructing Procedures Using Lambda
function pi_sum(a, b)
   return sum(
      function(x) return 1.0 / (x * (x + 2.0)) end,
      a,
      function(x) return x + 4.0 end,
      b)
end

function integral(f, a, b, dx)
   return sum(
      f,
      a + (dx / 2.0),
      function(x) return x + dx end,
      b) * dx
end

function plus4(x) return x + 4 end

plus4 = function(x) return x + 4 end

print ((function(x, y, z) return x + y + square(z) end) (1, 2, 3))

-- Using let
function f(x, y)
   local function f_helper(a, b)
      return x*square(a) + y*b + a*b
   end
   return f_helper(1 + x*y, 1 - y)
end

-- not sure why need to go through a variable here???
function f(x, y)
   return
      (function(a, b)
         return x*square(a) + y*b + a*b
       end) (1 + x*y, 1 - y)
end

function f(x, y)
   local a = 1 + x*y
   local b = 1 - y
   return x*square(a) + y*b + a*b
end

-- lua does not seem to have let binding.  use function to demo scoping.
x = 5
print ((function()
         local x = 3
         return x + x*10
        end)() + x)

x = 2
print ((function(x)
         local y = x + 2
         local x = 3
         return x * y
        end)(x))

function f(x, y)
   local a = 1 + x*y
   local b = 1 - y
   return x*square(a) + y*b + a*b
end

-- Exercise 1.34
function f(g) return g(2) end
print (f(square))
print (f(function(z) return z * (z + 1) end))

-- 1.3.3 Formulating Abstractions with Higher-Order Procedures - Procedures as General Methods

-- Half-interval method
function close_enough(x, y)
   return (abs(x - y) < 0.001)
end

function positive(x) return (x >= 0.0) end
function negative(x) return not(positive(x)) end

function search(f, neg_point, pos_point)
   local midpoint = average(neg_point, pos_point)
   if close_enough(neg_point, pos_point) then
      return midpoint
   else
      local test_value = f(midpoint)
      if positive(test_value) then
         return search(f, neg_point, midpoint)
      elseif negative(test_value) then
         return search(f, midpoint, pos_point)
      else
         return midpoint
      end
   end
end

function half_interval_method(f, a, b)
   local a_value = f(a)
   local b_value = f(b)
   if negative(a_value) and positive(b_value) then
      return search(f, a, b)
   elseif negative(b_value) and positive(a_value) then
      return search(f, b, a)
   else
      error(string.format("Values are not of opposite sign %d %d", a, b))
   end
end

print (half_interval_method(math.sin, 2.0, 4.0))

print (half_interval_method(function(x) return x*x*x - 2.0*x - 3.0 end, 1.0, 2.0))

-- Fixed points
tolerance = 0.00001

function fixed_point(f, first_guess)
   local function close_enough(v1, v2)
      return abs(v1 - v2) < tolerance
   end
   local function tryit(guess)
      local next = f(guess)
      if close_enough(guess, next) then
         return next
      else
         return tryit(next)
      end
   end
   return tryit(first_guess)
end

print (fixed_point(math.cos, 1.0))

print (fixed_point(function(y) return math.sin(y) + math.cos(y) end, 1.0))

-- note: this function does not converge
function sqrt(x)
   return fixed_point(function(y) return x / y end, 1.0)
end

function sqrt(x)
   return fixed_point(function(y) return average(y, x / y) end, 1.0)
end

-- Exercise 1.35
function golden_ratio()
   return fixed_point(function(x) return 1.0 + 1.0/x end, 1.0)
end

-- Exercise 1.36
-- 35 guesses before convergence
print (fixed_point(function(x) return math.log(1000.0) / math.log(x) end, 1.5))
-- 11 guesses before convergence (average_damp defined below)
-- print (fixed_point(average_damp(function(x) return math.log(1000.0) / math.log(x) end), 1.5))

-- Exercise 1.37
-- exercise left to reader to define cont_frac
-- cont_frac(function(i) return 1.0 end, lambda(i) return 1.0 end, k)

-- 1.3.4 Formulating Abstractions with Higher-Order Procedures - Procedures as Returned Values
function average_damp(f)
   return function(x) return average(x, f(x)) end
end

print ((average_damp(square)) (10.0))

function sqrt(x)
   return fixed_point(average_damp(function(y) return x / y end), 1.0)
end

function cube_root(x)
   return fixed_point(average_damp(function(y) return x / square(y) end), 1.0)
end

print (cube_root(8))

-- Newton's method
dx = 0.00001
function deriv(g)
   return function(x) return (g(x + dx) - g(x)) / dx end
end

function cube(x) return x * x * x end

print (deriv(cube) (5.0))

function newton_transform(g)
   return function(x) return x - (g(x) / (deriv(g) (x))) end
end

function newtons_method(g, guess)
   return fixed_point(newton_transform(g), guess)
end

function sqrt(x)
   return newtons_method(function(y) return square(y) - x end, 1.0)
end

-- Fixed point of transformed function
function fixed_point_of_transform(g, transform, guess)
   return fixed_point(transform(g), guess)
end

function sqrt(x)
   return fixed_point_of_transform(function(y) return x / y end, average_damp, 1.0)
end

function sqrt(x)
   return
      fixed_point_of_transform(
         function(y) return square(y) - x end,
         newton_transform,
         1.0)
end

-- Exercise 1.40
function cubic(a, b, c)
   return function(x) return cube(x) + a*x*x + b*x + c end
end
print (newtons_method(cubic(5.0, 3.0, 2.5), 1.0))

-- Exercise 1.41
function double(f)
   return function(x) return f(f(x)) end
end
print (double(inc)(5))
print (double(double)(inc)(5))
print (double(double)(double)(inc)(5))

-- Exercise 1.42
function compose(f, g)
   return function(x) return f(g(x)) end
end
print (compose(square, inc)(6))

-- Exercise 1.43
function repeated(f, n)
   local function iterate(arg, i)
      if i > n then
         return arg
      else
         return iterate(f(arg), i+1)
      end
   end
   return function(x) return iterate(x, 1) end
end
print (repeated(square, 2)(5))

-- Exercise 1.44
function smooth(f, dx)
   return function(x) return average(x, (f(x-dx) + f(x) + f(x+dx)) / 3.0) end
end
print (fixed_point(smooth(function(x) return math.log(1000.0) / math.log(x) end, 0.05), 1.5))

-- Exercise 1.46
function iterative_improve(good_enough, improve)
   local function iterate(guess)
      local next = improve(guess)
      if good_enough(guess, next) then
         return next
      else
         return iterate(next)
      end
   end
   return function(x) return iterate(x) end
end
function fixed_point(f, first_guess)
   local tolerance = 0.00001
   local function good_enough(v1, v2)
      return abs(v1-v2) < tolerance
   end
   return iterative_improve(good_enough, f)(first_guess)
end
print (fixed_point(average_damp(function(x) return math.log(1000.0) / math.log(x) end), 1.5))

Chris Rathman / Chris.Rathman@tx.rr.com