Лисп/Функции: различия между версиями

Содержимое удалено Содержимое добавлено
Новая: <div style="max-width:60em;margin:1em auto 0 4%;"> Если вы уже знакомы с каким-нибудь императивным языком типа Си или Perl, то п...
 
Нет описания правки
Строка 6:
Определение функции основано на [[w:Лямбда_исчисление|лямда-исчислении]]. Исходный вариант записи лямда-выражения, предложенный его автором Черчем, выглядит как
<math>\lambda(x1,x2...)fn</math>. Лисп-запись выглядит так: <code>(lambda (x1 x2 ...) fn)</code>. x1, x2 ... - формальные параметры, то есть они могут быть безболезненно заменены на другие без изменении значения лямбда-выражения. Благодаря этому лямбда-выражения способны обеспечить больший уровень абстракции, чем обычные функции.
 
Например, сумму квадратов на языке лямбда-выражений можно определить как <code>(lambda (x y) (+ (* x x) (* y y)))</code>. Вызов лямбда-функции с конкретными значениями <code>((lambda (x y) (+ (* x x) (* y y))) 2 3) => (+ (* 2 2) (* 3 3)) => 13</code> может быть сделан единожды, при желании вызвать такую функцию еще раз необходимо повторить запись еще раз. Это неудобно. Было бы удобнее написать нечто типа (сумма-квадратов 2 3). Это возможно, если вы предварительно определите функцию сумма-квадратов.
<source lang="lisp">
>> (defun сумма-квадратов (x y)
((lambda (a b) (+ (* a a) (* b b)))
x y))
</source>
Для удбства эта запись может быть сокрвщена до
<source><lang="lisp">
>> (defun сумма-квадратов (x y)
(+ (* x x) (* y y)))
</source>
Одно из преимуществ столь непривычных особенностей языка лисп в том, что вы можете написать нечто типа
<source><lang="lisp">
>> ((lambda (x)
((lambda (y)
(list x y))
'second))
'first)
<< (first second)
</source>
Здесь лямбда-выражение является '''телом''' другого лямда-вырадения. Оно так же может быть одним из его аргументов.
 
Посмотреть определение функции fn, которая уже была определена, можно с помощью функции symbol-function:
<source><lang="lisp">
>> (symbol-function 'сумма-квадратов)
<< #<function сумма-квадратов (x y) (declare (system::in-defun сумма-квадратов))
(block сумма-квадратов (+ (* x x) (* y y)))>
</source>