2019년 1월 2일 수요일

[on lisp] 2.3 함수 매개변수

2.3 Functional Arguments
함수를 객체처럼 쓴다는 말은, 매개변수로 다른 함수에 던질 수도 있다는 말이다.
이 기능은 리스프의 상향식 프로그래밍에서 중요한 역할을 한다.

함수를 객체로 허용하는 언어는 이것을 호출하는 기능을 제공해야 한다.
일반적으로 "apply"라는 함수에 두개의 매개변수(함수, 매개변수리스트)를 보내서 실행한다.

(+ 1 2)
(apply #'+ '(1 2))
(apply (symbol-function '+) '(1 2))
(apply #'(lambda (x y) (+ x y)) '(1 2))

커먼 리스프에서는 첫번째 야규먼트가 리스트로 들어가고 뒤에 매개변수들이 cons로 뒤에 붙는다.
그래서 아래와 같은 것도 가능하다.
(apply #'+ 1 '(2))
이러면 3이 나온다.

만약 매개변수가 리스트로 들어오는 것이 맘에 들지 않는다면, funcall을 사용하면 된다.
(funcall #'+ 1 2)
많은 빌트인 함수들은 함수를 매개변수로 받는다.
가장 빈번하게 사용되는 곳은 함수매핑이다.
예를들어 mapcar는 2개 이상의 매개변수를 받는다.
함수와 하나 혹은 그 이상의 리스트들을 받아서 각 리스트 요소에 함수를 적용시킨다.
(mapcar #'(lambda (x) (+ x 10)) '(1 2 3))
(mapcar #'+
        '(1 2 3)
  '(10 100 1000))
sort, remove-if 기능도 마찬가지다.
(sort '(1 4 2 5 6 7 3) #'<)
(remove-if #'evenp '(1 2 3 4 5 6 7))
아래 remove-if 기능을 살펴보자.
(defun our-remove-if (fn lst)
  (if (null lst)
      nil
   (if (funcall fn (car lst))
       (our-remove-if fn (cdr lst))
    (cons (car lst) (our-remove-if fn (cdr lst))))))
여기서 주목해야 할 점은 fn에 #'(sharp-quote)가 없이 사용되고 있다는 점이다.
함수는 객체이고, 해당 변수는 일반 변수처럼 함수를 가질 수 있다.
그러니까 #'(sharp-quote)는 심볼(이름)에서 함수를 빼낼때 사용되는 것이다.

댓글 없음:

댓글 쓰기