2016-07-20 5 views
-2

Я новичок в LISP, и я пытаюсь понять рекурсию.Объясните мне мой код LISP

Я знаю, что для рекурсии требуется условие STOP. В моем коде ниже вы можете объяснить мне, почему (equal x 0) 1 - мое состояние STOP. С fact(- X 1) может продолжаться бесконечно, так как в моем втором состоянии я установил t вторую строку моего cond, что означает, что она должна продолжаться.

НО, но когда я запускаю программу, она работает нормально. Ниже мой код (найденный случайно)

(defun fact(x) 
    (cond 
     ((equal x 0) 1) 
     (t (*(fact(- x 1)) x)) 
    ) 
) 
+0

Я мог бы продолжать бесконечно, если вы передали отрицательное число. – coredump

+0

Результатом либо последовательного, либо альтернативного является значение if, а последнее выражение - возвращаемое значение. В JS это будет выглядеть так: 'function fact (x) {return x === 0? 1: x * fact (x-1);} ' – Sylwester

ответ

0

cond expresssions имеет ряд оговорок. Каждый пункт имеет вид (expr1 expr2). Если значение expr1 равно true, то expr2 is evaluated and that is the returned value of the cond`. Никакие другие предложения не оцениваются.

Так, однажды x становится 0 первые пункты cond оценивает истинного и этот призыв к fact возвращается 1.

В другом предложении cond имеется первое выражение t, которое истинно по определению; поэтому, если первое предложение не используется, оно всегда использует второе предложение. (A cond статья с t подобна «другой» в «если» заявление в других langugaes.)

Эта функция является рекурсивной, если вы называете его с аргументом 2, он проверяет, если 2 == 0, он не делает этого, поэтому он умножает 2 на значение, возвращаемое рекурсивно, называя себя с 1. Так как 1! = 0, оно вернет значение 1, умноженное на значение, рекурсивно вызывающее себя с 0. Так как 0 равно 0, это просто возвращает 1, который используется одним слоем для возврата 1, который затем используется в верхнем слое этой рекурсии для возврата 2.

Common Lisp имеет функцию trace, которая позволит вам увидеть, когда вызывается функция и с каким аргументом , Обычно каждый рекурсивный вызов будет сдвинут, так что вы можете увидеть что-то вроде этого:

(fact 2) 
    (fact 1) 
     (fact 0) 

, которые могут быть полезны для понимания этой функции.

(Как указано в комментарии - эта функция не улавливает случай отрицательного ввода - но это обработка ошибок и может быть легко исправлена).

Смежные вопросы