def square(x): return x * x
def average(x, y):
    return (x + y) / 2
def sqrt(x):
    def is_good_enough(guess):
        return math_abs(square(guess) - x) < 0.001
    def improve(guess):
        return average(guess, x / guess)
    def sqrt_iter(guess):
        return guess if is_good_enough(guess) else sqrt_iter(improve(guess))
    return sqrt_iter(1)

print(sqrt(5))

# expected: 2.2360688956433634
