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?
应该怎样改写呢?