Emacs Lisp에서 샤프 작은따옴표(#') 기호의 의미

Emacs // 2024년 06월 29일 작성

Emacs Lisp 코드에서 샤프(#, sharpsign)와 작은따옴표(', single-quote)를 붙인 기호가 종종 쓰이는데 무슨 의미인지 대충 알아보자.

많이 쓰이는 예

#' 기호는 보통 함수 핸들러를 전달할 때 많이 보인다. 아래의 예는 개인적으로 사용하는 설정 코드에서의 예인데 Doom Emacs 전용 코드도 일부 포함되어 있다.

(add-to-list 'treemacs-ignored-file-predicates #'treemacs-ignore-local-cache))
(add-hook 'kill-emacs-hook #'my-exit-function)

;; Doom Emacs config.el
(add-hook! 'markdown-mode-hook #'my-text-styles)
(map! "C-c a l" #'my-miracle-function)

여기서 #'가 붙어있는 심볼들이 모두 함수일 것 같은 기분이라면 바로 정답이다.

Function Abbreviation

#'로 샤프와 작은따옴표를 붙여 쓰면 Function Quote 즉 함수 인용이라는 기능이 된다. 다른 말로 Function Abbreviation이라다 표현하기도 한다. 다른 언어에선 콜백 혹은 핸들러 정도의 의미와 비슷하다. 예를 들자면 이런 식이다.

(defun do-what (f)
  (funcall f "This is the what!"))

(do-what #'message)

위 예에서 do-what이라는 함수의 첫번째 인자로 함수를 전달하기 위해 #'가 함수 이름 앞에 붙어있다. 이렇게 함수를 어딘가 전달해야 할 때 #'가 종종 사용된다.

그래서 무슨 차이일까?

사실 위 모든 예제에서 #'을 그냥 '으로 바꿔도 아무 문제 없이 동작한다. 함수 인용이든 인용이든 둘 다 인용이니 말이다.

그렇다면 #'는 도대체 왜 쓰는 걸까?

개인적인 추측이지만 명시적인 표현 때문에 쓴다고 생각된다. 즉 여기에는 반드시 함수 인용이 들어와야 할 자리이고 그래서 함수를 인용해서 넘긴다는 의미로 #'을 명확하게 표기한다고 생각한다.

다르게 말해서 #'를 표시한 자리에 함수가 아닌 다른 심볼이나 리스트 등을 넣으면 안 된다는 말이 된다. 실제로 여기에 함수가 아닌 것을 넣으면 호출 시점에서 에러가 발생한다.

(funcall #'(1 2 3) "parameter")

함수가 와야 할 자리에 리스트가 들어가 있으니 "Invalid Function"이라는 오류가 발생한다.

결국 #'는 가독성을 좋게 만들기 위한 Lisp 만의 특수한 꾸밈 요소라고 생각된다. 물론 다른 언어에만 익숙한 사람이 보면 '#'든 암호 같은 건 마찬가지 겠지만 말이다.

관련된 글들