Ради другого объяснения:
Здесь мы начинаем
(my-length '(a b c d))
Заполняя аргумент в функцию, это превращается в
(if (empty? '(a b c d))
0
(add1 (my-length (rest '(a b c d)))))
Очевидно, что '(a b c d)
не пусто. Таким образом, оценивается "else" случай if:
(add1 (my-length (rest '(a b c d))))
(add1 (my-length '(b c d)))
Теперь, что означает (my-length '(b c d))
? Что ж, если мы скопируем и вставим тело функции в нашу последнюю строку, мы получим:
(add1 (if (empty? '(b c d))
0
(add1 (my-length (rest '(b c d))))))
Продолжая...
(add1 (add1 (my-length (rest '(b c d)))))
(add1 (add1 (my-length '(c d))))
Так продолжается до тех пор, пока мы не получим пустой список:
(add1 (add1 (add1 (add1 (if (empty? '())
0
(add1 (my-length (rest '()))))))))
'()
пусто, поэтому оператор if возвращает 0:
(add1 (add1 (add1 (add1 0))))
(add1 (add1 (add1 1)))
(add1 (add1 2))
(add1 3)
4
Как будто мы погружаемся в функцию все глубже и глубже, потому что на каждый шаг, который мы делаем, нам нужно сделать еще один, чтобы действительно оценить то, что у нас есть.
Чем это отличается от (add1 '(a b c d))
? Из того, как проводилась оценка, видно, что add1
на самом деле никогда не применялось к a, b, c или d. Мы даже не проверили, что было в списке. У вас мог бы быть список из четырех списков, каждый из которых содержал бы списки списков, и он все равно оценивал бы.
В частности, сказать (add1 '(a b c d))
все равно, что сказать «Сколько будет 1 плюс клубника?», а ваша функция больше похожа на:
«Сколько вещей в этом списке?»
«Ну, если ты ничего не видишь сверху ((first my-list)
), то точно ничего нет».
"Хорошо, хорошо... Я вижу "а" сверху!"
"Хорошо! Убери это. Это как минимум 1 в списке."
"Хорошо, но сколько в остальных?"
«Как насчет того, чтобы попробовать то же самое еще раз? Просто продолжайте вынимать элементы из верхней части списка, пока список не станет пустым. Затем мы соберем его обратно и будем считать по мере продвижения».
«Хорошо, я вынул их все. Теперь я собираюсь вставить их обратно: d — это 1, c — это 2, b — это 3 и a — это 4!»
"Ну вот, 4 в списке!"
person
ಠ_ಠ
schedule
17.06.2014
(add1 ...) === (+ 1 ...)
. Итак,(length l) === (+ 1 (length (rest l)))
, еслиl
— непустой список, и0
, еслиl
— пустой список. Итак,(length '(x y z)) === (+ 1 (+ 1 (+ 1 0))) === 3
. - person Joshua Taylor   schedule 16.06.2014