갈루아의 반서재




전역 변수 정의하기

LISP에서 전역 변수는 다음과 같이 설정합니다. 예를 들어 상한과 하한을 나타내는 small 과 big 변수를 정의해보겠습니다. 리스프에서 전역으로 정의된 변수를 top-level definition 이라고 부르는데요. 다음과 같이 defparameter 함수를 이용해서 top-level definition 을 정의할 수 있습니다. 

1
2
3
4
5
6
7
8
9
10
11
12
[1]> (defparameter *small* 1)
*SMALL*
[2]> (defparameter *big* 100)
*BIG*
[3]> *small*
1
[4]> *big*
100
[5]> (defparameter *big* 1000)
*BIG*
[6]> *big*
1000
cs


defparameter 라는 함수이름은 parameter 와는 사실 무관합니다. 단지 전역 변수를 정의해줄 뿐입니다. 그다음으로 오는 *small* 이라는 부분이 정의하고자하는 새로운 변수 이름입니다. 여기에서 애스터리스크(또는 earmuffs)에 둘러싸는 것은 선택사항입니다. 둘러싸지 않아도 아래에서 보듯이 아무 문제가 없습니다. 하지만 로컬 변수와 구분이 쉽기 때문에 애스터리스크로 둘러싸는게 보통입니다. 

1
2
3
4
[1]> (defparameter top 9999)
TOP
[2]> top
9999
cs


그리고 defparameter 를 통해서 전역변수를 정의하게 되면, 기존의 값을 덮어쓰게 됩니다. 아래의 경우 *big* 변수의 값이 변경된 것을 알 수 있습니다. 

1
2
3
4
5
6
7
8
[1]> (defparameter *big* 100)
*BIG*
[2]> *big*
100
[3]> (defparameter *big* 999)
*BIG*
[4]> *big*
999
cs


전역변수를 정의하는 또 다른 방법은 defvar 라는 함수를 이용하는 것입니다. 다만 이 경우에는 기존의 정의된 값을 변경하지는 않습니다. 

1
2
3
4
5
6
7
8
[1]> (defvar *foo* 777)
*FOO*
[2]> *foo*
777
[3]> (defvar *foo* 888)
*FOO*
[4]> *foo*
777
cs


리스프 코딩 에티켓

리스프에서는 함수나 인수는 괄호로 감싸야 합니다. [2]에서 보듯이 괄호가 없으면 문제가 되지만 공백([3], [4])은 아무런 문제가 되지 않습니다. 다만 보기 불편할 뿐이죠. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[1]> (defparameter *small* 1)
*SMALL*
[2]> defparameter *big* 100
 
*** - SYSTEM::READ-EVAL-PRINT: variable DEFPARAMETER has no value
The following restarts are available:
USE-VALUE      :R1      Input a value to be used instead of DEFPARAMETER.
STORE-VALUE    :R2      Input a new value for DEFPARAMETER.
ABORT          :R3      Abort main loop
 
[3]> (                defparameter
*foo*   19999 )
*FOO*
[4]> *foo*
19999
cs