기본 콘텐츠로 건너뛰기

-0과 +0을 구분 할 수 있을

 0에는 부호가 없다. 수학을 배우면서 0이라는 숫자에 부호를 작성해본 적이 없을 것이다. 게다가 0에 부호가 있는가 없는 가에 수학에서는 어떠한 것도 변하지 않는다.  그도 그럴 것이 0에 어떤 값을 더하던 원래 값 그대로 반환 될 것이고, 어떤 값을 곱하던지 0 일테니까 말이다.  실제로는 없겠지만, 자바스크립트에는 0에는 부호가 존재한다.  console.log로 작석된 대로 0, -0이 확실히 찍혀 있는 것을 알 수 있다. 하지만 !== 연산자로도, 양수가 더 큰 가에 대한 질의에도 그냥 같은 값이다. 결론이 날 수 밖에 없다. 뭐 물론 아래처럼 판단하는 것은 가능하다.  Object.is는 값을 비교하는 방법 중 하나라고 알아두면 된다. 나중에 자세하게 다룰 일이 있을지는 모르겠다.  위의 상황이 무엇이 문제가 될까? 일단 수학이라면 모르지만, 우리는 프로그래밍 하는 입장에서 숫자를 0으로 나눌 수 있지만, 그러한 상황은 피하려고 한다. 하지만 그렇게 되면 어떻게 될까 저 음수와 양수의 차이가 수학과 프로그래밍과 차이가 나는 부분이라고 말할 수 있겠다. let pos = 0 let neg = - 0 pos = 1 / pos // Infinity neg = 1 / neg // -Infinity console . log ( pos > neg ) // true 수학에서는 숫자를 0으로 나누는 것이 불가능 한 연산이지만, 자바스크립트에서는 가능하며, 결과 값이 0이 음수냐 양수냐에 따라서 무한과 음수부호의 무한으로 표현이 된다.  컴퓨터가 부호를 표현하는 방법  일단 컴퓨터는 0과 1로만 값을 인지 할 수 있고, -라는 기호는 사용하지 않는다. 하지만, 일반적으로 숫자 표현시 최상위 비트(0번째 인덱스)를 부호를 표현하는 값으로 사용 한다. 0이면 양수 1이면 음수.  일단 위의 근거 만으로도 자바스크립트에 0의 부호가 있는지가 풀린다.  일단, 4비트로 표현을 하려...

가비지 컬렉션 핥기. (표시하고 쓸기)

 지난번에 가비지 컬렉션 알고리즘 중 하나인, 참조 세기를 확인 하였다. 이번에는 표시하고 쓸기 알고리즘을 확인 하려고 한다. 참조 세기의 단점인 서로 참조 하고 있는 상황에는 메모리에서 제거되지 않아, 문제가 있다고 말하였다.  표시하고 쓸기에서는 서로 참조 하고 있더라도 확실히 메모리에서 제거 할 수 있게 된다.  표시하고 쓸기를 간단하게 말하면, "닿을 수 없는 것을 메모리에서 제거한다."라고 설명 할 수 있다.  표시하고 쓸기(Mark-and-sweep) 가비지 컬렉션  닿을 수 없다. 라는 것을 확인 하기 위하여, roots라는 오브젝트 집합을 이용한다.  간단한 예시를 확인 해보자. 일단 우리는 roots라는 오브젝트를 확인 할 수 없으니, window가 roots중에 하나라고 생각 하자. var x = { a : [ 1 , 2 , 3 , 4 ] , b : 1 } var y = x . a  위의 상황에서 메모리를 표로 만들어 보자.  간단하게 위처럼 그릴수 있을 것이다. 이 상황에서 x의 값을 바꾸면 어떻게 될까? x = null  위처럼 더 이상 b(1)에 접근이 불가능 하게 된다. 이게 간단하게 표시한 표시하고 쓸기라고 보면 된다. 뭐 물론 위에서는 변수만 표현 하였지만. 실제로는 x의 값이 null로 바뀌었으니, {a, b} <= 이 객체 자체도 접근이 불가능하게 되니 메모리에서 해당 주소가 제거 될 것이다.  참조세기와 달리 닿지 않는 것을 메모리에서 제거를 하니 서로참조가 생기더라도 문제가 없다. 아래의 상황을 확인해보자. var z = { a : [ 1 , 2 ] } z . b = z . a z . a = z . b z = null  위처럼 root에서 접근 할 수 있는가? 에 대한 판단이기 때문에 위처럼 서로 참고 하고 있다하더라도 위처럼 제거 하게 된다.  조금 더 자세하게 설명 하기 위해 간단한 코드로...

가비지 컬렉션 핥기. (참조 세기)

  가비지 컬렉션이라고 많이 들어보았을 것이다. 옛날부터 개발한 사람이라면, java를 하면서 배웠을 테고, 요즘에 프런트엔드 학원에서 알려줄 지는 모르겠지만, javascript 또한 가비지 콜렉션이 있다.  가비지 컬렉션은 무엇일까? 간단히 말하자면, 사용하지 않는 메모리를 반환해주는 시스템이다. 고전적으로 c언어에서는 메모리를 할당 하는 행위를 malloc(), 해제하는 행위를 free() 두가지 함수를 사용 하여, 개발자가 직접 메모리 관리는 하였다. 뭐 물론 개발자가 전지전능하지는 않기에, 사용해야 함에도 메모리 해제를 하거나, 도달하지 못하는 변수에 메모리 할당 되어있는 경우도 있어서 메모리 누수가 발생 하기도 하였다.  가비지 컬렌션에서 가장 중요한 것은 무엇일까? 사용하지 않는 메모리 이것을 어떻게 아는가 이다. 당연하게도, 개발하는 도중에는 알 수 있는 정보이다. 하지만, 당신의 컴퓨터가 해당 변수가 언제부터 사용이 되지 않는지 알 방법은 없다. 뭐 물론 프로세스가 종료 되면 모든 메모리가 해제 될 것이다.  참조 세기(reference-counting) 가비지 컬렉션  * 요즘 브라우저는 더 이상 사용 하지 않지만, 왜 사용하지 않는지는 알아 주었으면 한다.  간단한 발상이다. 해당 변수를 참조하고 있는 변수가 있는지 확인을 하는 것 뿐이다. 예를 들어보자. var x = { a : [ 1 , 2 , 3 , 4 ] , b : 1 } var y = x . a  위의 상황에서 메모리를 표로 만들어 보자.  간단하게 위처럼 그릴수 있을 것이다. 이 상황에서 x.a의 값을 바꾸면 어떻게 될까? x . a = 'test'  [1, 2, 3, 4]의 값의 참조 횟수가 줄어들 것이다. 다시 한번 y이 값을 바꾸자. y = x . a  y에서 접근 가능 했던, [1, 2, 3, 4]는 더 이상 참조 되지 않고, 가비지 컬렉션에 의하여 메모리에서 제거 되게 ...

arguments 파해치기.

 사실 arguments는 그리 자주 쓰는 객체는 아니다. 하지만 화살표 함수( arraow function )를 배우는 사람이라면 화살표 함수( () => {} ) arguments가 없다는 설명을 들은 적은 있을 것이다.  오늘은 arguments가 어떤 속성을 가지고 있는지, 또 어떤 상황에서 사용 할 수 있을지 확인 해보도록 하자. 예제 코드를 위주로 다룰 터이니 한 번 살펴보고 적절한 상황에서 사용해보자.  arguments? function foo (a , b) { console . log (a , b) // 1 2 console . log (arguments) // Arguments(2) [1, 2, callee: ƒ, Symbol(Symbol.iterator): ƒ] } foo ( 1 , 2 )  일반 함수(function)에서 사용 할 수 있는 객체로 함수 호출시의 인자들을 확인 할 수 있다.  => a, b는 매개변수(parameter) foo( 1, 2 ) 인자(argument)라고 보면 된다.  함수 호출 시의 값을 알 수 있기에,  function foo (a , b) { console . log (a , b) // 1 2 console . log (arguments) // Arguments(2) [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ] } foo ( 1 , 2 , 3 )  위와 같이 정의 되지 않은 매개변수도 받을 수 있다.  arguments.length  arguments는 길이를 가지고 있다. 인자의 갯수를 알려준다. 하지만 배열은 아니다. 정확히는 키와 값을 가지고 있는 Map에 더 가까운 구조를 가지고 있다. 아래의 JSON.stringify만 보더라도 확인이 가능하다. function foo (a , b) { console . l...

Array.map?

지난 글에 haskell에서 정의한 functor는 아래와 같다고 하였다.   fmap :: (a -> b) -> fa -> fb  해석을 하면  1. a를 받아 b를 리턴하는 함수를 인자로 받는다.  2. a가 담긴 functor를 받아 b가 담긴 functor를 리턴한다. 자 일단 배열은 functor이고, 위와 같이 작성해보면, map :: (a -> b) -> [a] -> [b ]  1. a를 받아 b를 리턴하는 함수를 인자로 받는다.  2. a가 담긴 배열을 받아 b가 담긴 배열을 리턴한다.  이제야 배열이 functor라는 것을 순환 없이 이해 할 수 있게 되었다. 자 그러면 배열처럼 값을 순환해주는 functor를 작성해보도록 하자. function Stream (value) { this . value = value?.[ Symbol . iterator ] ? value : [] this . map = function (cb) { const res = [] for ( const v of this . value ) { res. push (cb(v)) } return new Stream (res) } } new Stream ([ 1 , 2 , 3 ]). map (x => x) // ~ [1, 2, 3] new Stream ([ 1 , 2 , 3 ]). map (x => x). map (x => x * 2 ) // ~ [2, 4, 6]  이름을 Stream으로 작성해보았다.  배열의 map과 달리 나의 경우에는 Symbol.iterator를 기준으로 삼았기에 아래와 같은 작업도 가능하게 되었다. new Stream ( '123' ). map (x => x) // ~ [1, 2, 3] new Stream ( null ). map (x => x) // ~ [] new St...

Functor.map?

 배열은 펑터인가? 맞다. map함수가 있으니 맞다. 그러면 map이 무엇인가? 사실 우리는 map이라는 함수를 만나기 전부터 map이라는 단어를 프로그래밍하는 도중 만난적이 있다.  Map이라는 자료 구조인데 키와 값을 같은 자료 구조이다. Map이라는 자료 구조자체가 키에 값을 대응시킨다. 라는 매핑에서 따서 만들어 진 자료구조일 것이다.  사실 자료구조에서 Map과 Functor.map은 같은 단어이다. 지난 내용으로 범주론을 설명하면서 A범주에서 B범주로 대응시키는 것이다. 함자라고 하였다. 그리고 그 대응시키는 함수가 사상(map)이라고 부른다.  자 그러면 오해를 풀어보자. 우리가 생각하는 map?  [1, 2, 3, 4].map( x => x + 1 ) 이 문장을 보면 우리는 배열의 데이터를 순환하면서 1씩 더해주는 무언가로 보기 때문에, map에서 순환이라는 내용을 내려놓기 힘들다.  하스켈에서 정의한 Funtor는 무엇일까?   fmap :: (a -> b) -> fa -> fb  해석을 하면  1. a를 받아 b를 리턴하는 함수를 인자로 받는다.  2. a가 담긴 functor를 받아 b가 담긴 functor를 리턴한다.    자바스크립트로 구현하면 위의 내용은 어떤 모양일까? function Functor (value) { this . value = value this . map = function (cb) { return new Functor (cb( this . value )) } }  간단하게 Functor를 구현해볼 수 있다. 당연하게도 배열을 넣게 되면 그 배열을 제대로 순회하지 못할 것이라는 것을 알 것이다. 그 부분은 다음 장부터 한번 풀어보도록 하자.  학습하면서 진행하는 블로그이며, 함수형 프로그래밍과 관련된 내용을 마치고 나서 이 산이 아닌가벼....

Functor?

  Functor가 무엇일까? Array가 Functor라는 말은 들어보았을 것이다. 뭐 다들 그러니 Functor가 맞을 것이다. 그러면 Array는 왜 Functor이고 Functor라고 말할 수 있는 최소 조건은 무엇일까? 한 번 확인해보자.  Functor  Functor는 데이터 타입이다. 뭐 Array도 데이터 타입이니 놀랄 내용도 아니다. Functor는 어떤 값을 가지고 있는 컨테이너 성격의 데이터 타입이며, 해당 값에 함수를 적용 할 수 있어야 한다. 우리가 Array안에 있는 값을 map으로 특정 함수를 적용 시키는 것과 마찬가지라고 보면 된다.  자주 들어보았을 법한 내용으로 map을 가지고 있는 객체라면, 펑터라고 보아도 된다고 많이 들었을 것이다. map이 무엇을 뜻하는 걸까? 간단하게 Array에서의 map은 내부의 값들을 순회하며, 함수를 적용하고 출력을 해주는 함수이다.  간단한 내용을 언급하자면, 내부의 값은 Functor아 아니다. 일반적으로 [1, 2, 3, 4], [true, true, false, true] 등등 원시 값들을 순회 한다고 쳐보자. 당연학게도, 숫자나 진위 값들이 map을 지원 할 리 없으니 Functor가 아니다.  ( 뭐 물론, 2차원 이상의 배열을 순회시 내부의 값은 배열들 일테니, Functor겠지만, 일반적인 상황을 따지자.)  뭐 간단하게 Functor가 무엇인지, 아직까지는 감이 안 올 수 있다. 감이 오는게 이상 할 것이겠지만....  Functor는 왜 어려울까? 어려운 거니까 어렵다.  Functor(함자)  뭐 물론 Array는 Functor이다. 이런식의 설명만 하고 마친다면 꽤나 쉬울 만한 내용일 것이다. 하지만 조금만 더 들어가보자.  함자를 설명하기 위해서는 범주론 을 간략하게나마 설명 하고자 한다. 뭐 물론 내 설명에 틀린 내용도 있을 수 있...

reduce (함수형 프로그래밍)

  지난 주제에 reduce를 소개를 하였다.  reduce를 이용하여, map, filter, compose등 여러 함수를 만들 수 있는 것을 볼 수 있었을 것이다.  뭐 눈치는 챘겠지만 함수형 프로그래밍을 공부를 하기 위하여 작성하는 포스팅들이다. 하지만, 지난번에 작성한 reduce는 아쉬운 점이 있다. for문을 사용 하였다는 것이다.  for문이 뭐가 문제인가? 라는 생각을 할 수 있겠지만, 많은 함수형 프로그래밍 언어에서는 for, while ~ do와 같은 장치는 지원하지 않는 다는 것이다. 반복문 없이 코드를 어떻게 작성하냐 싶겠지만, 우리는 모두 안다. 재귀를 사용하면 된다는 것을....  그렇다 이번에는 reduce를 재귀를 이용하여 작성을 해보려고 한다.  reduce 재귀함수 ver. function reduce ( arr , reducer , initValue ) { if ( !arr. length ) return initValue const currentValue = arr. shift () initValue = reducer( currentValue , initValue ) return reduce ( arr , reducer , initValue ) }  재귀 함수로 코드를 작성하고자 한다면 위와 같이 작성 할 수 있을 것이다. const arr = [ 1 , 2 , 3 , 4 ] reduce(arr , (c , a) => c + a , 0 ) // 10 console.log(arr) // []  정상적으로 잘 작동 하는 듯 하였지만, shift함수를 이용 해버려서 배열의 데이터를 손상 시켰다. 이 부분은 아래와 같이 수정이 가능하다. function reduce ( arr , reducer , initValue ) { if ( !arr. length ) return initValue const [currentValue, ...othe...

reduce?

 reduce는 함수형 프로그래밍을 공부하면, 항상 보게 되는 함수이다. 처음 reduce라는 함수를 마주쳤을 때, 굳이 이런 함수를 사용해야 하나, 이런생각도 해보기도 하고, 왜 감소하다라는 뜻을 갖고 있는 reduce이지? 이런생각을 해보기도 했다.  reduce는 reducer 함수에 의한 결과를 누적 해 주는 함수이다. 누적이라는 말에서 accumulate라고 불러야 하는거 아닌가? 하고 아직도 생각 하고 있는 함수이다.  reduce의 함수 reduce ( reducer : (accumulator: Any , current: Any ) => Any , initialValue: Any ) => accumulator: Any  javascript에는 Array가 이미 reduce를 지원을 하고 있기에, 아래와 같이 사용이 가능 하다. [ 1 , 2 , 3 ]. reduce ( (accumulator , current) => accumulator + current , 0 ) // 6  구현을 해보자 한다면, 아래와 같이 간단하게 구현이 가능하다. function reduce ( arr , reducer , initValue ) { let accumulator = initValue for ( let idx = 0 ; idx < arr. length ; idx++ ) { accumulator = reducer( accumulator , arr[idx] , idx , arr ) } return accumulator }  Array.reduce와 마찬가지로 사용이 가능 하다. reduce ([ 1 , 2 , 3 ] , (accumulator , current) => accumulator + current , 0 ) // 6  reduce로 만들어보기  reduce는 기본적으로 반복을 하기 때문에 forEa...

함수 합성 (function composition)

  요즘에 프로그래밍 공부를 하다보면, 다시 수학 공부를 하는 기분이 드는 중이다. 이래서 프로그래머 되려면 수학이 중요하다고 한건가? 이 생각이 드는 수준이다.  운을 띄운김에 함수 합성에 대해서 잠깐 설명 하자면, 아래와 같은 것이다. <<https://en.wikipedia.org/wiki/File:Example_for_a_composition_of_two_functions.svg>>  위의 그림은 고등학교 1학년 수학시간에 합성 함수를 공부를 하면서 본 적이 있을 것이다. 간단하게 위의 내용을 수학적 기호로 표현 하면, h(x) = (g ∘ f )(x) = g(f(x)) 이와 같이 표현이 된다. h는 f와 g의 합성함수라고 부른다.  일단 간단하게 위의 함수를 코드로 작성을 해보자. 아주 간단하게 작성 하였다. function f (x) { if (x === 1 ) return 1 if (x === 2 ) return 3 if (x === 3 ) return 1 if (x === 4 ) return 2 } function g (x) { if (x === 1 ) return 2 if (x === 2 ) return 3 if (x === 3 ) return 1 if (x === 4 ) return 2 } function h (x) { if (x === 1 ) return 2 if (x === 2 ) return 1 if (x === 3 ) return 2 if (x === 4 ) return 3 } g ( f ( 1 )) === h ( 1 )  일단 이게 함수합성이다. 그러니 별거 아니다.  함수 합성  뭐 물론 위의 방법도 훌룡한 함수 합성이다. 수학적으로는 말이다. 코드에서는 저런 스타일은 꽤 좋지 않을 것이다.  생각을 넓혀 보면 콜백지옥도 함수 합성이라고 볼 수 있다. 또한 Promise 체인을 하고 있다면,...

함수형 프로그래밍 ( 계산, 액션, 데이터 )

  이번 포스팅에서는 함수형 프로그래밍에 대한 오해에 대해 이야기 해보고자 한다. 함수형 프로그래밍을 검색을 하면 "불변성", "순수함수", "선언적" 등등의 무언가 고고한 패러다임 처럼 보이곤 한다. 그래서 지역변수를 하나라도 참조하는 순간 이건 함수형 프로그래밍이 아니야! 이런 착각이 들기도 한다.  하지만 생각해보자. 함수형 프로그래밍은 범용 프로그래밍 패러다임이다. 이 명제에는 대부분의 프로그래머들이 동의 할 것이다. 하지만 지역변수 하나 참조 했다고, 이 프로젝트는 함수형 프로그래밍 스타일로 짠 프로젝트가 아니네 할 사람은 없을 것이다. 물론 나중에 함수형 프로그래밍 스타일 이라는 단어가 생긴다면 몰라도 말이다.  뭐 물론 위의 예시가 통용되어 순수함수로 짜야 할 코드에 전역 변수를 참조하고 있다면, 그건 피해야 할 것이다. 이런 방식을 방지 하기 위하여 함수형 프로그래밍은 세 부분으로 나누어 생각해야 한다.  계산  이 부분이 함수형 프로그래밍 하면, 순수함수로써 다루어야 하는 부분이다.  계산은 이름에서 알 수 있듯이 입력으로 받은 데이터를 기반으로 값을 계산하고 출력을 반환하는 해야한다. 동일한 입력에 대해 항상 동일한 출력을 갖게 되며, 외부변수를 참조하여서는 안된다.  예를 들면, 두 정수의 곱을 계산을 하는 등, 같은 입력에는 항상 같은 결과를 리턴 해야한다.  액션  이 부분은 순수 함수가 아닌 부분이다.  외부에 존재하는 데이터베이스의 데이터를 가져오거나, 특정한 데이터를 데이터베이스에 쓰는 행위를 담당하는 등, 동일한 조작에도 실패의 가능성이 있거나, 동일한 값을 받아 올 수 없는 함수인 경우이다.  실행 횟수 및 시점에 다른 값을 출력 가능성이 있다.  데이터  데이터에 대해서는 불변성을 지원하는 것이 좋다. 함수형 프로그래밍에서는 불변성이 원칙이니 말이다. 하지만, 액션 내의 지역변수와 지금 말하고자 하는 데이터는 분리...

자바 스크립트 희소 배열.

  희소 배열이라고 들어보았나? 학부생 때 교양 혹은 전공으로 선형대수를 배웠다면, 희소 행렬이라고는 들어보았을 것이다. 들었지만 아마 기억에는 없을 수도 있겠다. 행렬에 0이 비교적 많은 행렬을 희소 행렬이라고 부른다. 0이 많다는 것은 데이터가 없다는 것으로 볼 수 있다.  뭐 물론 프로그래밍을 하면서 배열에 0이 많다고 해서 희소 배열이라고 부르지는 않을 것이다.  희소 배열  아마 알고리즘 연습을 하는 사람들은 아래와 같이 배열의 개수를 초기화하는 코드를 작성 해본 사람이 있을 것이다. let a = [] a. length = 30  인풋이던 아웃풋이던 30개로 고정되어야 하는 상황 같은 때 말이다. 위의 결과는 무엇일까? 아마도 위와 같은 코드를 작성해본 사람이라면 알 것이다.  empty가 30개 있다고 한다. 일단 난 희소 배열의 정의를 empty가 하나라도 있는 상황을 희소 배열이라고 부르겠다.  희소 배열을 만드는 방법은 아래처럼 더 있다. delete를 사용 한다던가 일부러 초기화를 안 하는 경우다. let a = [ 1 , 2 , , 4 ] delete a[ 1 ]  empty?  그래 희소 배열이 존재 하는 것은 알았다. 그러면 왜 알아야 하는가? 이것이 궁금할 수도 있다.  일단 하나만 집고 넘어가자 empty는 값도 아니고, 예약어도 아니다. 저장할 수도 없고, 읽을 수도 없다. 우리에게는 데이터가 없다는 표현으로 undefined가 있다.  하지만 empty와 undefined는 다르다! 자 아래 실험을 보자. let a = [ 1 , , 3 ] a[ 0 ] = a[ 1 ]  분명 empty의 값을 갖고 있는 1번 인덱스에서 값을 가져와 0번 인덱스에 값을 삽입 하였으나, undefined가 되어버렸다.  이는 자바스크립의 배열 객체에서 1번 인덱스를 읽는 상황에서 undefined를 리턴 하였기 때문 이라 추측 된다. ...

선언형 프로그래밍

  선언형 프로그래밍을 처음 들어보는 개발자들도 있을 것이다. 뭐 물론 그들이 모르는 것은 뭐 딱히 신기할 만한 일도 아니다. 하지만 SQL을 사용해본 개발자는 대부분일 것이다. 그나마 들어보았다면, 학생 때나, 정보처리 기사등 자격증을 따려고 공부 할 때 SQL의 특징 중 선언형 프로그래밍 언어이다. 라는 문장을 본 정도 일 것이다.  하지만 함수형 프로그래밍에 관심 있는 혹은 사용중이 개발자라면, 함수형 프로그래밍이 선언형 프로그래밍 방식 중의 하나라고 알고 있거나 함수형 프로그래밍이 선언형 프로그래밍이라고 알고 있는 개발자들도 있을 것이다.  우리가 알고있는 프로그래밍 방식은 크게 두 분류로 나뉜다. 명령형 프로그래밍 절차적 프로그래밍 객체지향형 프로그래밍 선언형 프로그래밍 논리형 프로그래밍 함수형 프로그래밍  논리형 프로그래밍이라고 하면, 아마 못 들어본 사람이 많을 것이다. 뭐 프로그래밍 언어론을 배웠다면 PROLOG언어의 특징을 보면서 들어보았을 법하다.  명령형 프로그래밍은 HOW에, 선언형 프로그래밍은  WHAT에 중점을 두는 지에 대한 차이라고 한다. 뭐 물론 시험을 볼 것이 아니라면 아 그렇구나 정도면 된다. 선언형 프로그래밍 대표인 SQL로 어떤 차이인지 맛만 보도록 하자. SELECT * FROM users WHERE user_id = 1; DELETE FROM users WHERE user_id = 1;  첫 문장은 user_id가 1인 유저의 데이터를 가져오는 문장이고,  두번째 문장은 user_id가 1인 유저의 데이터를 삭제하는 문장이다.  위 처럼 무엇을 할 지에 대한 구분이 전체를 보지 않아도 된다. SELECT, DELETE 여부에 따라 검색이냐 삭제이냐 결정이 된다.  자 그러면 자바스크립트 코드로 userList에서 userId가 1인 데이터를 찾고자 해보자.  명령형 프로그래밍 let res = [] for ( const u...

함수형 프로그래밍 겉핥기.

 1년 전에 작성한 포스팅 중에  Lodash fp 사용하기.  포스팅을 작성한 내용이 있다. 함수형 프로그래밍에 대해서 언급을 했지만, 함수형 프로그래밍을 설명되지 않아 작성을 해본다.  뭐 겉핥기이니, 절차적 프로그래밍 vs 객체지향 프로그래밍 vs 함수형 프로그래밍 중에 뭐가 좋아요? 이 질문에 답변을 해본다면 절대 해당 프로그래밍 방식들은 비교대상이 아니다. 뭐 간단하게 C++로 구구단 출력을 작성한다고 생각해보자.  1. main 메서드에서 for문으로만 구구단을 절차적 프로그래밍으로 작성 할 수 있을 것이다.  2. GuguClass를 작성하여, 객체지향 프로그래밍으로 작성 할 수 있을 것이다.  3. C++11버전 부터 사용가능함 람다표현식으로 함수형 프로그래밍을 작성 할 수 있을 것이다.  위의 예제에서는 구구단만 노출 하면 되는 것이니, 1번이 제일 낫겠다 볼 수 있을 있지만, 객체지향 프로그래밍이 각광받았던 이유가 대형 서비스를 구축할 때 절차적 프로그래밍의 한계 때문에 각광 받았다.  하지만 생각해보라. Class로 쪼갤 뿐이지, Class 내부에서 복잡한 메서드를 작성하게 될 때, 결국 함수를 호출 할 것이니, 절차적 프로그래밍이다.  이 처럼 우리가 만들 서비스에 일부분은 절차적, 객체지향, 함수형 프로그래밍은 상황에 따라서 유용한 방식이 있을 뿐이다. 앞설이 길었으니, 함수형 프로그래밍을 소개해보자.  함수형 프로그래밍  일단 함수가 무엇일까? 프로그래밍 용어가 아닌 함수 말이다. 사실 당신은 중학교 수학 시간에 함수라는 단어를 들었다. 아래의 이미지를 보면 아! 할 것이다.  함수형 프로그래밍에서의 함수는 이 수학적 함수를 말하고 있다. 수학적 함수와 우리가 사용하는 함수의 차이는 수학적 함수에는 레퍼런스 참조가 없다는 점과 외부의 값에 의존하지 않는다. 뭐 더 수많은 차이가 있겠지만, 위키를 작성 중인 것은 아니니 그렇...

옛날 코드 다시 읽기 3 (XMLHttpRequest)

  ajax라는 단어를 아는가? Asynchronous JavaScript And XML의 약자이다. xml은 json과 마찬가지로 데이터의 포맷 중 하나이다. 요즘이야 일반적으로 사용하지 않는 데이터 형태라서 익숙하지 않을 수 있지만, 뭐 아예 찾아볼 수 없을 정도로 사라진 데이터 형태는 아니다.  하지만 우리가 axios, fetch, $.ajax등으로 비동기 호출을 할 때, 웬만하면 호출과 응답을 json형태로 보내지 xml 형태로 결과를 받거나 요청 시에 데이터형태로 사용하는 경우는 드믈다. 결론은 XML이라고 표기 되어있지만, 1999년 3월에 처음 만들어진 용어이고, json을 본격적으로 사용 한 건은 2000년대 초이기 때문에, 그저 네이밍의 실패 정도일뿐 xml을 굳이 알아야 할 필요는 없다고 본다.  XMLHttpRequest  XMLHttpRequest는 서버와 상호작용 할때 사용하는 수 있는 브라우저 내장객체이다. 2000년대 초에 처음 도입 되었다.  XMLHttpRequest에서의 xml 또한 ajax처럼 xml이란 단어가 거의 의미가 없어졌다. XMLHttpRequest 서버 호출시 json형태로 호출하는 것이 지금은 지배적이다. 뭐 물론 직접적으로 사용해 본 적이 없는 개발자도 많을 것이다. 특히나 $.ajax가 나온 후부터는 웬만해서는 직접 호출 사용할 일 없었던 객체이다.  그 이유는 사용법이 꽤나 불편하기 때문인데, 아니 반대로 $.ajax로 호출하는 것이 편했기 때문일 수도 있다. 이건 예시를 보여줄 테니 그때 확인해보자.  하지만 여러 라이브러리에서 XMLHttpRequest를 사용한다.  위의 이미지는  https://github.com/jquery/jquery/blob/main/src/ajax/xhr.js  코드의 일부분이다.  위의 이미지는  https://github.com/axios/axios/blob/...