2015년 2월 15일 일요일

Clojure 연습 2






;; 2015-02-16 14:20:05 (월요일)
;; 클로저를 배워보자.

;; 참조:
;; http://www.moxleystratton.com/blog/2008/05/01
;; /clojure-tutorial-for-the-non-lisp-programmer/


(comment

클로저 표현식은 두가지가 있다.
atoms, lists.


atoms 는 다른언어의 primitive 타입과 같다.

클로저의 atoms 에는 다음과 같은것들이 포함된다.

Number
Booleans
Nil
String
Symbols
Keywords

)

;; Number
5

;; Booleans
true

;; Nil
nil

;; String
"Hello, world!"

;; Symbols
;;
;; 심볼은 값의 이름이다.
;; 다른 언어에서 상수라고 부르는것과 유사하다.
;; 클로저는 "변수"라는것이 없다.
;; 클로저에서는 심볼과 심볼의 값을 명확히 구분한다.
;;

;; 다음과 같은것이 심볼의 예가 되겠다.
*file*
*compile-path*
*clojure-version*
*command-line-args*
+

;; 위에서 나열된 심볼은 클로저의 내장심볼이다. (built-in symbols)
;; 관례적으로, 데이터에 바인드된 심볼은 
;; 앞뒤에 * 를 붙여준다.
;; 마지막에 있는 + 는 내장함수이다.

;;
;; 클로저에서는
;; 심볼이름에 다음과 같은 문자를 포함할수있다.
;; *,+,!,-,_,?
;; 위 문자는 C++ 변수에 쓰면 대부분 에러가 나는것들이다.
;; C++ 보다 클로저에서 더 자유롭게 이름을 지을수있다.
;; 클로저 심볼역시, 숫자로 시작해서는 안된다.
;;


;; Keywords
;; 키워드는 값에 바인드되지 않는다는 점을 빼면, 심볼과 같다.
;; 키워드는 항상 자기자신에게 바인드된다.
;; 키워드는 : 으로 시작한다.

:a
:_123
:KEY


;;Lists
;; 리스트는 다음과 같이 생겼다.
()
(list 1 2 3)
(+ 3 3 3)

;; 괄호()로 감싸진것은 리스트다.
;; 리스트는 두가지 용도로 사용된다.
;; 데이터구조, 함수호출
;;
;; 즉, 클로저에서는
;; 리스트 자료구조도 리스트 형태로 표현하고,
;; 함수호출도 리스트 형태로 표현한다.
;;
;; 두가지 기능을 같은 문법 형태로 표현한다.
;;

;; 리스트문법으로 데이터를 표현하면 다음과 같다.
(list 1 2 3)

;; 위 문장과 같은 뜻으로, 다음과 같이 쓸수있다.
'(1 2 3)

;; 둘다 리스트 데이터를 표현한다.


;; 리스트문법으로 함수호출을 표현하면 다음과 같다.
(+ 1 2)

;; 맨앞에있는것이 함수, 그 뒤에오는것이 인자(arguments)다.


;; 리스트 안에 들어가는 요소의 타입이 같을 필요는없다.
;; 여러가지 다른 다입을 리스트에 넣을수있다.
(list :keyword1 (list 1 2 3) [4 5 6])

;;
;; C++ 의 배열이나 리스트는 한가지 타입만 가능하다.
;; 클로져는 리스트에 여러가지 타입을 넣을수있다.
;; 언어의 표현력. 언어의 자유도가 높다는것을 알수있다.
;;

;; 리스트데이터를 표현할때 quote 를 쓰는 다음과 같은 표현은
'(1 2 3)

;; 식을 평가하지 않는 효과를 가진다.
;; 이 기능은 매크로를 만들때 사용된다.
;; 지금은 그냥 리스트를 표현하는 문법만 알아두자.


;; Vectors
;; 벡터는 이렇게 생겼다.
[1 2 3]

;; 벡터역시 여러가지 타입을 요소로 넣을수있다.
[ 1 2 3 :keyword1 (list 1 2 3) [4 5 6]]

;; 리스트와는 달리
;; 첫번째 요소에 list 를 쓴다거나
;; 맨앞에 ' 를 쓴다거나 하는 제약조건이 없다.
;; 이건 그냥 데이터를 표현한다.
;; 반면,
;; 리스트 문법은, 데이터와 함수호출 두가지를 표현하기때문에,
;; 그 둘을 구분하기위해 list, ' 등이 필요한것이다.
;; 그런것이 없으면, 함수호출로 해석하고,
;; 그런것이 있으면, 데이터 리스트로 해석하는것이다.
;;

;; 배열처럼 index 로 특정요소를 가져온다.
([1 2 3] 1)
(first [1 2 3])
(last [1 2 3])
(rest [1 2 3])


;; Maps and Sets
;; 맵은 키-값 쌍을 정의한다.
{"a" 1, "b" 2, "c" 3}

;; 중간에 콤마(,) 를 써도되고 안써도 된다.
;; 대부분 클로저는 콤마(,)를 공백으로 해석한다.
{"a" 1 "b" 2 "c" 3}
{"a", 1, "b", 2, "c", 3}


;; 키를 써서, 값을 가져오는 기능.
(get {"a" 1 "b" 2 "c" 3} "a")
(get {"a" 1 "b" 2 "c" 3} "b")
(get {"a" 1 "b" 2 "c" 3} "b")

;; 위코드의 단축형으로, 다음과 같이 쓸수있다. 같은 뜻이다.
( {"a" 1 "b" 2 "c" 3} "a")
( {"a" 1 "b" 2 "c" 3} "b")
( {"a" 1 "b" 2 "c" 3} "b")

(comment
;; 이건 안되는구나.
( "a" {"a" 1 "b" 2 "c" 3} )
( "b" {"a" 1 "b" 2 "c" 3} )
( "c" {"a" 1 "b" 2 "c" 3} )
)

;; 키를 써서, 값을 가져오는 기능.
(get {:a 1 :b 2 :c 3} :a)
(get {:a 1 :b 2 :c 3} :b)
(get {:a 1 :b 2 :c 3} :c)

;; 단축형(1). 같은뜻.
( {:a 1 :b 2 :c 3} :a)
( {:a 1 :b 2 :c 3} :b)
( {:a 1 :b 2 :c 3} :c)

;; 단축형(2). 같은뜻.
( :a {:a 1 :b 2 :c 3} )
( :b {:a 1 :b 2 :c 3} )
( :c {:a 1 :b 2 :c 3} )


;; 위, 단축형(1) 과 단축형(2) 는 자주쓰이는 문법이다.
;; 기억해두자.
;;
;; 맵도 넣을수있는 요소의 타입에는 제약이 없다.




;; 정리하자.

;; 1. list
()

;; 2. vector
[]

;; 3. map
{}

;; 4. set
#{}


(println (type ()))
(println (type []))
(println (type {}))
(println (type #{}))






;; def
;; 심볼을 값에 연결한다.
(def x 5)
(println x)

(def val1 (+ 5 x))
(println val1)

(def my-list '(1 2 3))
(println my-list)
(println (last my-list))

;; 새로운 심볼이 생성되고,
;; 여기에 주어진 값을 연결하는 작업이 수행된다.
;; C++ 에서 이렇게 하던것이었는데.
;;
;; x = 5;
;; val1 = 5 + x
;;


;; defn
;; 함수를 만든다.

(defn election-year? [year]
  (zero? (rem year 4)))

(println (election-year? 2007))
(println (election-year? 2008))


;; 모든 심볼에 ? 문자를 쓸수있다.
;; 함수이름에 ? 문자를 쓸수있다.
;; true/false 를 리턴하는함수를 predicate 라 한다.
;; 관례적으로 predicate 함수명에 ? 문자를 붙여준다.
;;



;; fn
;; 무명의 함수.

(fn [x] (+ x 1))
(println ((fn [x] (+ x 1)) 9))

;; 이름없는 함수. 
;; 무명함수.
;; 그 유명한 람다(lambda).
;; 또는, 그 유명한 클로저(closure).
;;
;; 이름이 없으므로 호출할수없다.
;; 호출할수있는 유일한 기회는, 그 함수가 정의되는 곳 뿐.
;; 

;; 물론 이름을 붙여줄수도 있다.
(def plus-one (fn [x] (+ x 1)))
(println (plus-one 9))

;; 위에서 사용한 def, fn 조합의 단축형이 defn 이다.
(defn plus-one [x] (+ x 1))


;; 무명함수가 함수 외부값을 쓸수있는가? 
;; 쓸수있다면, 
;; 이것은 람다(lambda)가 아니라 클로저(closure)다.
(def xxx 7)
(defn xxxfn [x] (+ x xxx))
(println (xxxfn 1))


;; 의문이 생긴다.
;; 이름이 없어서 나중에 호출할수없는 함수라니.
;; 호출할수없는 함수가 필요한가?
;; 이것을 어디에 쓴단말인가?



;; doc
;; repl 에서만 된다.
;;(doc first)



;; str
(str "Hello," "world!")

;; if
(if true "yes")

;; do
(do (println "Hello.") (+ 2 2))

;; when
(when true "yes")

;; let
(let [x 2] (+ x 8))

;; Looping and Iterating
(loop [i 0]
  (when (< i 5)
    (println i)
    (recur (inc i))))


(dorun (for [i (range 0 5)]
         (println i)))


(doseq [i (range 0 5)]
  (println i))


;; Sequences
(seq [1 2 3])
(println (seq [1 2 3]))

(def s (seq [1 2 3]))
(println (type s))
(println (.getClass s))

(first s)
(second s)
(last s)
(rest s)


(println (first s))
(println (second s))
(println (last s))
(println (rest s))

(cons 1 [ 2 3])
(println (cons 1 [ 2 3]))


;; Java Integration
(new java.util.Date)

(new StringBuffer "this is..")

(StringBuffer. "this is..")

(.toString (new java.util.Date))

(.toString (java.util.Date.))

(Integer/MAX_VALUE)
(Character/TYPE)
(Boolean/valueOf "true")

(println (Integer/MAX_VALUE))
(println (Character/TYPE))
(println (Boolean/valueOf "true"))




Firefly Algorithms

firefly algorithm 001 Firefly Algorithms ¶ 반딧불 알고리즘 번역 요약 ¶ References [1] X. S. Y...