조건문: if, cond, and, or

조건문: if, cond, and, or

조건 분기는 Racket 프로그램에서 가장 자주 만나는 형태 중 하나예요. if부터 시작해서 분기가 여럿일 때 쓰는 cond, 그리고 여러 조건을 묶는 andor까지 차례로 살펴볼게요.

출처: Racket Reference

본문

조건문에 대한 소개는 The Racket Guide의 Conditionals에서 다룹니다.

if 구문

syntax

(if test-expr then-expr else-expr)

test-expr를 평가합니다. 그 결과가 #f가 아닌 어떤 값이든 생기면 then-expr가 평가되고, 그 결과가 if 폼의 결과가 됩니다. 그 외의 경우에는 else-expr가 평가되고, 그 결과가 if 폼의 결과가 됩니다. then-exprelse-exprif 폼에 대해 꼬리 위치(tail position)에 있습니다.

예시:

> (if (positive? -5) (error "doesn't get here") 2)
2

> (if (positive? 5) 1 (error "doesn't get here"))
1

> (if 'we-have-no-bananas "yes" "no")
"yes"

cond 구문

syntax

(cond cond-clause ...)

cond-clause = [test-expr then-body ...+]
            | [else then-body ...+]
            | [test-expr => proc-expr]
            | [test-expr]

cond에 대한 소개는 The Racket Guide의 Chaining Tests: cond에서 다룹니다.

else로 시작하는 cond-clause는 마지막 cond-clause여야 합니다.

cond-clause가 하나도 없으면 결과는 #<void>입니다.

[else then-body ...+]만 있는 경우에는 then-body들이 평가됩니다. 마지막 then-body를 제외한 나머지의 결과는 무시됩니다. cond 폼에 대해 꼬리 위치에 있는 마지막 then-body의 결과가 전체 cond 폼의 결과가 됩니다.

그 외의 경우에는 첫 번째 test-expr가 평가됩니다. 그 결과가 #f라면, 결과는 나머지 cond-clause들을 가진 cond 폼과 같으며, 이는 원래 cond 폼에 대해 꼬리 위치에 있습니다. 그 외의 경우 평가는 cond-clause의 형태에 따라 달라집니다:

[test-expr then-body ...+]

then-body들이 순서대로 평가되고, 마지막 then-body를 제외한 나머지의 결과는 무시됩니다. cond 폼에 대해 꼬리 위치에 있는 마지막 then-body의 결과가 전체 cond 폼의 결과를 제공합니다.

[test-expr => proc-expr]

proc-expr가 평가되어 인자를 하나 받는 프로시저를 만들어야 하며, 그렇지 않으면 exn:fail:contract 예외가 발생합니다. 이 프로시저는 cond 표현식에 대해 꼬리 위치에 있는 test-expr의 결과에 적용됩니다.

[test-expr]

test-expr의 결과가 cond 폼의 결과로 반환됩니다. test-expr는 꼬리 위치에 있지 않습니다.

예시:

> (cond)

> (cond
   [else 5])
5

> (cond
   [(positive? -5) (error "doesn't get here")]
   [(zero? -5) (error "doesn't get here, either")]
   [(positive? 5) 'here])
'here

> (cond
   [(member 2 '(1 2 3)) => (lambda (l) (map - l))])
'(-2 -3)

> (cond
   [(member 2 '(1 2 3))])
'(2 3)

else 구문

syntax

else

cond와 같은 폼 안에서 특별하게 인식됩니다. 표현식으로서의 else 폼은 문법 오류(syntax error)입니다.

=> 구문

syntax

=>

cond와 같은 폼 안에서 특별하게 인식됩니다. 표현식으로서의 => 폼은 문법 오류입니다.

and 구문

syntax

(and expr ...)

and에 대한 소개는 The Racket Guide의 Combining Tests: and and or에서 다룹니다.

expr이 하나도 없으면 결과는 #t입니다.

expr이 하나만 있으면 그것은 꼬리 위치에 있으므로, and 표현식의 결과는 그 expr의 결과입니다.

그 외의 경우에는 첫 번째 expr이 평가됩니다. 그 결과가 #f라면 and 표현식의 결과는 #f입니다. 그 외의 경우 결과는 나머지 expr들을 꼬리 위치에 가진 and 표현식과 같습니다.

예시:

> (and)
#t

> (and 1)
1

> (and (values 1 2))
1
2

> (and #f (error "doesn't get here"))
#f

> (and #t 5)
5

or 구문

syntax

(or expr ...)

or에 대한 소개는 The Racket Guide의 Combining Tests: and and or에서 다룹니다.

expr이 하나도 없으면 결과는 #f입니다.

expr이 하나만 있으면 그것은 꼬리 위치에 있으므로, or 표현식의 결과는 그 expr의 결과입니다.

그 외의 경우에는 첫 번째 expr이 평가됩니다. 그 결과가 #f가 아닌 값이라면 그 결과가 or 표현식의 결과입니다. 그 외의 경우 결과는 나머지 expr들을 꼬리 위치에 가진 or 표현식과 같습니다.

예시:

> (or)
#f

> (or 1)
1

> (or (values 1 2))
1
2

> (or 5 (error "doesn't get here"))
5

> (or #f 5)
5

더 알아보기