컴퓨터 프로그래밍에서 느긋한 계산법(Lazy evaluation)은 계산의 결과 값이 필요할 때까지 계산을 늦추는 기법이다. 지연 평가를 하면 필요 할 때까지 계산을 늦추면서 불필요한 계산을 줄일 수 있다.
reduce에 list를 전달하기 전에 이미 range를 실행했을 때 이 list라는 변수에 담긴 값이 배열인 상태
숫자하나를 받고 그 숫자의 크기만한 배열을 리턴 후에 그 값들을 더하는 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]
L.range에서의 list의 값은 이터레이터이다.
const L = {};
L.range = function *(l) {
let i = -1;
while (++i < l) {
yield i;
}
};
var list = L.range(4);
log(list); //뭔가 특이한게 출력됨 => 이터레이터임!
log(reduce(add, list));
function test(name, time, f) {
console.time(name);
while (time--) f();
console.timeEnd(name);
}
test('range', 10, () => reduce(add, range(1000000)));
test('L.range', 10, () => reduce(add, L.range(1000000)));
take 함수는 값을 받아서, 원하는 크기 만큼 잘라주는 함수이다.
const take = curry((l, iter) => {
let res = [];
for (const a of iter) { //받은 이터러블 순회
res.push(a); //결과에 push
if (res.length == l) return res;
//결과를 담고있는 결과의 length와 리미트가 같아지면 그만 순회
}
return res;
});
log(take(5, range(100)));
log(take(5, L.range(100)));
console.time('');
log(take(5, range(100)));
console.timeEnd('');
console.time('');
log(take(5, L.range(100)));
console.timeEnd('');
L.map은 새로운 Array를 만들지 않고, 이터러블을 순회하면서,
각 요소에 대해 함수를 적용한 값을 yield를 통해 게으른 평가를 수행한다.
평가를 미루는 성질을 가지고 평가 순서를 달리 조작할 준비가 되어있는 이터레이터를 반환하는 제너레이터
L.map = function *(f, iter) {
for (const a of iter) yield f(a); // f(a)
};
var it = L.map(a => a + 10, [1, 2, 3]);
log(it.next());
log(it.next());
log(it.next());
L.filter는 이터러블을 순회하면서, 조건결과 값이 참인 경우에만 값을 yield를 통해 발생시킨다.
L.filter = function *(f, iter) {
for (const a of iter) if (f(a)) yield a; // a
};
var it = L.filter(a => a % 2, [1, 2, 3, 4]);
log(it.next());
log(it.next());
log(it.next());
[[mapping, mapping], [filtering, filtering], [mapping, mapping]]
=
[[mapping, filtering, mapping], [mapping, filtering, mapping]]