Використання "налагодження printf"
Ви можете дозволити Emacs допомогти вам зрозуміти, змінивши визначення функції:
(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))))))
Просто додайте (message ...)десь, щоб слід було надрукувати слід до *Messages*буфера.
Використання Edebug
Помістіть точку в будь-якому місці визначення функції та натисніть C-u C-M-xна "інструмент". Потім оцініть функцію, наприклад, поставивши крапку після (triangle-using-cond 3)та натиснувши C-x C-e.
Зараз ви перебуваєте в режимі Edebug. Натисніть пробіл, щоб перейти через функцію. Проміжні значення кожного виразу відображаються в області ехо. Для виходу з режиму Edebug просто натисніть q. Щоб видалити інструментарій, поставте крапку десь усередині визначення та натисніть, C-M-xщоб переоцінити визначення.
Використання стандартного відладчика Emacs
M-x debug-on-entry triangle-using-cond, тоді при triangle-using-condвиклику вас розміщують у відладчику (буфері *Backtrace*) Emacs .
Перегляньте оцінку за допомогою d(або cпропустіть будь-які нецікаві оцінки).
Для перегляду проміжного стану (змінних значень тощо) ви можете використовувати eбудь-коли. Вам буде запропоновано ввести сексоп для оцінки, і результат оцінки надрукується.
Під час використання налагоджувача зберігайте копію вихідного коду в іншому кадрі, щоб ви могли слідкувати за тим, що відбувається.
Ви також можете вставити явні дзвінки для введення налагоджувача (більш-менш точок перерви) у довільних місцях у вихідному коді. Ви вставляєте (debug)або (debug nil SOME-SEXP-TO-EVALUATE). В останньому випадку при введенні налагоджувача SOME-SEXP-TO-EVALUATEоцінюється і результат друкується. (Пам'ятайте, що ви можете вставити такий код у вихідний код і використовувати його C-M-xдля оцінки, а потім скасувати - не потрібно зберігати відредагований файл.)
Дивіться посібник Elisp, вузол Using Debuggerдля отримання додаткової інформації.
Рекурсія як петля
У будь-якому випадку, подумай про рекурсію як цикл. Визначено два випадки припинення: (<= number 0)та (= number 1). У цих випадках функція повертає просте число.
У рекурсивному випадку функція повертає суму цього числа та результат функції з number - 1. Зрештою, функція буде викликана з 1або числом, меншим або рівним нулю.
Отже, рекурсивний результат:
(+ number (+ (1- number) (+ (1- (1- number)) ... 1)
Візьмемо для прикладу (triangle-using-cond 4). Давайте накопичимо підсумковий вираз:
у першій ітерації numberє 4, тому слід (> number 1)гілка. Починаємо будувати вираз (+ 4 ...і викликаємо функцію за допомогою (1- 4), тобто (triangle-using-cond 3).
зараз numberє 3, і результат є (+ 3 (triangle-using-cond 2)). Загальний вираз результату - (+ 4 (+ 3 (triangle-using-cond 2))).
numberє 2зараз, тому вираз є(+ 4 (+ 3 (+ 2 (triangle-using-cond 1))))
numberв 1даний час, і ми беремо (= number 1)гілка, в результаті роздратування 1. Весь вираз є (+ 4 (+ 3 (+ 2 1))). Оцінювати , що зсередини , і ви отримаєте: (+ 4 (+ 3 3)), (+ 4 6)або просто 10.
triangle-using-condаргумент на 1 менше, ніж будь-яке число. Умови йдуть у порядку a, b, а потім c - усе, що спочатку відповідає, саме там долар зупиняється.