2014-01-19 2 views
1

Я искал в Интернете ответы, но не имел большой удачи, поэтому, пожалуйста, простите меня, если это повторный вопрос. Я сформулирую свои вопросы: = (?) Таким образом и в комментариях в коде, который следует также. (Я использую Emacs с CLISP и Slime): (?)Необходимые концепции и терминология

;; is this called nested function or partial application or what(?) 

    (defun create-function(a) 
     (defun add-function(x)(+ x a))) 

    ->(create-function 8) 
    ->ADD-FUNCTION 
    ->(add-function 3) 
    ->11 

я могу увидеть преимущества сцепления этих «частичных приложений», но это не выделки сами по себе, да ладно, давайте проверить, если мой наблюдения являются правильными:

;; the 'let statement *binds* 'loc to the 'clos object with 10 being the argument 
    ;; for the formal parameter x. when funcall is applied to 'loc with 20 for y, the 
    ;; lambda expression substitutions are complete and 200 is returned(?). 

    (defun close(x) 
     (lambda(y)(* x y))) 
    ->CLOSE 
    (let ((loc (close 10))) 
     (funcall loc 20)) 
    ->200 

Приведенный выше код является закрытие из-за объема из «LOC в» пусть заявление (?): если «Клоса был изменчивый переменной было бы только изменить значение в то время как внутри «Пусть заявление (?) ... я думаю. Наконец, если кто-нибудь может сказать мне, как получить макрос step, чтобы играть хорошо с вышеупомянутыми функциями, это очень помогло бы (они сразу оценивают ...) Спасибо.

ответ

0

Первый пример можно назвать вложенной функцией и частичной оценкой. Но следующий пример более идиоматичен. Оба можно также назвать ручной каррированием, хотя обычно каррирование понимается как автоматическая процедура. Вы можете использовать каррирование в Лиспе, как это (один вариант):

(defun curry (function &rest arguments) 
    (lambda (&rest more) 
    (multiple-value-call function 
         (values-list arguments) (values-list more)))) 

Говоря о закрывающего вопрос: funcall под let не замыкание - замыкание является определение функции внутри let. На самом деле, ваш первый пример - это закрытие, потому что вы определяете функцию внутри другой функции, и каждая функция вводит что-то похожее на привязку let.

Еще более канонический пример в вашем случае будет:

(let ((z 10)) 
    (defun close (x) 
    (* x z)) 
->CLOSE 
(close 20) 
->200 

Здесь z переменная захвачена в затворе.

+0

Извините за поздний отклик, отказ оборудования и больной питомец сделали меня очень занятой. Я был немного смущен ответами, которые я получил, поэтому я просто провел последний час, расшифровывая г-на Стил и г-на Сейбела на обязательных формах и закрытиях. Теперь я чувствую себя более уверенно в своем понимании и терминологии. Я напишу общий ответ позже. – macrolyte

0

Первый пример не является вложенной функцией или частичным приложением. Вместо этого он вычисляет внутренний defun, переопределяя глобально видимый add-function, каждый раз, когда вызывается внешняя функция. Я не думаю, что есть какое-то конкретное имя для этого шаблона.

Общие Lisp имеет лексически ограниченные вложенные функции формами flet и labels.

Во втором примере, функция возвращает close укупорочного (значение функции, которая относится к переменным лексический связанным вне тела этой функции). То, что вы делаете с этим возвращаемым значением, не влияет на его ценность.

step будет бесполезным в SBCL, если вы не запрашиваете дополнительную информацию об отладке. Сделайте это, поставив эту форму перед функцией:

(proclaim '(optimize (debug 3))) 
Смежные вопросы