조건문

  • if
  • cond
  • 불 연산

조건문이란?

어떻게 반응할지 결정하기

“조건문”은 주어진 상황에서 어떻게 반응할지를 결정하는 프로그래밍 용어입니다. 우리는 항상 결정을 내립니다. 만약 날씨가 좋다 공원에 가자; 그렇지 않다면 실내에서 보드 게임을 하자. 만약 연료가 다 떨어진다 주유소에 가자; 그렇지 않다면 계속 목적지를 향해 가자.

반응하기 위해 조건 평가하기

소프트웨어 역시 이러한 결정들로 가득 차있습니다. 만약 사용자의 입력이 유효하다, 그 데이터를 저장해야 한다; 그렇지 않다면 에러 메세지를 보여준다. 여기에 공통된 패턴은 조건을 테스트하고 그 조건이 인지 거짓인지에 기반하여 다른 반응을 보인다는 것입니다.

if

클로저에서 조건문을 쓸 때, 가장 기본적으로 if 연산자를 사용합니다. 다음은 데이터의 유효성을 검증하는 코드의 예제입니다.

만약 y에 40을 더한 값이 여전히 150 미만이라면 (+ y 40)을 반환하고 그렇지 않다면 -150을 반환하세요. (거북이 앱의 프레임에서 y축은 위로는 150, 아래로는 -150을 가집니다.)

참조: Conditional if

(if (< (+ y 40) 150)
  (+ y 40)
  -150))

if 연산자의 일반적인 형태

(if conditional-expression
  expression-to-evaluate-when-true
  expression-to-evaluate-when-false)

if 예제

(if (> 3 1)
  "3 is greater than 1"
  "3 is not greater than 1")
;=> "3 is greater than 1"

(if (> 1 3)
  "1 is greater than 3"
  "1 is not greater than 3")
  ;=> "1 is not greater than 3"

Truthiness

조건문의 참/거짓을 판단할 때, 클로저는 nilfalse를 거짓으로 생각하고, 그밖의 모든 것을 참으로 판단합니다. 다음 예제를 확인하세요:

참조: Truthiness

(if "anything other than nil or false is considered true"
  "A string is considered true"
  "A string is not considered true")
;=> "A string is considered true"

(if nil
  "nil is considered true"
  "nil is not considered true")
;=> "nil is not considered true"

(if (get {:a 1} :b)
  "expressions which evaluate to nil are considered true"
  "expressions which evaluate to nil are not considered true")
;=> "expressions which evaluate to nil are not considered true"

연습문제 1: 프레임 안의 Y값

  • y(세로 좌표)를 인자로 가지는 y-within-frame 함수를 만드세요.
  • 슬라이드의 예제를 사용하세요.
  • y-within-frame함수는 150을 넘지 않는다면 y값을 반환해야 합니다.

;; if example
(if (< (+ y 40) 150)
  (+ y 40)
  -150))
;; usage of y-within-frame function
(y-within-frame 80)    ;=> 120
(y-within-frame 180)   ;=> -150

cond

if 연산자는 한 개의 조건만을 가집니다. 다수의 조건을 사용하고 싶을 때, if는 좋은 선택이 아닙니다. 이 경우에는 아주 많이 중첩된 if문을 사용해야 합니다. 다수의 상황들을 묶기 위해서는 cond 연산자가 적합합니다.

예제를 봅시다. 만약 y에 40을 더한 값이 150을 초과할 경우 첫번째 형태를 계산하세요. 이 경우에는 -150을 반환합니다. 만약 y에 40을 더한 값이 -150 미만일 경우에는 두번째 형태를 계산하세요. 이 경우에는 150을 반환합니다. 만약 두 조건 모두 거짓일 경우, :else를 계산하세요. 이 경우에는 y에 40을 더한 값을 반환합니다. 만약 이 함수를 거북이 앱에서 사용할 경우, 우리는 거북이를 프레임의 세로축 내에서만 있도록 할 수 있습니다.

참조: Conditional cond

(cond
  (> (+ y 40) 150) -150
  (< (+ y 40) -150) 150
  :else (+ y 40)))

cond 연산자의 일반적인 형태

(cond
  predicate1 expression-to-evaluate-when-predicate1-is-true
  predicate2 expression-to-evaluate-when-predicate2-is-true
  ...
  :else expression-to-evaluate-when-all-above-are-false)

연습문제 2: 프레임 안의 Y값 - part 2

앞의 excercise에서 작성한 y-within-frame 함수에는 문제가 있습니다. 만약 주어진 y값이 -1000일경우 함수는 -960을 반환합니다. 프레임에서 가장 아래의 y값은 -150이므로 -960은 이를 넘습니다. 거북이는 보이지 않는 영역으로 가게 될 것입니다. 거북이를 실제 프레임 내에서만 있게하도록 cond를 사용해 봅시다.

  • y(세로좌표)를 인자로 갖는 y-witin-frame-cond 함수를 만드세요.
  • 슬라이드의 cond예제를 사용하세요.
  • 함수는 -150과 150사이의 값만을 반환해야 합니다.

;; usage of y-within-frame-cond function
(y-within-frame-cond 200)    ;=> -150
(y-within-frame-cond -200)   ;=> 150
(y-within-frame-cond 0)      ;=> 40

and, or, not을 사용한 불연산

if는 오직 한가지만 평가할 수 있다는 한계가 있습니다. 불 연산을 사용한다면 여러 개의 조건을 평가할 수 있습니다. __불 연산__은 조건들을 and,or,not을 이용하여 묶어서 값을 평가합니다.

이전에 프로그래밍할 때 이 개념을 본 적이 없다면, 이것이 당신이 평소에 사물을 바라보는 것과 같은 방식을 따른다는 것을 기억하세요. __and__는 모든게 참일 때 참입니다. __or__는 하나–혹은 둘다–가 참일 때 참입니다. __not__은 조건이 거짓일 때 참입니다.

진리표

and, or, not은 다른 함수들처럼 행동합니다.(정확히는 함수는 아니지만 함수처럼 행동합니다.) 그렇기 때문에 이것들은 앞서 산술 연산에서 본 _prefic 표기법_을 따릅니다.

x y (and x y) (or x y) (not x) (not y)
false false false false true true
true false false true false true
true true true true false false
false true false true true false

and, or, not 조합

and, or, not은 조합해서 사용할 수 있으며 이 경우에는 읽기 어려울 수 있습니다. 다음 예제를 봅시다:

(defn leap-year?
  "Every four years, except years divisible by 100, but yes for years divisible by 400."
  [year]
  (and (zero? (mod year 4))
       (or (zero? (mod year 400))
           (not (zero? (mod year 100))))))

[보너스] cond, and, or, not 조합

지금까지 cond, and, or, not을 배웠습니다. 이것들을 조합해서 만들 수 있는 함수는 무엇이 있을지 생각해 봅시다. 다음 예제를 봅시다.

(defn true-or-false?
  "Given op, returns true or false"
  [op]
  (let [x true
        y false]
    (cond
      (= op :and) (and x y)
      :else false)))

(defn correct?
  "Given op and ans, returns message whether ans was corret or not"
  [op ans]
  (if (= ans (true-or-false? op))
      "You won"
      "You lost"))

연습문제 3: [보너스] true-or-false? 함수 완성하기

앞 슬라이드에 나오는 true-or-false? 함수는 :and만을 사용했습니다. 함수에 :or, :not연산자를 추가해 봅시다.

  • myprojectcore.clj와 InstaREPL을 사용하세요.
  • cond 안에(= op :or)(= op :not)을 추가하세요.
  • :not에는 인수에 대해 x와 y중 하나를 택하세요.
;; usage of correct? function
(corret? :and false)   ;=> "You won"
(corret? :or false)    ;=> "You lost"
(corret? :not true)    ;=> "You won"  (this may be "You lost")

첫번째 슬라이드로 돌아가거나 curriculum outline으로 가세요.