2018년 1월 25일 목요일

[clojure] 리습-1 너 누구냐

클로저는 리습-1이란다. (그렇단다.)

리습-1

함수나 값 바인딩에 있어서 이름을 같은 방식으로 해석.

리습-2

심벌이 함수 호출 위치에 있는지 인지 위치에 있는지 등의 맥락에 따라 다르게 해석 (다른 곳에서 알아보니 함수이름이 저장되는 곳이랑 변수이름이 저장되는 곳이 다를 수도 있다네... 그러니 같은 변수이름 함수이름이 똑같아도 된다는 말인 것 같다.)

리습-1의 단점은 이름에 의존하기에 어쩌다 그 이름을 겹치게 사용하면 문제가 생길 수 있다는 것이다. (음... 다른 리습을 사용안해봐서 잘 모르겠다)
이런걸 포기하고 바인딩에 대한 단순성을 가지기 위해 리습-1을 사용하는 듯 하다.

어쨋든

클로저는 리습-1의 해석방식을 적용하여 명확한 구현과 심벌을 조회할 때 혼란에 빠지지않고 로직에 집중하라는 말씀이시다. (사실 잘모름...)
클로저의 단순성이 무엇인가
(defn best [f xs]
  (reduce #(if (f % %2) % %2) xs))
(best > [1 2 3 4 5 6])
6
위 best함수는 > 함수를 받아 몸체 안에서 f로 호출한다. (이렇게 함수, 값이 이름바인딩으로 아주 일괄적)
이게 뭐? 라고 생각한하면

리습-2(커먼리습)은 명시적으로 함수를 호출해주는 다른 함수 (funcall 이라고 하네?)의 도움이 필요하다. 마찬가지로 어떤 함수를 넘기려면 다음과 같이 함수 객체임을 표시하는 태그를 사용해야함.

;; 이거 클로저아님 커먼리습 코드임 실행안되니까 따라치지 말길.
(defun best (f xs)
  (reduce #'(lambda (l r)
             (if (funcall f l r) l r))
         xs))

(best #'>' '(1 2 3 4 5 6))
뭐 이상해 보이는건 내가 커먼리습을 몰라서 그런거지 절대 클로저가 좋아서 그런건 아닌듯. 그냥 차이를 알고 있자.


댓글 없음:

댓글 쓰기