2016년 4월 4일 월요일

The first Clojure - 03.Data Structures

nil, truth, and falsehood
Clojure’s nil is equivalent to null in Java and nil in Ruby. It means “nothing”.
Boolean values are simple. Everything other than false and nil is considered true.

Characters and Strings
Clojure characters are java characters unsigned 16-bit UTF-16 code points.
Clojure strings are Java string. They’re denoted using double quotes
Some examples are

(.contains "clojure-in-action" "-")
and
(.endsWith "program.clj" ".clj")

Clojure numbers
Most of the time the numbers you’ll be using in Clojure are 64-bit integers(Java primitive longs) or 64-bit floating-point numbers(Java primitive doubles).


When different number types are mixed together in the same arithmetic operations,
the number type with the highest “contagiousness” will “infect” the result with its type.
Here’s an illustration of this principle:

(+ 1 1N)
;=> 2N
(+ 1 1N 1/2)
;=> 5/2
(+ 1 1N 1/2 0.5M)
;=> 3.0M
(+ 1 1N 1/2 0.5M 0.5)
;=> 3.5

Lists
Lists are the basic collection data structure in clojure. Clojure lists are singly linked lists.

Use the list function to create a list and the list? function to test for list types:

(list 1 2 3 4 5)
;=> (1 2 3 4 5)
(list? *1)
;=> true

Use the conj function to create a new list with another value added to it:

(conj (list 1 2 3 4 5) 6)
;=> (6 1 2 3 4 5)

The conj function is the generic “add an item to a collection” function in Clojure. It
always adds an item to a collection in the fastest way possible for that collection. So on
lists conj adds to the beginning, as you saw, but with other collections it may add to
the end or even (for unordered collections) nowhere in particular. You’ll see more of
conj when we look at the other collection types.
conj can take multiple arguments; it will add each argument to the list in the order
in which it is supplied. Note that this means it will appear in the new list in the reverse
order, because lists can grow only from the front:

(conj (list 1 2 3) 4 5 6)
;=> (6 5 4 1 2 3)
(conj (conj (conj (list 1 2 3) 4) 5) 6)
;=> (6 5 4 1 2 3)

You can treat a list like a stack, too. Use peek to return the head of the list and pop to
return the tail:

(peek (list 1 2 3))
;=> 1
(pop (list 1 2 3))
;=> (2 3)

Finally, you can count the number of items in a list in constant time using the
count function:

(count (list))
;=> 0
(count (list 1 2 3 4))
;=> 4

Vectors
Vectors are like lists, except for two things: they’re denoted using square brackets,  and they’re indexed by number.
Vectors can be created using the vector function or literally using the square bracket notation:

(vector 10 20 30 40 50)
;=> [10 20 30 40 50]
(def the-vector [10 20 30 40 50])
;=> #'user/the-vector

Vectors being indexed by numbers means that you have fst random access to the elements inside a vector.
The functions that allow you to get these elements are get and nth, the difference between nth and get is that nth throws an exception if the value isn.t found, where as get returns nill.

(get the-vector 2)
;=> 30
(nth the-vector 2)
;=> 30
(get the-vector 10)
;=> nil
(nth the-vector 10)
IndexOutOfBoundsException clojure.lang.PersistentVector.arrayFor (PersistentVector.
java:107)

The most commonly used one is assoc, which accepts the index at which to associate a new vlaue, along with the value itself:

(assoc the-vector 2 25)
;=> [10 20 25 40 50]
(assoc the-vector 5 60)
;=> [10 20 30 40 50 60]
(assoc the-vector 6 70)
IndexOutOfBoundsException clojure.lang.PersistentVector.assocN
(PersistentVector.java:137)

“conj” also works on vectors. Notice that the new element ends up an the end of the sequence this time, because that’s the fastest spot on a vector”

(conj [1 2 3 4 5] 6)
;=> [1 2 3 4 5 6]

peek and pop work, too, and they also look at the end of the vector instead of the beginning
like with lists:

(peek [1 2])
;=> 2
(pop [1 2])
;=> [1]

댓글 없음:

댓글 쓰기

시스템 부팅시 도커 컨테이너 자동 실행

Docker 컨테이너를 운용중인 시스템이 Reboot 되버리면 컨테이너가 자동으로 올라오지 않아 불편해서 시스템 리붓시 컨테이너를 자동으로 시작되게 init 데몬에 등록하기로 했습니다. 서버는 Ubuntu 17.10 Docker는 17.0...