다음의 도표는 클로저의 모든 자료형들을 한 눈에 살펴볼 수 있도록 일목요연하게 정리한 것이다. 먼저 전체적인 지도를 마음 속에 두고 각 부분을 자세하게 살펴 나가는 것이 클로저를 빠르고 정확하게 이해하는 지름길이다. 각 자료형 옆에는 실제로 구현되어 있는 자바 클래스를 병기했다. 이 장에서는 단순 자료형(Simple values)들을 중심으로 살펴보고, 다음 장에서 복합 자료형인 Collection들을 살펴 보겠다.
클로저 타입 | 자바 클래스 | ||
---|---|---|---|
Immutables (= Values) |
Simple values |
Integers |
java.lang.Long clojure.lang.BigInt |
Floats |
java.lang.Double |
||
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 |
클로저의 nil
은 자기 자신으로 평가되는 값이다. 자바의 null
, 루비의 nil
, 파이썬의
None
과 같이 값의 부재를 표현한다.
nil ;=> nil
(type nil) ;=> nil
nil
은 클로저에서 논리적인 거짓(logically false)으로 취급된다. 클로저에서는 false
와
nil
만을 논리적 거짓으로 판단하고, 그 이외의 모든 값은 논리적 참(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
불린값으로는 true
와 false
가 있고, 역시 자기 자신으로 평가되는 값이다.
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
키워드는 임의의 식별자 앞에 콜론(:
) 기호를 붙여 만든다. 자기 자신으로 평가되는 값으로
클로저에서 아주 많이 사용된다.
: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
클로저의 심볼은 다른 언어들에서의 식별자(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
문자는 역슬래쉬(\
) 기호 뒤에 한 개의 문자를 덧붙여 표현한다.
\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