4

Why would one need to use .constant(value) from lodash/fp/constant? I saw some other guys use _.constant(true) or _.constant(1) but don't really know what is the benefit of it.

From what I know .constant(value) return a function that returns the given value. I know it has something to do with functional programming, but why don't just use const VALUE = 1; instead?

Huy Vo
  • 2,418
  • 6
  • 22
  • 43
  • Immutablity is a concept from functional programming, gives some benefits for concurrency and makes your functions pure in a mathematical sense. https://stackoverflow.com/a/279522/2739274 – David Lemon Apr 10 '18 at 15:06

3 Answers3

3

One usecase would be to fill an array on creation:

  Array.from({length: 5}, _.constant(1))

but without it would be actually shorter:

  Array.from({length: 5}, () => 1);
Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
  • 2
    Right. `_.constant` is a convenience function often used to construct [iteratees](https://en.wikipedia.org/wiki/Iteratee) which always return the same value. – wbadart Apr 10 '18 at 14:02
  • I realized that one instance of the anonymous fat arrow function syntax *not* being shorter or more readable could be in returning object literal notation e.g. `_.times(7, () => { return {a: 1}})` vs. `_.times(7, _.constant({a: 1}))` – jmmygoggle Sep 13 '19 at 16:35
  • @jimmygoggle `_.times(7, () => ({ a: 1 }))` – Jonas Wilms Sep 13 '19 at 17:47
2

From https://github.com/jashkenas/underscore/issues/402#issuecomment-3112193:

// api: object.position = function(time) { return coords }
circle.position = _.constant( [10, 10] )

// api: image.fill( function(x, y) { return color })
image.fill( _.constant( black ) );

So, mainly for passing constants to APIs that expect functions. Nice.

Brian Kung
  • 3,957
  • 4
  • 21
  • 30
2

The use cases of constant only become clear to you if you understand the functional paradigm. With functional programming, literally everything can be expressed with functions. Constants are no exception. Here is a contrived example:

const map = f => xs =>
  xs.map(f);

const co = x => y => x;

console.log(
  map(co(0)) ([1,2,3]) // [0,0,0]
);

Let's implement a more complex example. We want a function that takes two monadic computations (aka actions), but we are only interested in the result of the second action. So why do we need the first action in the first place? Because we are interested in its side effect:

const chain = mx =>
  fm => x => fm(mx(x)) (x);
  
const co = x => y => x;

const seq = mx => my =>
  chain(mx) (co(my));
  
const sqr = n =>
  n * n;
  
// monadic sequence

const z = seq(console.log) (sqr);

// apply it

const r = z(5); // logging 5 is the observed effect

console.log("return value:", r); // logs the return value 25

Usually a composition with console.log would lead to an error: add(console.log(5)) (5) yields NaN. But our actual composition looks like add(co(sqr) (console.log(5)) (5) and yields 25 as desired.

However, as I mentioned above, to understand advanced functional idioms that take advantage of constant you need a proper understanding of the paradigm.