Чем отличаются локальные переменные и функции, определенные через defvar и defun от let/let* и flet/labels? (последние я буду для краткости записывать *-let)
Я понимаю, что первые локальны внутри функции, в которой они определены, вторые - внутри *-let-формы. Неужели это единственное отличие? У let есть дополнительная плюшка - временное перебиндивание внешних переменных; у flet этого нет, отчего его использование для меня становится еще более загадочным.
Ок, в глобальном скопе или даже в очень большой функции может понадобиться в двух разных местах иметь две функции или переменные с одинаковыми именами, тут хоть и с натяжкой еще можно предположить полезность *-let.
До поры, до времени я особо не акцентировал на этом внимания, но, полистав некоторые наобум взятые исходники, обнаружил, что везде предпочитают писать так:
(defun foo (x)
(labels ((foo-req (depth)
...))
(foo-req 0)))
вместо более (для меня) логичного:
(defun foo (x)
(defun foo-req (depth)
...)
(foo-req 0))
Чувствую, что неспроста пишут именно так, но понять, почему, не могу. Ведь дело не в том, что десяток лишних скобок придает большей брутальности написанному коду? :)
Если я думаю по-сишному, и непонимание исходит из этого, прошу помочь переместить точку сбо^W^W^Wначать мыслить в нужном русле.