이 글의 내용은 다음을 참조하여 작성되었습니다.🙇♂️
조건에 따라 연산하는 방법을 고르는 표현 수단은 어떻게 생겨났을까?
양수인지 음수인지 0인지 따져보고 절대값을 달리 계산하는 규칙이 있을 때 프로시저로 표현하는 방법을 알아보자.
- 예시
|x| = { x (x>0일 경우),
0 (x=0일 경우),
-x (x<0일 경우) }
위와 같은 기법을 case analysis(갈래 나누기)라고 하며
Lisp에선 cond(:condinational) 문법(특별한 형태)로 나타낸다고 한다.
(define (abs x)
(cond ((> x 0) x)
((= x 0) 0)
((< x 0) (- x))))
조건식의 문법을 간추리면 다음과 같다.
(cond (<p1 e1>)
(<p2 e2>)
...
(<p𝙣 e𝙣>)
cond 뒤에 두 식을 괄호로 묶어 놓은 (<p1, e1>) clause(절)이 여러개 나온다.
두 식 가운데 첫 식을 predicate(술어)라 하며
그 답은 언제나 참 또는 거짓 가운데 하나를 내놓는다.
조건식의 값을 구하는 방법
1. 먼저 술어<p₁>의 답을 구한다.
2. 그 답이 거짓이면 <p₂>의 답을 구한다.
3. 이 마저 거짓이면 <p₃>의 답을 구하는 패턴을 반복한다.
4. 반복 중, 처음으로 참이라는 답을 내놓는 술어가 나오면
그 술어와 짝을 이루는 consequent expression(결과식) 의 값을 구한다.
5. 결과 식의 값을 전체 조건 식의 값으로 삼는다.
- 참이라는 대답을 내놓는 <'p'>가 하나도 없을 때에는 cond 식의 값을 알 수가 없다( 즉, 정의할 수 없다.)
술어는 참이나 거짓이라고 대답하는 프로시저 또는 식을 가리킬 때 널리 쓰는 말이다. 다음 프로시저를 통해 특별한 형태를 알아보자.
- 절대값 프로시저 abs 몸 속에선 primitive predicate >, =, ﹤를 쓰고 있다.
- 두 수를 인자로 받아서 앞 수가 뒤 수보다 크거나 작거나 같은지 따지고, 참이나 거짓으로 답을 내놓는 기본 술어 프로시저다.
(define (abs x)
(cond ((﹤ x 0) (-x))
(else x))
'x가 0보다 작으면 -x, 아니면 x를 그대로 돌려준다.'
여기서 else는 cond의 마지막 절에서 <'p'> 자리에 올 수 있도록 따로 만든 이름(특별한 기호special symbol)인데,
앞서 나온 모든 절을 거쳐 else 절에 이르렀을 때, else와 짝이 되는 의 값을 cond의 값으로 삼으라는 뜻이다.
else라는 이름이 따로 없어도, 마지막 절<'p'> 자리에 언제나 true라고 대답하는 식을 쓰기만 하면 else를 쓴 것이나 마찬가지다.
고쳐 쓴 절대값 프로시저는 다음과 같다.
(define (abs x)
(if ﹤ x 0)
(-x)
x))
이번엔 if를 썼다.
따져 볼 경우가 둘 밖에 없을 때 쓰기 좋은 문법이며,
간추리면 다음과 같다.
(if ﹤predicate>﹤consequent>﹤alternative>)
if 식의 값을 구할 때 실행기는
﹥, =, ﹤와 같은 기본 술어 말고도, 복잡한 논리나 판단을 나타낼 수 있게끔 논리 식을 묶는 연산도 있다.
흔히 쓰이는 논리 연산 세가지는 다음과 같다.
and와 or는 보통 프로시저와 달리 인자가 되는 모든 식의 값을 구하지 않기 때문에 특별한 형태로 정의해야 한다. 한편 not은 보통 프로시저다. 논리 연산을 어떻게 쓰는지 보기 위해 x가 5﹤x﹤10 안에 있는지 알아보는 식을 적어 보자.