← Архив: Common Lisp

вопрос к знатокам

Author: · 06.09.2011 11:57
· original author: stairs
возможно ли в CL создать безымянную(лямбда) рекурсивную функцию?
· original author: archimag
Так безымянную или лямбду? ;) См. alexandria:named-lambda
· original author: andy128k
Да. Есть такая вещь: анафорическая лямбда.
(defmacro alambda (params &body body)
   `(labels ((self ,params ,@body))
        #'self))
· original author: Love5an
Через Z-комбинатор :)
(lambda (f)
  ((lambda (x) (funcall f (lambda (y) (funcall (funcall x x) y))))
   (lambda (x) (funcall f (lambda (y) (funcall (funcall x x) y))))
)
)

;; Вычисление факториала, рекурсивно:

(funcall
  (funcall
    (lambda (f)
      ((lambda (x) (funcall f (lambda (y) (funcall (funcall x x) y))))
       (lambda (x) (funcall f (lambda (y) (funcall (funcall x x) y))))
)
)

    (lambda (f)
      (lambda (n)
        (if (zerop n)
          1
          (* n (funcall f (1- n)))
)
)
)
)

  5
)

;; ==> 120
· original author: andy128k
Отжёг!
· original author: stairs
Круто!
· original author: orivej
http://www.xach.com/naggum/articles/3219426877120035@naggum.net.html:
> Has anyone ever thought it would be nice to recurse an anonymous lambda?
(defun jestcall (function &rest arg)
  (apply function function args)
)

 Where you would funcall a function that would funcall itself by name to
 make a recursive call, you jestcall a function that jestcalls its first
 argument to make a recursive call.
· original author: LinkFly
А к чему это? Если серьёзно, labels всё решает, и не фиг извращаться)
· original author: orivej
Скажем, для факториала:
(defun jestcall (function &rest args)
  (apply function function args)
)

(jestcall
 (lambda (f n)
   (if (zerop n)
       1
       (* n (jestcall f (1- n)))
)
)

 5
)

Ещё, jestcall — это «грязный» вариант первой же функции в этой статье про комбинаторы неподвижной точки: http://okmij.org/ftp/Computation/fixed-point-combinators.html.