2016년 10월 30일 일요일

[javascript patterns] 스터디 09


즉시 실행 함수

즉시 실행 함수 패턴: 함수 선언 직후 바로 실행되는 문법.
(function() {
  alert('바로 실행');
})();
이 패턴은 함수 표현식을 생성한 직후 실행시킨다. 일반 함수에 두개의 괄호가 붙었다. 붙은 위치를 보고 '아! 저렇게 하면 즉시 실행되는 구나!' 하고 느끼기 바란다. 사실 비슷하지만 다르게도 즉시실행을 할 수 있다.
(function() {
  alert('바로 실행');
}());
별 차이는 없다. 하지만 JSLint는 이놈을 더 좋아한다고 한다. 이것을 언제 쓸까? 페이지 로드가 완료 되었을 때, 기본적으로 이벤트 핸들러를 연결하는 등의 초기 설정 작업을 한다. 이런 것들을 사용할 때 이름을 하나하나 전역에 붙였다가는 더러워질 수 있을 것이다.(재사용할 것이 아니기 때문)
(function () {
  var days = ['일요일', '월요일', '화요일', '수요일', '목요일', '불금세일', '토요일'],
      today = new Date(),
      msg = 'Today is ' + days[today.getDay()] + [, ] + today.getDate();
  alert(msg);
}()); 

즉시 실행 함수의 매개변수

(function (who, when) {
  alert(when + ' ' + who + '와 약속이 있습니다.');
}('아무개씨', new Date()));
일반적으로 전역 객체가 즉시 실행 함수의 인자로 전달된다. 즉 window를 쓰지 않고 전역 객체에 접근할 수 있다. 이런 방법으로 브라우저 외에서도 코드를 사용할 수 있다. 잘보라
(function (global) {
  // 전역 객체르 'global'로 참조 하는데 브라우저 상에서는 window였지만 다른 곳에서는 아닐 수도 있는 법
  console.log(global); // Window 객체가 뜰 것이다.
}(this));
다음 글에 이어서 하도록 하자.

2016년 10월 29일 토요일

[Mathematics for Computer Science] 스터디 05

Axioms

Axiom은 공리, 자명한 이치이다.
An axiom is a proposition that is assumed to be true, because you believe it is somehow reasonable.
Axiom 1. If a = b and b = c, then a = c. 우리가 아주 잘 아는 Axiom이다. A가 B이고 B가 C라면, A = C 이다.

2016년 10월 22일 토요일

[Mathematics for Computer Science] 스터디 04

지난 시간에 이어서 truth table에 대해서 알아보도록 하자.
다른 함의(implication)의 예시를 보자.
만약 개가 날 수 있다면, 당신은 토익을 만점 받을 거야.
장난스럽지만 이건 참이다. 설사 지금 당신이 토익이 뭔지 모른다 하여도! 왜냐하면? 만약 개가 날 수 있다면 이 거짓이기 때문에!! 자 truth table을 한 번 보라. P⇒Q 일때 P가 FALSE 이면 Q는 항상 TRUE 라는 것을!(P⇒Q is always true when P is false.)
truth table이 마음에 들지 않을 수도 있겠다. 우리가 실제로 생각하는 if-then statements는 다른 것일 텐데 말이다. 그런데 실제 수학에서는 많이 쓰이는 듯 하다.

실망하지 말자 우리가 생각하는 가정문이 곧 나온다.

Proposition 8. ∀n ∈ ℤ (n≥2) ⇔ (n2≥4)
A proposition of the form P ⇔ Q is read "P if and only if Q". (Sometimes "if and only if" is abbreviated "iff".) This proposition is true provided P ⇒ Q and Q ⇒ P are both true. Here is a truth table that compares all these kinds of implication:
"iff"라고 불리는 이것이 당신들이 찾던 그것이다. 이것은 P ⇒ Q, Q ⇒ P 둘 다 true일 때 true이다.

2016년 10월 19일 수요일

[javascript patterns] 스터디 08

자기 자신을 정의하는 함수

함수는 동적으로 정의할 수 있고 변수에 할당할 수 있다. 새로운 함수를 만들어 이미 다른 함수를 가지고 있는 변수에 할당한다면, 새로운 함수가 이전 함수를 덮어쓰게 된다. (그러니까 이미 존재하는 함수가 있어도 덮어쓴다는 말)
어떻게 보면 함수 포인터를 재사용하는 것이다. 자기 자신을 정의하는 함수은 자기 자신을 덮어써서 재정의(재사용)하는 것이다.
var run = function() {
  alert("run!");
  run = function() {
    alert("run faster! ");
  }
}

// 자기 자신을 정의하는 함수를 사용
run(); // run!
run(); // run faster!
이 패턴은 함수가 어떤 초기화 준비 작업을 단 한 번만 수행할 경우에 유용하다(한 번쓰고 바로 덮어씌어지기 때문에). 단점은 자기 자신을 재정의한 후, 원본 함수에 추가했던 프로퍼티들을 모두 찾을 수 없다. 또한 객체의 매서드로 사용되면 처음 실행할 때 처음 것이 실행될 수도 있다.(다른 변수에 할당 되었을 시에도 동일)
이 함수를 일급 객체로 사용하는 예를 살펴보자.
// 새로운 프로퍼티 추가
var run = function() {
  alert("run!");
  run = function() {
    alert("run faster! ");
  }
}
run.property = '일급객체로 사용한다.';

// 1. 다른 이름으로 할당한다.
var go1 = run;

// 2. 메서드로 사용한다.
var go2 = {
  a : run
};

// 새로운 이름으로 호출
go1(); //"run"
go1(); //"run"
console.log(go1.property); // '일급객체로 사용한다.'

// 메서드로 호출
go2.a(); // "run"
go2.a(); // "run"
console.log(go2.a.property); // '일급객체로 사용한다.'

// 자기 자신을 재정의한 함수
run();
run();
console.log(run.property); // undefined
함수가 새로운 변수에 할당되면 예상과 달리 자기 자신을 정의하지 않는다. 이 호출들은 계속해서 전역 run() 포인터를 덮어 쓴다. 따라서 마지막에 전역 run()가 호출되었을 때 비로소, 변화된 것이 갱신된다.

[javascript patterns][타임아웃] 스터디 07

또 다른 콜백 패턴의 예제는 window객체의 setTimeout(), setInterval()이다.
예시
var delay = function() {
  console.log('500ms later...');
};
setTimeout(delay, 500);

delay가 괄호없이 변수로 전달된 점에 주의하자. 곧바로 실행하지 않고 포인터만을 전달하는 것이다. 함수포인터 대신 문자열 "delay()"를 전달하는 것은 eval()과 비슷한 안티패턴이다.

2016년 10월 18일 화요일

[javascript patterns][비동기 이벤트 리스터]스터디 06

콜백 패턴은 이미 일상적으로 사용되고 있다. 예를 들어 페이지의 엘리먼트에 이벤트리스터를 붙이는 것, 실제로는 이벤트가 발생했을 때 호출된 콜백 함수의 포인터를 전달하는 것이다.
예시
document.addEventListener("click", console.log, false);

대부분의 클라이언트는 event-driven 방식이다. 페이지 로딩이 끝나면 load 이벤트를 발생시킨다. 사용자는 click, keypress와 같은 이벤트들을 발생시킨다.
자바스크립트가 이런 프로그래밍에 잘 맞는 것은 콜백패턴 때문이다.(비동기적으로 그때그때 동작하는 것이 달라질 것)

2016년 10월 16일 일요일

[javascript patterns][콜백과 유효범위]스터디 05

한번 단순하게 사용해보자.
  1. 첫번째 리스트
  2. 두번째 리스트
  3. 세번째 리스트
  4. 네번째 리스트

여담인데 혹여 절대로 이 코딩을 따라하지는 않길...

2016년 10월 12일 수요일

[javascript patterns][콜백과 유효범위]스터디 04

이전의 예에서, 콜백은 이런 식으로 실행했다.
var a = function() {
  callback(parameters);
}
이 코드는 간단하고 대부분의 경우 훌륭하게 작동한다. 그러나 콜백이 일회성의 익명 함수나 전역 함수가 아니고 객체의 메서드인 경우도 많다.
var a = function() {
var myapp = {};
myapp.color = 'green';
myapp.paint = function (node) {
  node.style.color = this.color;
};

var findNodes = function(callback) {
  //...
  if (typeof callback === 'function') {
    callback(found);
  }
//...
};
findNodes(myapp.paint);

이러면 작동하지 않는다. findNodes(myapp.paint)를 호출하면 this.color가 정의되지 않아 예상대로 동작하지 않는다.
findNodes()가 전역 함수이기 때문에 객체 this는 전역 객체를 참조한다. findNodes()가 (dom.findNodes()처럼) dom이라는 객체의 메서드라면, 콜백 내부의 this는 예상과는 달리 myapp이 아닌 dom을 참조하게 된다.(this에 대해 자세히 공부를 해야함)

이 문제를 해결하려면, 콜백 함수와 콜백이 속해 있는 객체를 함.께. 전달하면 된다.

findNodes(myapp.paint, maapp);
var findNodes = function (callback, callback_obj) {
  //...
  if (typeof callback === 'function') {
    callback.call(callback_obj, found);
  }
  //...
};

이것을 바인딩(binding)이라고 하는데 저 위에 사용해본 call(), apply() 가 바인딩을 위해 사용되는 것인데, 나중에 더 공부해보도록 하자.

콜백으로 사용될 메서드와 바인딩할 객체를 전달할 때, 메소드를 문자열로 전달 할 수도 있다. (이렇게 하면 객체를 두 번 반복하지 않아도 된다. 무슨말이냐면!

findNodes(myapp.paint, myapp);
여기서
findNodes("paint", myapp);
이렇게 바꿀 수 있는데, 이 두 방법에 모두 대응하는 findNodes()를 만드려면?!
var findNodes = function (callback, callback_obj) {
  if (typeof callback === 'string') {
    callback = callback_obj[callback];
  }
  //...
  if (typeof callback === 'function') {
    callback.call(callback_ovj, found);
  }

[javascript patterns][콜백함수]스터디 03


  • First List
  • Second List
  • Third List
  • Fourth List

[javascript patterns][콜백함수]스터디 02

노드를 숨기는 로직의 실행을 콜백 함수에 위임하고 이 함수를 findNodes()에 전달한다.
b(a)
// findNodes()가 콜백을 받도록 리팩터링한다.
var findNodes = function (callback) {
  var i = 10000,
      nodes = [];

  // 콜백 함수를 호출할 수 있는지 확인한다.
  if (typeof callback !== "function") {
    callback = false;
  }

  while(i) {
    i -= 1;
    // 이곳에 복잡한 로직을 구현한다.예를들어
    nodes[i]=i;

    // 여기서 콜백을 실핸한다.
    if (callback) {
     nodes[i] = callback(nodes[i]);
    }
    nodes.push(nodes[i]);
  }
  return nodes;
};
이 구현 방법은 직관적이다.
findNodes()에는, 콜백 함수가 추가되었는지 확인하고, 있으면 실행하는 작업 하나만 추가되었다. 콜백은 생략할 수 있기 때문에 리팩터링된 findNodes()는 여전히 이전과 동일하게 사용할 수 있고, 기존 API에 의존하는 코드를 망가뜨리지 않는다.
루프를 돌 필요가 없어진 hide()를 보라.
//콜백 함수
var hide = function (node) {
  node = "none";
};

//노드를 찾아서 바로 숨긴다.
findNodes(hide);

//또는 익명 함수를 바로 사용할 수 있다.
findNodes(function (node) {
  node = "none";
});
다음 글에는 실제로 콜백을 DOM에 써보자.

[javascript patterns][콜백함수]스터디 01


함수

자바스크립트의 함수를 특별하게 만드는 두 가지 중요한 특징이 있다.
1. 함수는 일급(first-class) 객체다.
2. 함수는 유효범위(scope)를 제공한다.
 - 런타임, 즉 실행 중에 동적으로 생성할 수 있다.
 - 변수에 할당, 참조,확장가능하고, 몇몇 특별한 경우를 제외하면 삭제할 수 있다.
 - 자기 자신의 프로퍼티와 메소드를 가질 수 있다.

콜백 패턴

함수는 객체다. 즉 함수를 다른 함수에 인자로 전달 할 수 있다.

var a = function() {
return 1+1;
}
var b = function getSquare(a) {
  return a()*a();
}
b(a)
4
예제를 한 번 살펴보자. 처음에는 콜백 없이 시작하여 리팩터링 하는 것과 비교를 할 것이다. 복잡한 작업을 수행한 후 그 결과로 대용량 데이터셋을 반환하는 범용함수가 있다고 하자.

var findNodes = function() {
  var i = 100000,
          nodes = [],
          found;
  while (i) {
    i -= 1;
    // 복잡한 작업이 있다 가정
    nodes.push(found);
  }
  return nodes;
};
범용함수니까 아무 작업도 하지 않고 DOM 노드의 배열을 반환하기만 하도록 하자. 로직은 다른 곳에 두어서 로직에만 신경쓸 수 있도록. hide()라는 함수로 해당 배열을 죄다 숨겨보자. 그리고 여기는 예시이기 때문에 값이 변화한 것인지 아닌지 확인 차 리턴을 해보자.

var hide = function (nodes) {
  var i = 0, max = nodes.length;
  for (; i < max; i += 1) {
    nodes[i] = "none";
  }
  return nodes;
};
var res = hide(findNodes());
res[0];
"none"
res[1];
"none"
  이것은 findNodes()에서 반환된 노드의 배열에 대해 hide()가 다시 루프를 돌아야 하기 때문에 비효율적이다. findNodes()에서 노드를 선택하고 바로 숨긴다면 재차 루프를 돌지 않아 더 효율적일 것이다. 그런데 그렇게 하면 분리를 한 의미가 사라진다. 이럴때 콜백함수가 사용된다. 콜백함수는 다음 페이지에 적겠다.

2016년 10월 11일 화요일

[누구나 쉽게 배우는 클로저] 스터디 3

맵 : 그냥 해시맵이라 생각하자 하지만 clojure 세미나에서 보니 clojure의 해시맵은 꽤나 많은 고민을 하여 알고리즘을 선정하여 구현했다고 한다.

맵을 한 번 만들어 보자.
{}
끝. 이게 맵이다.

{:a "aaa" :b "bbb"}
여기서 :a는 키워드라고 하는데 키워드는 말그대로 키워드다.
{:더하기 +}
이러면 :더하기 라는 키워드(문자열아님)에 + 함수를 연결한 것이다.
{:a {:aa "숨겨진 값"}}
컬렉션 안에 컬렉션이 들어있는 느낌으로 감을 익혀라. (map안에 map이 있는 것)

map에서 값을 꺼내보자
(get {:A 1 :B 2} :A)
;=1
(get {:A 1 :B {:C "맵안에 맵!"}} :B)
;={:C "맵안에 맵!"}

감이 오는가? 많은 것을 배우려고 하지말자. 어떤 느낌인지 감을 느껴라. 리듬을 타라. 고개를 끄덕이며 '아 이런 느낌이군!' 감만 익혀라. 그러면 어떤 책이든 잡고 공부할 수 있다. (하지만 나도 공부하는 중이니 내 말은 듣지말도록...)

만약 값이 없다면?? (감이 있는 사람은 뭐가 나올지 알겠지.)
(get {:a "ㅎㅎㅎ"} :b)
;=nil

(get {:a "ㅎㅎㅎ"} :b "디폴트값 값이 없으면 이놈이 나오지")
;="디폴트값 값이 없으면 이놈이 나오지"

잠깐 그런게 맵.안.의.맵.의.값. 은 어떻게 가져오지?

(get (get {:A 1 :B {:C "날 뽑아낼 수 있을까?"}} :B) :C)

이걸 보는 순간 이제 리스프형의 프로그래밍이 어떻게 되는지 알 것이다. 반환하는 것을 감싸고 감싸고 감싸고.... 또 감싸다보면 상상하는 모든 일들이 벌어지는 것이다. 하지만 일단 코딩을 하기 전에 검색을 하는 버릇을 가지자. 저렇게 계속 get을 두번 사용하는 것보다 더욱 아름다워 보이는 방법이 있다.

(get-in {:A 1 :B {:C "날 뽑아낼 수 있을까?"}} [:B :C])

그리고 get이 없이 할 수도 있다.

(:C (:B {:A 1 :B {:C "날 뽑아낼 수 있을까?"}}))

왜 그런진 잘 모름. 키워드도 함수처럼 사용되는 느낌? 좀 더 내공이 쌓이면 완벽하게 이해를 할 수 있을지도...? 없을지도...

[javascript patterns][콜백함수]스터디 03


  • First List
  • Second List
  • Third List
  • Fourth List

[javascript patterns] 스터디 전.

나는 자바스크립트를 사용하지만 자바스크립트에 대해 잘 알지 못한다. 자바스크립트에 대해 책을 읽기는 하였지만 관련기술을 쓸 기회가 없다. 제이쿼리를 쓰고는 있지만 제대로 알고 있지는 않다. 하지만 분명 제대로 알고 쓰는 것과 아닌 것의 차이는 다를 것이라 믿는다. 자바스크립트는 분명 더욱더 많이 쓰게 될 것이고, 그것에 대해 여러 패턴과 안티패턴을 알아가는 것은 분명 좋은 것이라 믿는다.

2016년 10월 9일 일요일

[Mathematics for Computer Science] 스터디 03

Proposition 4.
∃x ∈ ℝ   x2-x+1 = 0
∀y ∈ ℝ+   ∃z ∈ ℝ   ez = y

∃는 존재한다(there exists)를 말하며, ∀는 전부(for all)을 말한다. 첫번째 문제는 오른쪽의 공식이 실재 값(real number로)을 가지는지 물어보는 것이다. 두번째 문제는 ez가 positive real number인 경우가 z가 real number인게 존재한다(there exitst).

Proposition 7.
∀n ∈ ℤ   (n≥2) ⇒ (n2≥4);
A ⇒ B means if A is true then B is true. ℤ denotes the set of integers, {... , -2, -1, 0, 1, 2, ...}. There is predicate nested inside this proposition.
(n≥2) ⇒ (n2≥4);
This is an example of an implication, a proposition of the form P ⇒ Q. This expression is read "P implies Q" or "if P, then Q".
함의(implication)는 명제가 다른 개념 또는 다른 명제의 의미를 포함하는 것을 말한다. 예를 들어 "나는 네 엄마다" 라는 명제가 있을 때, "엄마"는 여자라는 개념을 함의(implication)한다. 여기서 재미있는 것은 함의(implication)의 truth table이다.

P Q P ⇒ Q
T F T
T F F
F T T
F F T

중요하게 봐야 할 점은 표의 세번째 줄이다. P가 false임에도 Q가 True이면 True인 것이다. 이 내용은 다음에 제대로 다뤄보자.

2016년 10월 7일 금요일

[누구나 쉽게 배우는 클로저] 스터디 2

def 이름 정하기 : 클로저에선 def로 이름에 값을 매긴다.

(def a [1 2 3])

a
;=[1 2 3]
a 라는 이름에 [1 2 3]이라는 값이 매겨졌다. (보통 다른 언어에서는 변수(variable)에 값을 할당한다.(assign)이라고 말하는 언어도 있다.) 그렇게다면 값을 여러개 할당하여 해당 조건 마다 다른 값이 할당되는(또는 매겨지는) 것이 클로저에서도 가능할까?

자바
String a = "a"

String result = null;
if("a".equals(a))
  result = "참참참!!";
else
  result = "거짓거짓";

만약 클로저로 비슷한 것을 만든 다면?

(def a "a")
(def result nil)
(if (= a "a")
  (def result "참참참!!")
  (def result "거짓거짓"))

def만 몇개인가. 그것보다 이게 조금만 복잡해져도... clojure... 이것밖에 안되는 언어인가?!!
걱정하지 말자.

(defn res [a]
  (if (= a "a")
    "참참참"
    "거짓거짓"))
(res "a")
;=>"참참참"

아주 깔끔하다.

2016년 10월 5일 수요일

[Mathematics for Computer Science] 스터디 02

1.1-2 Propositions (명제)

Proposition 3. a4 + b+ c= dhas no solution when a, b, c, d ∈ +.
  Here denotes the positive natural numbers, {1, 2, 3, . . .}. In 1769, Euler conjectured that this proposition was true. But the it was proven false 218 years later by Noam Elkies at the liberal arts school up Mass Ave. He found the solution a  = 95800, b = 217519, c = 414560, d = 422481. We could write his assertion symbolically as follows:

 ℕ+은 자연수를 뜻한다. 위의 Proposition 은 1769년 오일러가 참이라 말한 적 있지만. 218년 뒤에 노암 엘키스(?)가 거짓이 있음을 밝혀냈다. (그 말은 값이 있음을 알아냈다는 말)

∃ a, b, c, d ∈ +   a4 + b+ c= d4

The ∃ is read "there exists". So, in words, the expression above says that there exist positive natural numbers a, b, c and d such that  a4 + b+ c= d4 .

∃는 '존재한다' 정도의 의미인듯 하다. 그러므로 [존재한다. a, b, c, d 가 자연수일때 s.t.  a4 + b+ c= d4.] 여기서 s.t. 는 such that 이며 수학에서 많이 사용하는 듯 하다.
참고.
http://mathworld.wolfram.com/SuchThat.html


[Mathematics for Computer Science] 스터디 01

Ch.1 What is Proof?

1.1-1 Propositions (명제)

A proposition is  a statement that is either true or false.
  1. 2 + 3 = 5 (참)
  2.  ∀n ∈ ℕ   n2 + n+ 41 is a prime number.
 *∀ is read "for all"
  ℕ is symbol that stands for the set of natural numbers, {0, 1, 2, 3, ...} (0이 제외일 때도 있음)



This proposition asserts that the final phrase is true for all natural numbers n. That phrase is a proposition in its own right:

"n2 + n+ 41 is a prime number"
this is a special kind of proposition called predicate, which is a proposition whose truth depends on the value of one or more variables.  This predicate is certainly true for many natural numbers n:

왼쪽은 오른쪽에 대한 명제이다. 2번의 명제는 predicate(술어)라 불리는데 이것은 변수에 따라 참이 될수도 거짓이 될 수도 있다. 그럼 저 2번 명제를 예로 들어보자
n=0   0×2 + 0 + 41 = 41 (prime number)
n=1   1×2 + 1 + 41 = 43 (prime number)
n=2   2×2 + 2 + 41 = 47 (prime number)
. . .
n=39 39×39 + 39 + 41 = 1601 (prime number)
  Experimental data like this can be useful in mathematics, but can also be misleading. In this case, when n = 40, we get  n2 + n+ 41 = 402 + 40+ 41 = 41×41, which is not prime. So Proposition 2 is actually false!

  위와 같은 실험자료(또는 경험적 데이터)는 유용할 수 있지만, 잘못된 답으로 이끌어 갈 수 있다. 여기서 n = 40일 때 거짓인 경우가 나타나므로 40을 체크하지 않으면 아마 전부 prime number이니 참이라고 생각했을 지도 모르겠다.


[Mathematics for Computer Science] 스터디 하기 전

내가 이것을 공부해야 하는 이유는 근본이 없기 때문이다.
나는 전산물리학이라는 과목을 수강한 적은 있지만 전산관련 전공자는 아니다. 내가 처음 입사한 날, 나는 전공자가 아니라는 것만으로 급이 낮아졌다. 근본이 없는 취급을 받았고 비소를 날리며 받아준 것에 감사하라는 눈빛을 나는 보았다.

Compiler를 공부해라. Algorithm을 공부해라. Design Pattern을 공부해라. 자바나 제대로 할줄 알아라. Spring을 공부해라. Python을 공부해라... 수많은 이야기를 나는 그냥 지나칠 수 없었지만 나는 똑똑하지 못하고 내가 공부해야 할 것들은 난이도가 높다.

Cousera에 알고리즘 디자인을 들어보기로 하였다. 하지만 이내 포기했다. 그 수업은 내가 기본이 없다는 것. '근본없음'이 무엇인지 뼈저리게 느끼게 해주었다.

근본이 무엇일까?
뿌리를 박아 내가 있는 위치에서 굳건히 버틸 수 있게 해줄 그런 지식은 무엇일까.
가장 땅 위에 모이지 않고, 코딩에서는 쓸모 없어 보이는 것.

나는 기초들을 공부하기로 했다.
그 첫번째가 Mathmatics for Computer Science by Eric Lehman and Tom Leighton 이다.
이 책은 영어로 되어 있으며 이미 몇 챕터를 읽었지만 다시 읽을 참이다.
Cousera에서 수강했던 강의에서 사용하는 4개의 서적을 앞으로 읽을 것이며, 필요할 때 이곳에 적어놓을 것이다.

내가 이곳에 글을 적는 이유는 이 구글이 큰 위안이 될 때가 있기 때문이다. 아무것도 하지 못하고 도대체 어떻게 해야 할지 모를 때, 나는 웹상에서 내 불안함을 해소하려했다. 길을 잃은 양처럼 수많은 문서들을 클릭하고 읽었다.

많은 답이 있지만 나를 울릴 답은 찾아내지 못했다. 사실... 답보다는 나와 같은... 나처럼 길을 잃고선, 어디론가 가고있는 사람들을 찾고 싶었던 것이다.

당신이 지금까지 겪은 많은 이야기들은 당신이 어떤 직업을 가지던 당신을 도와줄 것이나, 그 직업이 만약 개발자(아니더라도)고 당신의 많은 경험들이 이곳에서는 통하지 않는다면, 내가 위안이 될 것이다.

우리 함께 공부합시다. 포기하지 마십시오. (공부만 하지는 말고요. 삶에는 아름다운것들이 너무 많잖아요.)

2016년 10월 4일 화요일

[누구나 쉽게 배우는 클로저] 스터디 1


클로저는 리스프와 같은 구조로 괄호를 사용한다. 소괄호의 향연이다.

(+ 1 2 3)
;= 6
(str "I am" " Younghwan" " " "Nam")
;="I am Younghwan Nam"

이제 단순한 코드를 작성해 보자.

if문
(if true
  "always here"
  "never get here")
;=>"always here"
(if false
  "여긴 올리가 없지"
  "이 문장은 항상 false라 여기를 오지")
;=>"이 문장은 항상 false라 여기를 오지"

보면 알겠지만 if문은 참이면 처음 거짓이면 뒤의 내용을 반환한다. 아주 단순하다. 그런데 만약 if문에서 참일 때 두 가지의 일을 시키려면??

do
(if (= 1 1)
  (do (println "하나")
        "안녕?")
  (do (println "둘")
        "안녕."))
;=>하나
;=>"안녕?"

위에 있는 하나와 "안녕?"의 차이는 무엇일까? 하나는 콘솔에 값을 string값을 출력한 것이며 "안녕?"은 string값을 반.환. 한것이다.

when : when은 else문이 없고 조건이 참일 때 무언가를 하는 것이다. (여러개도 상관 없음)
(when true
  (println "이것도 하고")
  (println "저것도 하고")
  "이걸 반환해")
;=이것도 하고
;=저것도 하고
;="이걸 반환해"

if문 when문을 사용할 때, clojure가 참 거짓을 표현하는데 알아둬야 할 점이 있다.
(nil? 1)
;=false
(nil? nil)
;=true

nil과 false는 모두 거짓을 뜻하며 그 외는 모두 참이다.
(if "거짓!!"
  "true가 아니라도 값이 있으면 참이란다."
  "그럴리 없어!!"
)
;="true가 아니라도 값이 있으면 참이란다."
(if nil
  "nil은 참이 될 수 없습니다."
  "nil은 항상 거짓이 됩니다.")
;="nil은 항상 거짓이 됩니다."

등위 연산자 =
(= 1 1)
;=true
(= nil nil)
;=true
(= 1 2)
;=false

연산자 or , and
or 연산자는 참이 되는 값이 나오는 즉시 계속을 계산을 하
지 않고 그 값을 반환한다. 아니면 마지막 값을 반환한다. (and는 그 반대)
(or false nil :첫번째참이되는놈 :왜나도참인데반환하지않는것이냐)
;=:첫번째참이되는놈
(or false nil nil false nil)
;=nil