June
15th,
2017
- CREATED
BASIC
user==> (defn hello [name] (str “Hello, “ name))
- defn : 함수를 정의
- hello : 함수 이름, name이라는 인자를 받는다.
- str : 여러 인자를 받아 하나의 문자열로 연결하는 함수
- 실행 : user==> (hello “test”) Hello, test
몫과 나머지
(quot 22 7)
==> 3
(rem 22 7)
==> 1
자릿수에 상관없이 정확한 계산을 위해서 -> BigDecimal -> BigDecimal 연산은 자바의 부동소수점 연산에 비해 매우 느리다.
(+ 1 (/0.00001 10000000000))
==> 1.0
(+ 1 (/0.00001M 10000000000))
==> 1.000000000000001M
클로저의 문자(character)는 곧 자바 문자다.
user> (str \a \b \c \space \d \e \f)
==> "abc def"
특수변수
- REPL은 최근에 입력된 표현식의 결과 값 세 개를 각각 *1, *2, *3 이라는 특수 변수에 저장하고 있다.
- *e 는 바로 직전의 예외를 저장하고 있다.
user ==> (.printStackTrace *e)
file load
; abc.clj
user ==> (load-file "abc.clj")
병행성 예제 - preview
(def visitors (ref #{}))
(defn hello
"Writes hello message to *out*. Calls you by username.
Knows if you have been here before."
[username]
(dosync
(let [past-visitor (@visitors username)]
(if past-visitor
(str "Welcome back, " username)
(do
(alter visitors conj username)
(str "Hello, " username))))))
user> (load-file "helloworld.clj")
#'user/hello
user> (hello "ASDF")
"Hello, ASDF"
user> (hello "ASDF")
"Welcome back, ASDF"
라이브러리
- require : clojure library를 load 한다.
(require quoted-namespace-symbol)
- refer : 현재 namespace 의 모든 이름을 새로운 namespace로 대응 시킬 수 있다.
(refer quoted-namespace-symbol)
- use : require와 refer가 한꺼번에 이루어진다.
use quoted-namespace-symbol)
- reload-all : 강제로 library를 다시 load 하도록 할 수 있다.
(use :reload-all 'eamples.introduction)
문서 찾아보기
- doc
user> (doc str) clojure.core/str ([] [x] [x & ys]) With no args, returns the empty string. With one arg x, returns x.toString(). (str nil) returns the empty string. With more than one arg, returns the concatenation of the str values of the args. nil user>
위의 병행성 예제 4line 이 바로 기술 문서의 역할이다.
(doc hello)
==> message를 확인 해 볼 수 있다.
- find-doc : function name을 정확하게 알지 못할때 사용한다.
컬렉션과 시퀀스
컬렉션
컬렉션은 여러 데이터를 하나의 덩어리로 묶어서 다루기 위한 것이다. 클로저는 컬렉션으로 사용할 수 있는 여러가지 자료구조(Data Structures)를 제공하는데 다음과 같은 특징을 갖는다.
- 불변(Immutable)
- 존속적(Persistent)
- 구조의 공유(Structural Sharing)
- 동등 비교는 값으로만
- hash 값을 제공
- thread-safe
- 추상(Abstraction)으로 표현
- java.lang.Iterable을 구현
- java.util.Collection의 일부 read-only 부분을 구현
클로저 컬렉션의 이러한 특성으로 인해 클로저는 다른 리스프(LISP)언어와는 구별된다. 또한 클로저 컬렉션은 클로저가 함수형 프로그래밍 언어로서의 효율적이고 효과적으로 동작하는데 았어 매우 중요한 역할을 한다. 자료구조의 이러한 특성을 잘 아는 것은 그것을 잘 사용하는 것 만큼이나 중요하다.
컬렉션으로서 데이터를 어떤 방식으로 묶느냐에 따라 클로저는 다음 4개의 컬레션을 제공한다.
클로저 컬렉션
- 리스트 : 가장 단순한 컬렉션으로 순차 접근이 가능하다. 단일 연결 리스트로 되어 있다.
- 벡터 : 임의 접근이 가능하다. 다른 언어에서의 배열 정도에 해당한다.
- 맵 : 키-값 쌍으로 구성된다. 파이썬의 dictionary, 루비의 Hash에 해당한다.
- 집합 : 중복되지 않는 요소를 갖는다.
시퀀스
클로저의 시퀀스는 리스프의 cons cell에 해당하는 것이다. 즉 모든 시퀀스는 2개의 쌍으로 이루어져 있는데, 하나는 시퀀스의 첫 요소를 나타내고, 다른 하나는 또 다른 시퀀스이다. 이것은 first와 rest 라는 함수로 얻을 수 있다.
- 시퀀스 추상 함수 seq : 주어진 컬렉션에 대해 시퀀스를 만들어 낸다. first, next, rest : 시퀀스에 순차적으로 접근하는 방법을 제공한다. lazy-seq : lazy-seq를 만들어 낸다.