갈루아의 반서재



Defining Local Functions in Lisp

flet 명령을 이용하여 로컬 함수를 만들 수 있다. 함수 선언은 함수명, 인수, 그리고 함수 본문으로 구성된다. 예를 들면 다음과 같다. 

1
2
[1]> (flet ((f (n) (+ n 10))) (f 5))
15
cs

예제에서는 하나의 인수 n 을 갖는 함수 f 를 정의했다. 함수 f 는 변수 n 에 10을 더한다. 그리고 5를 인수로 해당 함수에 집어넣으면 보는대로 15가 결과값으로 반환된다. let 을 이용하여 flet 의 범위내에 하나 이상의 함수를 정의할 수 있다. 그리고 하나의 flet 을 통해 다수의 로컬 함수를 다음과 같이 선언할 수 있다.

1
2
3
4
5
6
[4]> (flet ((f (n)
         (+ n 10))
           (g (n)
         (- n 3)))
         (g (f 5)))
12
cs

여기서는 f 와 g 로 명명된 2개의 함수를 선언했다. flet 본문에서 f, g 2개의 함수를 동시에 호출했다. 먼저 함수 f 에 인수 5를 넣어 15를 도출해낸 다음, 함수 g 에 앞선 결과값 15를 넣어 최종적으로 12라는 결과가 나왔다. 

flet 과 유사한 구조를 가진 labels 명령에 대해 알아보자. 

1
2
3
4
[1]> (labels ((a (n) (+ n 5))
              (b (n) (+ (a n) 6)))
             (b 10))
21
cs

위의 예에서 로컬 함수 a 는 주어진 수에 5를 더한다. 이어서 함수 b 를 선언한다. 여기서 함수 a 를 호출해 여기에 6을 더한다. 그리고 함수 b 에 10을 넣는다. 결과값은 21이 된다. 

위의 예에서처럼 함수 b가 함수 a 를 호출해야하는 경우에는 flet 대신에 labels 를 사용해야 한다. 만일 이 경우에 flet 을 사용한다면 다음과 같이 함수 a 는 정의되지 않았다고 나오게 된다.

1
2
3
4
5
[3]> (flet ((a (n) (+ n 5))
            (b (n) (+ (a n) 6)))
           (b 10))
 
*** - EVAL: undefined function A
cs

즉, labels 명령은 로컬 함수를 다른 함수에서 사용가능하게 해준다. 


What's the difference between “flet” and “labels” in Common Lisp?

  • flet is a special form for local function binding. Bindings are not recursive and cannot refer to each other. Each binding contains function name, arguments, and function body.

  • labels is a special form for local function binding. Bindings can be recursive and can refer to each other. Each binding contains function name, arguments, and function body.