# Functional Programming With Javascript: Generator, Lazy functions

We made basic util functions map, filter, reduce, and so on. In this posting, we’ll make additional functions using ‘Generator’.

# Generator

`function* generator() {  console.log('one');  yield 1;    console.log('two');  yield 2;  console.log('three');  yield 3;  console.log('four');}const iterable = generator();console.log(iterable);console.log(iterable.next());console.log(iterable.next());console.log(iterable.next());console.log(iterable.next());----------------------------- Console -----------------------------Object [Generator] {}one{ value: 1, done: false }two{ value: 2, done: false }three{ value: 3, done: false }four{ value: undefined, done: true }`

Looking at the code above, iterable waits for calling the ‘next’ function and returns {value, done}. The generator function stops at the ‘yield’ statement. And when the ‘next’ function is called, continue the next line.

Why do we need this feature? Lazy evaluation can reduce unnecessary calculation. Sometimes, we don’t have to calculate all elements of the collection(For example, we need just the first-page list). We can get the correct result by calculating only the number of elements that are finally needed.

Expressed in pictures, a normal map evaluates all of the function’s values and then starts the next function.

But lazy function evaluates to the final function one by one.

# Lazy functions

## Lazy map

`function *map(collection, mapper) {  for (const value of collection) {    yield mapper(value);  }}module.exports = map;`

‘for … of …’ statement and spread syntax can access iterable’s values. The lazy map yields a mapped value.

`test('map', () => {  const squared = map([1, 2, 3, 4, 5], (value) => {    console.log(value);    return value * value;  });  expect(squared.next().value).toBe(1);  expect(squared.next().value).toBe(4);});----------------------------- Console -----------------------------12`

The test case success. The map function squares the elements. The difference is ‘iteratee’ function is called just twice! It’s more efficient:)

## Lazy filter

`function* filter(collection, predicate) {  for (const value of collection) {    if (predicate(value)) {      yield value;    }  }}module.exports = filter;`

Similar to the ‘map’, we can implement ‘filter’.

`test('filter', () => {  let called = 0;  const odds = filter([1, 2, 3, 4, 5], (value) => {    called++;    return value % 2;  });  expect(odds.next().value).toBe(1);  expect(odds.next().value).toBe(3);  expect(called).toBe(3);});`

In this code, to get the secondly filtered element, the iteratee function has to be called three times(because 2 is not an odd number).

The ‘reduce’ function must calculate to the end of the element so lazy is not exist.

Github Source Code