Sử dụng "gỡ lỗi printf"
Bạn có thể để Emacs giúp bạn hiểu bằng cách sửa đổi định nghĩa hàm:
(defun triangle-using-cond (number)
(message (format "called with %d" number))
(cond ((<= number 0) 0)
((= number 1) 1)
((> number 1)
(+ number (triangle-using-cond (1- number))))))
Chỉ cần thêm (message ...)một nơi nào đó để có một dấu vết được in vào*Messages* bộ đệm.
Sử dụng Edebug
Đặt điểm bất cứ nơi nào trong định nghĩa hàm và nhấn C-u C-M-xvào "công cụ" nó. Sau đó đánh giá chức năng, ví dụ bằng cách đặt điểm sau (triangle-using-cond 3)và nhấn C-x C-e.
Bây giờ bạn đang ở chế độ Edebug. Nhấn thanh không gian để bước qua chức năng. Các giá trị trung gian của mỗi biểu thức được hiển thị trong vùng echo. Để thoát chế độ Edebug chỉ cần nhấn q. Để xóa thiết bị, đặt điểm ở bất kỳ đâu trong định nghĩa và nhấn C-M-xđể đánh giá lại định nghĩa.
Sử dụng trình gỡ lỗi Emacs tiêu chuẩn
M-x debug-on-entry triangle-using-cond, sau đó, khi triangle-using-condđược gọi, bạn được đặt trong trình gỡ lỗi Emacs (bộ đệm *Backtrace*).
Bước qua đánh giá bằng cách sử dụng d(hoặc cbỏ qua mọi đánh giá không thú vị).
Để xem trạng thái trung gian (giá trị biến, v.v.) bạn có thể sử dụng e bất cứ lúc nào. Bạn được nhắc nhập sexp để đánh giá và kết quả đánh giá được in.
Trong khi bạn sử dụng trình gỡ lỗi, hãy giữ một bản sao của mã nguồn hiển thị trong một khung khác, để bạn có thể theo dõi những gì đang diễn ra.
Bạn cũng có thể chèn các cuộc gọi rõ ràng để vào trình gỡ lỗi (nhiều hoặc ít điểm dừng) tại các vị trí tùy ý trong mã nguồn. Bạn chèn (debug)hoặc (debug nil SOME-SEXP-TO-EVALUATE). Trong trường hợp sau, khi trình gỡ lỗi được nhập SOME-SEXP-TO-EVALUATEđược đánh giá và kết quả được in. (Hãy nhớ rằng bạn có thể chèn mã đó vào mã nguồn và sử dụng C-M-xđể đánh giá nó, sau đó hoàn tác - bạn không cần lưu tệp đã chỉnh sửa.)
Xem hướng dẫn Elisp, nút Using Debuggerđể biết thêm thông tin.
Đệ quy như một vòng lặp
Dù sao, hãy nghĩ về đệ quy như một vòng lặp. Có hai trường hợp chấm dứt được xác định: (<= number 0)và (= number 1). Trong những trường hợp này, hàm trả về một số đơn giản.
Trong trường hợp đệ quy, hàm trả về tổng của số đó và kết quả của hàm với number - 1. Cuối cùng, hàm sẽ được gọi với một 1hoặc một số nhỏ hơn hoặc bằng 0.
Do đó, kết quả trường hợp đệ quy là:
(+ number (+ (1- number) (+ (1- (1- number)) ... 1)
Lấy ví dụ (triangle-using-cond 4). Hãy tích lũy biểu thức cuối cùng:
trong lần lặp đầu tiên numberlà 4, vì vậy (> number 1)nhánh được theo sau. Chúng ta bắt đầu xây dựng một biểu thức (+ 4 ...và gọi hàm với (1- 4), tức là (triangle-using-cond 3).
bây giờ numberlà 3, và kết quả là (+ 3 (triangle-using-cond 2)). Biểu thức tổng kết quả là (+ 4 (+ 3 (triangle-using-cond 2))).
numberlà 2hiện nay, vì vậy biểu thức là(+ 4 (+ 3 (+ 2 (triangle-using-cond 1))))
numberlà 1bây giờ, và chúng tôi lấy (= number 1)chi nhánh, kết quả là nhàm chán 1. Toàn bộ biểu hiện là (+ 4 (+ 3 (+ 2 1))). Đánh giá rằng từ trong ra ngoài và bạn nhận được: (+ 4 (+ 3 3)), (+ 4 6), hoặc chỉ 10.
triangle-using-condvới đối số là 1 nhỏ hơn bất kể số đó là gì. Các điều kiện đi theo thứ tự a, b, và sau đó c - bất cứ điều gì khớp trước, là nơi buck dừng lại.