Skip to content

Latest commit

 

History

History
372 lines (253 loc) · 8.33 KB

simple-values.adoc

File metadata and controls

372 lines (253 loc) · 8.33 KB

Simple Values

1. Clojure Data Type Diagram

다음의 도표는 클로저의 모든 자료형들을 한 눈에 살펴볼 수 있도록 일목요연하게 정리한 것이다. 먼저 전체적인 지도를 마음 속에 두고 각 부분을 자세하게 살펴 나가는 것이 클로저를 빠르고 정확하게 이해하는 지름길이다. 각 자료형 옆에는 실제로 구현되어 있는 자바 클래스를 병기했다. 이 장에서는 단순 자료형(Simple values)들을 중심으로 살펴보고, 다음 장에서 복합 자료형인 Collection들을 살펴 보겠다.

클로저 타입 자바 클래스

Immutables (= Values)

Simple values

Integers

java.lang.Long clojure.lang.BigInt

Floats

java.lang.Double
java.math.BigDecimal

Ratios

clojure.lang.Ratio

Strings

java.lang.String

Characters

java.lang.Character

Symbols

clojure.lang.Symbol

Keywords

clojure.lang.Keyword

Booleans

java.lang.Boolean

nil

null

Collections

Lists

clojure.lang.PersistentList

Vectors

clojure.lang.PersistentVector

Maps

array-map: clojure.lang.PersistentArrayMap hash-map: clojure.lang.PersistentHashMap sorted-map: clojure.lang.PersistentTreeMap

Sets

hash-set: clojure.lang.PersistentHashSet sorted-set: clojure.lang.PersistentTreeSet

Mutables (= References)

Identities

Atoms

clojure.lang.Atom

Refs

clojure.lang.Ref

Agents

clojure.lang.Agent

Vars

clojure.lang.Var

2. nil

클로저의 nil은 자기 자신으로 평가되는 값이다. 자바의 null, 루비의 nil, 파이썬의 None과 같이 값의 부재를 표현한다.

nil          ;=> nil

(type nil)   ;=> nil

nil은 클로저에서 논리적인 거짓(logically false)으로 취급된다. 클로저에서는 falsenil만을 논리적 거짓으로 판단하고, 그 이외의 모든 값은 논리적 참(logically true)으로 판단한다. 예를 들어 0이나 빈 문자열 "", 빈 백터 [] 등도 논리적 참으로 취급된다.

(if nil 10 20)     ;=> 20
(if false 10 20)   ;=> 20

(if 0 10 20)       ;=> 10
(if "" 10 20)      ;=> 10
(if [] 10 20)      ;=> 10

nil? 함수는 주어진 인수가 nil인지 판별한다.

(nil? nil)     ;=> true

(nil? false)   ;=> false
(nil? 0)       ;=> false
(nil? "")      ;=> false
(nil? [])      ;=> false

some? 함수는 주어진 인수가 nil이 아닌지 판별한다. (not (nil? x) 와 같다.

Caution
some? 함수는 클로저 버전 1.6부터 도입되었다. core 함수치고 꽤 늦게 도입된 것인데, 그 아래 버전에서는 컴파일 예외 발생하니 사용시 버전 주의.
(some? nil)      ;=> false

(some? false)    ;=> true
(some? 0)        ;=> true
(some? "")       ;=> true
(some? [])       ;=> true

3. 불린(Booleans)

불린값으로는 truefalse가 있고, 역시 자기 자신으로 평가되는 값이다.

true    ;=> true
false   ;=> false

(type true)    ;=> java.lang.Boolean
(type false)   ;=> java.lang.Boolean

true? 함수는 주어진 인수가 '실제로 true'[1]인지 판별한다. 즉, 주어진 인자가 true로 평가될 때에만 true를 반환한다. 그리고 false? 함수는 주어진 인수가 실제로 false인지 판별한다. 즉, 주어진 인자가 false로 평가될 때에만 true를 반환한다.

(true? true)      ;=> true
(true? (= 1 1))   ;=> true

(true? "hello")   ;=> false
(true? 1)         ;=> false

(false? false)     ;=> true
(false? (= 1 2))   ;=> true

(false? nil)       ;=> false
(false? "foo")     ;=> false
(false? 1)         ;=> false

4. 키워드(Keywords)

키워드는 임의의 식별자 앞에 콜론(:) 기호를 붙여 만든다. 자기 자신으로 평가되는 값으로 클로저에서 아주 많이 사용된다.

:city              ;=> :city

(type :city)       ;=> clojure.lang.Keyword

(keyword? :city)   ;=> true

;; keyword함수는 문자열을 키워드로 바꾸어 준다.
(keyword "city")   ;=> :city
(= :city (keyword "city")) ;=> true

콜론은 키워드를 만들기 위한 문법적 기능을 수행하기 위한 것이지 키워드의 이름은 아니다.

(= :seoul (keyword "seoul"))
(= :seoul (keyword ":seoul"))

키워드는 특히 키/값 쌍으로 이루어진 맵 자료형의 키로 많이 사용된다.

(def person {:name "Sandra Cruz"
             :city "Portland, ME"})

식별자 앞에 콜론을 두 개 붙이면 해당 이름공간을 가진 키워드로 확장된다. 예를 들어, 현재의 이름공간이 user일 때 다음을 실행하면, user 이름공간이 붙은 키워드로 확장되는 것을 볼 수 있다.

::address   ;=> :user/address

이때 namespace 함수와 name 함수로, 이름공간과 키워드명 부분만을 알아낼 수 있다.

(name :user/address)        ;=> "address"
(name ::address)            ;=> "address"

(namespace ::address)       ;=> "user"
(namespace :user/address)   ;=> "user"

(namespace :address)        ;=> nil

5. 심볼(Symbols)

클로저의 심볼은 다른 언어들에서의 식별자(identifiers)와 유사한 개념이다. 심볼은 숫자가 아닌 문자로 시작해야 하고, 그 뒤에 *, +, -, =, ?, !, $, %, &, _, |, <, > 같은 기호와 문자들이 올 수 있다.

(def *+-=?!$%&_|<> "이런 심볼도 가능") ;=> "이런 심볼도 가능"

심볼은 유니코드를 지원한다.

(def 심볼1 "한글도 가능") ;=> "한글도 가능"

심볼은 일반적으로 어떤 값을 가리킨다. 그래서 심볼이 평가되면 가리키던 값을 반환하게 된다.

;; 전역 심볼 a를 정의한다.
(def a 10)

;; 전역 심볼 a를 평가하면, 가리키던 값 10을 반환한다.
a   ;=> 10

;; 지역 심볼 a를 정의한다. let 안에서 지역 심볼 a는 전역 심볼 a을 가린다(shadowing).
(let [a 20]
  (+ 100 a))
;=> 120

;; 전역 심볼 a는 여전히 10을 가리키고 있다.
a   ;=> 10

name 함수는 심볼을 문자열로 바꾼다.

(name 'a) ;=> "a"

symbol 함수는 문자열을 심볼로 만든다.

(symbol "a") ;=> a
(symbol "my-namespace" "a") ;=> my-namespace/a

symbol? 함수는 심볼인지 여부를 확인한다.

(def a 1)      ;=> 1
(symbol? 'a)   ;=> true
(symbol? a)    ;=> false

(symbol? "a")  ;=> false
(symbol? :a)   ;=> false
(symbol? 1)    ;=> false

6. 문자(Characters)

문자는 역슬래쉬(\) 기호 뒤에 한 개의 문자를 덧붙여 표현한다.

\a    ;=> \a
\가   ;=> \가

(type \a)    ;=> java.lang.Character
(char? \a)   ;=> true

\u 뒤에 16진법 숫자 4개를 덧붙여 유니코드를 직접 표현할 수도 있다. \o[2] 뒤에 8진법 숫자를 붙여 표현할 수도 있는데, \o0 ~ \o377 (즉, 0 ~ 255) 사이의 숫자만 허용한다.

\u03bb   ;=> \λ
\o101    ;=> \A

이름을 갖는 특별한 문자들이 다음과 같이 정의되어 있다.

  • \space

  • \newline

  • \formfeed

  • \return

  • \backspace

  • \tab

`char`함수는 정수를 문자로 바꾼다.

(char 97)     ;=> \a

`char?`는 문자인지를 판별한다.

(char? \a)    ;=> true
(char? 97)    ;=> false
(char? "a")   ;=> false

1. 논리적 참(logically true)과는 다르다는 점에 주의하자.
2. 숫자 0이 아니라 알파벳 o임에 주의하자.