JavaScript 94

제너레이터 / 이터레이터 프로토콜로 구현하는 지연 평가

지연평가에 대해서 자세하게 알아보자. 지연평가라는 것은 게으른 평가라고도 하지만 영리하다라는 말이다. 게으르기만 하는 것이 아니라 최대한 게으르게 가장 영리하게 표현하는 것이라고 볼 수 있다. 가장 필요할 때까지 평가를 미루다가 정말 필요할 때 해당하는 코드들을 평가하면서 값들을 만들어 나가는 기법이다. 앞에서 range함수를 봤던것처럼 배열을 미리 큰 크기로 만드는 것이 아니라, 그 이후에 필요한 연산이었던 reduce를 하면서 모두 add를 한다고 하면 필요한 a값과 b값 뽑을 때 만 실제로 배열의 안쪽에 있는 값들을 만들어 내면서 값을 만드는 것을 최소화하고 연산을 조금 효율적으로 줄이는 아이디어라고 볼 수 있다. 자바스크립트에서 보여주는 것처럼 이터레이터와 제너레이터, 이터러블을 기반으로 한 프로..

take 함수

take함수를 알아보자 take함수는 아래와 같다. 인자를 두개를 받는데 l값(limit)값을 받고 이터러블을 받는다.(이터러블) 받은 이터러블을 순회를 해준다. 결과에 푸시를 해주고 결과를 담고있는 length와 limit이 같아지면 더 순회하지 않고 해당하는 번째까지만 담고서 리턴하는 함수이다. 100개의 range를 만들어서 출력을 하면 아래와 같은 결과가 나온다. take함수를 통해서 5개만 잘라볼 수 있다. log(take(5, range(100))); take 함수같은 경우에는 이터러블 프로토콜을 따르고 있고 이터러블 받아서 이터러블 안에 값을 next를 통해 순회하고 꺼내서 push만 하는 단순한 로직을 가지고 있다. 함수를 만들어 놓고 사용한다면 L.range도 사용을 할 수 있다. L.r..

range와 느긋한 L.range 테스트

이번에는 array로 모든 값을 평가한 후에 해당하는 array를 이터레이터로 만들어서 reduce를 통해 add를 하는 코드와 배열을 만들지 않고 바로 이터레이터를 만들어서 reduce를 통해 다 add를 하는 코드가 어느정도 효율성을 가지고 있는지 보자. 아주 큰 성능상의 차이는 나지않는 것을 알고있자. 테스트를 하는 간단한 함수를 만든다. 테스트이름을 받고, 얼마나 실행할지, 실행함수를 받는 함수를 정하고 어떤 테스트인지를 정해주고 time만큼 실행하기 위해서 구현을 해준다. : 0.567138671875 ms : 0.091796875 ms https://www.inflearn.com/course/functional-es6/dashboard 함수형 프로그래밍과 JavaScript ES6+ - 인프런..

range와 느긋한 range(지연성ⅰ)

간단한 버전의 range함수를 만들어 보자. 숫자하나를 받고 그 숫자하나의 크기만한 배열을 리턴하는 함수이다. 예를 들어서 아래만 구현해놓고 range를 사용한다면 [0, 1, 2, 3, 4]가 되는 배열을 리턴하고 밑에는 [0, 1] 배열을 리턴하는 함수를 만들어보자. 아래와 같이 동작하는 함수이다. range함수를 만들었는데 const range = l => { let i = -1; let res = []; while (++i < l) { res.push(i); } return res; }; log(range(5)); // [0, 1, 2, 3, 4] log(range(2)); // [0, 1] range함수를 통해서 만들어진 배열에 있는 모든 값들을 더하는 코드를 작성해본다. add라는 함수를 만들..

HTML로 출력하기

이번에는 HTML을 구성해서 화면에 출력을 해보자. 일단 아래와 같이 함수가 구성된 상태에서 진행을 해보자. 간단한 뼈대를 먼저 만들어보자. 아래결과와 같은 식으로 나온다고 생각해보자. (template literal을(` `)을 사용했다.) document.querySelector('#cart').innerHTML = ` 상품 이름 가격 수량 총 가격 반팔티 10000 30000 반팔티 10000 30000 합계 6 60000 `; 우선 총 가격과 총 수량은 이미 함수로 만들어 놓았다. const total_quantity = sum(p => p.quantity); const total_price = sum(p => p.price * p.quantity) 수량과 가격을 전달하면서 아래와 같이 넣어주자...

장바구니 예제(총 수량, 총 가격)

장바구니에 담긴 총 수량을 뽑아보는 코드를 작성해보자. 모든 quantity를 더해야 하기 때문에 products를 출발해서 quantity만 남겨놓으면 reduce를 통해서 축약하기 쉬울 것이다. 그 다음에 go를 통해 map을 하고 reduce를 하면 a와 b를 받은 다음 a + b를 해주면 총 수량이 나타나게 된다. go(products, map(p => p.quantity), reduce((a, b) => a + b), log); 함수로 만들어보자. total_quantity라고 변수를 지정해주고 products가 들어오면 수량을 리턴해주는 함수를 만들어 볼 수 있다. const total_quantity = products => go(products, map(p => p.quantity), re..

함수 조합으로 함수 만들기

같은 데이터를 가지고 두 가지의 일을 하는 코드가 아래와 같이 있다. 값을 합하는 함수 total_price를 만들어 주고 위에 두 함수에서 중복되는 코드들을 빼서 total_price안에 넣어주면 된다. // 30000 // 75000 또 코드를 쪼개서 작성할 수도 있는데 base_total_price라는 함수를 만들어서 함수를 전달을 받고(predi) 아래와 같이 해주고 위에 중복되는 부분은 base_total_price안에 넣어주고 predi함수를 넣어주는 것이다. // 30000 // 75000 이런식으로 함수형 프로그래밍에서는 고차함수들을 함수의 조합으로 만들어가면서 잘게 나뉘어진 함수들을 계속해서 쪼개면서 중복을 제거하는 식으로 더 많은 곳에서 사용될 수 있게 할 수 있다. https://ww..

go + curry를 사용하여 더 읽기 좋은 코드로 만들기

curry라는 함수 역시 함수를 값으로 다루면서 어떤함수를 원하는 시점에 평가시키는 함수이다. curry라는 함수는 함수를 받아서 함수를 리턴하고 인자를 받아서 인자가 원하는 갯수만큼의 인자가 들어왔을 때 받아두었던 함수를 나중에 평가시키는 함수이다. 첫번째 인자와 나머지 인자(a, ..._)를 받는데 만약에 인자가 두개이상 전달 되었을때라는 것을 뜻하는 것은 _에 length가 있을 때 일것이다. length가 있다면 받아둔 함수를 즉시 실행하고( f(a, ..._) ) 만약아 아니라면 다시한번 함수를 리턴한다. 그리고 그 이후에 들어올 값들을 받아오고 함수를 실행하는 함수이다. 즉 미리받은 a와 새로받은 ..._인자를 전달하는 것이다. 정리하면 함수를 받아서 함수를 리턴하고 실행되었을 때 인자가 두개..

go를 사용하여 읽기 좋은 코드로 만들기

함수를 위에서 아래로 왼쪽에서 오른쪽으로 평가하면서 연속적으로 함수를 실행하고 이전에 실행된 함수의 결과를 다음함수에게 전달하는 go라는 함수를 만들었기 때문에 아래 코드의 표현을 바꿀 수가 있다. const add = (a, b) => a + b; log( reduce( add, map(p => p.price, filter(p => p.price < 20000, products)))); console.clear(); go를 이용해서 작성을 하면 products로 시작을 하고 products를 받아서 filter를 하겠다라고 작성을 하고 products를 받아서 map을 하겠다라고 작성을 할 수가 있다. 위 코드에서 reduce를 이용해서 log를 찍어보면 결과가 잘 나오게 된다. 처음코드보다 양은 좀 ..

코드를 값으로 다루어 표현력 높이기(pipe)

pipe함수는 go함수와 다르게 함수를 return하는 함수인데 go함수는 즉시 함수들과 인자들을 전달해서 평가하는데 사용한다면 pipe는 함수는 함수들이 나열되어 있는 합성된 함수를 만드는 함수이다. pipe를 빈함수로 만들어준다. const go = (...args) => reduce((a, f) => f(a), args); const pipe = () => {}; go( 0, a => a + 1, a => a + 10, a => a + 100, log); f라는 함수를 pipe를 통해서 만드는데 코드를 전달해서 a가 있는 세 개의 함수를 연속적으로 실행하면서 축약하는 하나의 함수를 만들어서 함수를 f에다가 리턴한다. 즉 pipe함수는 함수를 리턴하는 함수이다. 로그를 실행하면서 f를 전달하면 똑같이..