수색…


통사론

  • (함수 이름); 그 이름의 함수 객체를 검색한다.
  • # '이름; 통사론 (함수명)
  • (기호 - 기능 기호); symbol에 바인딩 된 함수를 반환합니다.
  • (funcall 함수 args ...); args로 함수 호출하기
  • (함수 arglist 적용); 리스트에 주어진 인자를 가진 함수를 호출한다.
  • (함수 arg1 arg2 ... argn arglist 적용); arg1, arg2, ..., argn에 의해 주어진 인자를 가진 함수를 호출하고 나머지는 arglist에 넣는다.

매개 변수

매개 변수 세부
이름 함수의 이름을 짓는 일부 (평가되지 않은) 기호
상징 상징
기능 호출 될 함수
args ... 0 개 이상의 인수 (인수하지리스트)
arglist 함수에 전달할 인수가 들어있는 목록
arg1, arg2, ..., argn 각 함수는 함수에 전달할 단일 인수입니다.

비고

Lisp과 비슷한 언어에 대해서 이야기 할 때, Lisp-1과 Lisp-2로 알려진 것을 공통적으로 구분합니다. Lisp-1에서 기호는 값을 가지고 있고 기호가 함수를 참조하면 그 기호의 값은 그 함수가됩니다. Lisp-2에서 기호는 별도의 연관된 값과 함수를 가질 수 있으므로 값 대신 기호에 저장된 함수를 참조하려면 특수 형식이 필요합니다.

Common Lisp는 기본적으로 Lisp-2이지만 실제로 심볼이 참조 할 수있는 것 이상의 2 개의 네임 스페이스가 있습니다. - 심볼은 값, 함수, 유형 및 태그를 참조 할 수 있습니다.

익명 함수 정의하기

Common Lisp의 함수는 퍼스트 클래스 값 입니다. 익명 함수는 lambda 를 사용하여 만들 수 있습니다. 예를 들어, 다음은 funcall 사용하여 호출하는 3 개의 인수의 함수입니다.

CL-USER> (lambda (a b c) (+ a (* b c)))
#<FUNCTION (LAMBDA (A B C)) {10034F484B}>
CL-USER> (defvar *foo* (lambda (a b c) (+ a (* b c))))
*FOO*
CL-USER> (funcall *foo* 1 2 3)
7

익명의 기능을 직접 사용할 수도 있습니다. Common Lisp은이를위한 구문을 제공합니다.

((lambda (a b c) (+ a (* b c)))    ; the lambda expression as the first
                                   ; element in a form
  1 2 3)                           ; followed by the arguments

익명 함수는 전역 함수로 저장할 수도 있습니다.

(let ((a-function (lambda (a b c) (+ a (* b c)))))      ; our anonymous function
  (setf (symbol-function 'some-function) a-function))   ; storing it

(some-function 1 2 3)                                   ; calling it with the name

따옴표 붙은 람다 식은 함수가 아닙니다.

따옴표 붙은 람다 식은 Common Lisp의 함수가 아닙니다. 작동하지 않습니다 .

(funcall '(lambda (x) x)
         42)

인용 된 람다 식을 함수로 변환하려면 coerce , eval 또는 funcall .

CL-USER > (coerce '(lambda (x) x) 'function)
#<anonymous interpreted function 4060000A7C>

CL-USER > (eval '(lambda (x) x))
#<anonymous interpreted function 4060000B9C>

CL-USER > (compile nil '(lambda (x) x))
#<Function 17 4060000CCC>

기존 함수 참조하기

Common Lisp의 심볼은 바인딩 될 변수를위한 슬롯과 바인딩 될 함수를위한 별도의 슬롯을 가지고 있습니다.

이 예제의 이름은 설명을위한 것입니다. 전역 변수는 foo 이지만 *foo* 지정하면 안됩니다. 후자의 표기법은 변수가 동적 바인딩을 사용하는 특수 변수라는 것을 분명히하기위한 규칙입니다.

CL-USER> (boundp 'foo) ;is FOO defined as a variable?
NIL
CL-USER> (defvar foo 7)
FOO
CL-USER> (boundp 'foo)
T
CL-USER> foo
7
CL-USER> (symbol-value 'foo)
7
CL-USER> (fboundp 'foo) ;is FOO defined as a function?
NIL
CL-USER> (defun foo (x y) (+ (* x x) (* y y)))
FOO
CL-USER> (fboundp 'foo)
T
CL-USER> foo
7
CL-USER> (symbol-function 'foo)
#<FUNCTION FOO>
CL-USER> (function foo)
#<FUNCTION FOO>
CL-USER> (equalp (quote #'foo) (quote (function foo)))
T
CL-USER> (eq (symbol-function 'foo) #'foo)
T
CL-USER> (foo 4 3)
25
CL-USER> (funcall foo 4 3)
;get an error: 7 is not a function
CL-USER> (funcall #'foo 4 3)
25
CL-USER> (defvar bar #'foo)
BAR
CL-USER> bar
#<FUNCTION FOO>
CL-USER> (funcall bar 4 3)
25
CL-USER> #'+
#<FUNCTION +>
CL-USER> (funcall #'+ 2 3)
5

고차 함수

Common Lisp에는 인수에 대한 함수가 전달되고 호출되는 많은 상위 순서 함수가 포함되어 있습니다. 아마도 가장 근본적인 것이 funcall 이며 apply .

CL-USER> (list 1 2 3)
(1 2 3)
CL-USER> (funcall #'list 1 2 3)
(1 2 3)
CL-USER> (funcall #'list 1 2 3 4 5)
(1 2 3 4 5)
CL-USER> (apply #'list '(1 2 3))
(1 2 3)
CL-USER> (apply #'list 1 2 '(4 5))
(1 2 3 4 5)
CL-USER> (apply #'+ 1 (list 2 3))
6
CL-USER> (defun my-funcall (function &rest args)
           (apply function args))
MY-FUNCALL
CL-USER> (my-funcall #'list 1 2 3)
(1 2 3)

예를 들어 목록의 요소에 여러 번 함수를 적용하는 많은 다른 higher-order 함수가 있습니다.

CL-USER> (map 'list #'/ '(1 2 3 4))
(1 1/2 1/3 1/4)
CL-USER> (map 'vector #'+ '(1 2 3 4 5) #(5 4 3 2 10))
#(6 6 6 6 15)
CL-USER> (reduce #'+ '(1 2 3 4 5))
15
CL-USER> (remove-if #'evenp '(1 2 3 4 5))
(1 3 5)

목록 합계

reduce 함수를 사용하여 목록의 요소를 합할 수 있습니다.

(reduce '+ '(1 2 3 4))
;;=> 10

기본적으로 reduce왼쪽 연관 감소를 수행합니다. 즉, 합계 10은 다음과 같이 계산됩니다.

(+ (+ (+ 1 2) 3) 4)

첫 번째 두 요소가 먼저 합산 된 다음 결과 (3)가 다음 요소 (3)에 추가되어 6이 생성되고, 마지막 요소 인 4가 최종 결과를 생성합니다.

이것은 ( '+'적용에서, 예를 들어 (적용하여보다 안전 (1 2 3 적용에 전달 될 수있는 인수 목록의 길이가 제한되기 때문에 4)) (참조) 인수 제한-전화 및 작동 감소 두 개의 인수 만 취하는 함수가 있습니다.

from-end 키워드 인수를 지정하면 reduce 는 목록을 다른 방향으로 처리합니다. 즉, 합계가 역순으로 계산됩니다. 그건

(reduce '+ (1 2 3 4) :from-end t)
;;=> 10

컴퓨팅이다

(+ 1 (+ 2 (+ 3 4)))

리버스 구현 및 revappend 구현

Common Lisp는 이미 역순으로 기능을 가지고 있지만 그렇지 않다면 reduce를 사용하여 쉽게 구현 될 수 있습니다. 다음과 같은 목록이 주어집니다.

(1 2 3) === (cons 1 (cons 2 (cons 3 '())))

반전 된 목록은

(cons 3 (cons 2 (cons 1 '()))) === (3 2 1)

이는 감소 의 명백한 사용은 아니지만, 우리가 "반대 개념"인 경우, xcons 와 같이

(xcons 1 2) === (2 . 1)

그때

(xcons (xcons (xcons () 1) 2) 3)

이는 감축입니다.

(reduce (lambda (x y)
          (cons y x))
        '(1 2 3 4)
        :initial-value '())
;=> (4 3 2 1)

Common Lisp은 revappend 라는 또 다른 유용한 함수를 가지고 있는데 , 이는 reverseappend 의 조합입니다. 개념적으로 목록을 뒤집어서 꼬리에 추가합니다.

(revappend '(3 2 1) '(4 5 6))
;;=> (1 2 3 4 5 6)

이것은 reduce 로 구현 될 수도 있습니다. 사실, 초기 값이 빈 목록 대신 (4 5 6) 이어야한다는 점을 제외하고 위의 역순으로 구현 한 것과 같습니다.

(reduce (lambda (x y)
          (cons y x))
        '(3 2 1)
        :initial-value '(4 5 6))
;=> (1 2 3 4 5 6)

마감

함수는 정의 된 어휘 범위를 기억합니다.이 때문에 람다를 let에 묶어서 클로저를 정의 할 수 있습니다.

(defvar *counter* (let ((count 0))
                    (lambda () (incf count))))

(funcall *counter*) ;; => 1
(funcall *counter*) ;; = 2

위의 예제에서 카운터 변수는 익명 함수에서만 액세스 할 수 있습니다. 이것은 다음 예제에서보다 명확하게 볼 수 있습니다.

(defvar *counter-1* (make-counter))
(defvar *counter-2* (make-counter))

(funcall *counter-1*) ;; => 1
(funcall *counter-1*) ;; => 2
(funcall *counter-2*) ;; => 1
(funcall *counter-1*) ;; => 3

함수를 사용하고 함수를 반환하는 함수 정의

간단한 예 :

CL-USER> (defun make-apply-twice (fun)
           "return a new function that applies twice the function`fun' to its argument"
           (lambda (x)
             (funcall fun (funcall fun x))))
MAKE-APPLY-TWICE
CL-USER> (funcall (make-apply-twice #'1+) 3)
5
CL-USER> (let ((pow4 (make-apply-twice (lambda (x) (* x x)))))
           (funcall pow4 3))
81

고전적 예 함수 조성물 (FgH) (X) = F (g (H (X)) :

CL-USER> (defun compose (&rest funs)
           "return a new function obtained by the functional compositions of the parameters"
           (if (null funs) 
               #'identity
               (let ((rest-funs (apply #'compose (rest funs))))
                 (lambda (x) (funcall (first funs) (funcall rest-funs x))))))
COMPOSE
CL-USER> (defun square (x) (* x x))
SQUARE
CL-USER> (funcall (compose #'square #'1+ #'square) 3)
100  ;; => equivalent to (square (1+ (square 3)))


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow