elisp改写牛顿求根公式

Python版的牛顿求根公式

#+begin_src ipython :session sicp :results output
import math

dx = 0.00001
def deriv(g):
    return lambda x: (g(x+dx) - g(x)) / dx

def fixed_point(f, guess):
    while True:
        nex = f(guess)
        if abs(guess-nex) < 0.0001:
            return nex
        else:
            guess = nex 

def newton_transform(g):
    return lambda x: x - g(x) / deriv(g)(x)

def newton_method(g, guess):
    return fixed_point(
           newton_transform(g),
           guess)


def curt(x):
    return newton_method(lambda y: pow(y, 3)-x,
                          1)
print(curt(27))

#+end_src

#+RESULTS:
: 3.000000000001917

改写成elisp

#+begin_src emacs-lisp :session sicp :lexical t
(defvar dx 0.00001)
(defvar tolerance 0.00001)

(defun deriv(g)
  (lambda (x)
    (/ (- (funcall g (+ x dx)) (funcall g x))
       dx)))

(defun fixed-point(f guess)
  (defun close-enough-p(v1 v2)
    (< (abs (- v1 v2)) tolerance))
  (let ((next (funcall f guess)))
    (if (close-enough-p guess next)
        next
      (fixed-point f next))) 
  )


(defun newton-transform(g)
  (lambda (x)
    (- x (/ (funcall g x) 
            (funcall (deriv g) x)))))

(defun newton-method(g guess)
  (fixed-point (newton-transform g) guess))


(defun curt(x)
  (newton-method (lambda (y) (- (* y y y) (* y y) x))
                  1.0))
(curt 12)
#+end_src

这里看起来惨不忍睹

(defun newton-transform(g)
  (lambda (x)
    (- x (/ (funcall g x) 
            (funcall (deriv g) x)))))

必须实现知道一个function的内部结构才能正确调用, 如果有更多层的closures, 更难看了.

这种改写方法是不是unidiomatic with elisp?
应该怎样改写呢?

cl-loop和break,而不是用奇怪的fixpoint。