Управляйте числами с пи-суммой, но сообщайте о неверной ошибке строки - PullRequest
0 голосов
/ 02 ноября 2019

Я узнал следующий шаблон кода, абстрактная сумма которого

#+BEGIN_SRC scheme :results value
(define (sum term a next b)
  (if (> a b)
      0
      (+ (term a)
         (sum term (next a) next b))))
(define (pi-sum a b)
  (sum (lambda (x) (/ 1.0 (* x (+ x 2))))
       a
       (lambda (x) (+ x 4))
       b))
(pi-sum 1 11)
#+END_SRC

#+RESULTS:
: 0.372005772005772

С elisp

#+begin_src emacs-lisp :session sicp :lexical t
(defun sum(term a next b)
  (if (> a b)
      0
      (+ (term a)
         (sum term (next a) next b))))

(defun pi-sum(a b)
  (sum (lambda (x) (/ 1.0 (* x (+ x 2))))
       a
       (lambda (x) (+ x 4))
       b))
#+end_src

#+RESULTS:
: pi-sum

Кажется, работает хорошо, пока не передадут аргументы

ELISP> (pi-sum 1 11)
*** Eval error ***  Wrong type argument: stringp, 1

Имеютнет идей, где аргументы в (pi-sum a b) указаны в виде строки?

1 Ответ

1 голос
/ 02 ноября 2019

Ваш код вызывает функцию term, которая задокументирована следующим образом:

(термин ПРОГРАММА)

Запустить эмулятор терминала в новом буфере. Буфер находится в режиме Term;см. 'term-mode' для команд, которые будут использоваться в этом буфере.

Вы можете увидеть подробности ошибки, если установить debug-on-error :

(setq debug-on-error t)
(pi-sum 1 11)

Вы получите обратную трассировку следующим образом:

Debugger entered--Lisp error: (wrong-type-argument stringp 1)
  make-process(:name "terminal" :buffer #<buffer *terminal*> :command ("/bin/sh" "-c" "stty -nl echo rows 25 columns 81 sane 2>/dev/null;if [ $1 = .. ]; then shift; fi; exec \"$@\"" ".." 1))
  apply(make-process (:name "terminal" :buffer #<buffer *terminal*> :command ("/bin/sh" "-c" "stty -nl echo rows 25 columns 81 sane 2>/dev/null;if [ $1 = .. ]; then shift; fi; exec \"$@\"" ".." 1)))
  start-process("terminal" #<buffer *terminal*> "/bin/sh" "-c" "stty -nl echo rows 25 columns 81 sane 2>/dev/null;if [ $1 = .. ]; then shift; fi; exec \"$@\"" ".." 1)
  apply(start-process "terminal" #<buffer *terminal*> "/bin/sh" "-c" "stty -nl echo rows 25 columns 81 sane 2>/dev/null;if [ $1 = .. ]; then shift; fi; exec \"$@\"" ".." 1 nil)
  term-exec-1("terminal" #<buffer *terminal*> 1 nil)
  term-exec(#<buffer *terminal*> "terminal" 1 nil nil)
  make-term("terminal" 1)
  term(1)
  (+ (term a) (sum term (next a) next b))
  (if (> a b) 0 (+ (term a) (sum term (next a) next b)))
  sum((lambda (x) (/ 1.0 (* x (+ x 2)))) 1 (lambda (x) (+ x 4)) 11)
  pi-sum(1 11)

Вам нужно изменить свою функцию sum, чтобы использовать funcall для вызова функций term и next, которые выВы переходите к нему:

(defun sum(term a next b)
  (if (> a b)
      0
      (+ (funcall term a)
         (sum term (funcall next a) next b))))

С этим пересмотренным определением sum, вызов pi-sum дает ожидаемый ответ:

(pi-sum 1 11)
0.372005772005772
...