question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Weird behavior in reduce function

See original GitHub issue

I am experiencing different behavior with the reduce function. Those two functions have different behaviors:

const fromListToMap = R.reduce((acc, attr) => {
  acc[attr.name] = attr.value
  return acc
}, {})

const fromListToMapWithoutCurrying = list => R.reduce((acc, attr) => {
  acc[attr.name] = attr.value
  return acc
}, {})(list)

Input:

[
  [
    { "name": "toto", "value": "toto1"}
  ],
  [
    { "name": "tata", "value": "tata1"}
  ],
]

Calling

 R.map(fromListToMap)(input)

returns

[
  {
    "toto": "toto1",
    "tata": "tata1"
  },
  {
    "toto": "toto1",
    "tata": "tata1"
  }

instead of

[
  {
    "toto": "toto1",
  },
  {
    "tata": "tata1"
  }

Is this a bug or an is it the expected behavior?

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:7 (4 by maintainers)

github_iconTop GitHub Comments

4reactions
buzzdecafecommented, Jul 25, 2017

I appreciate what you are trying to accomplish, and I support your desire to see these functions behave in a truly immutable way. However, I think bolting immutability onto a language that does not provide support for it – in fact, the base language is actively hostile to it – is a very difficult challenge.

Ultimately, there is no way to ensure that the reducing function is pure. And the stringify/parse solution for cloning is too naive. Suppose I am folding onto a FL-compliant Functor with map defined on the prototype? This is a common use case for Ramda users. That would fail immediately, since the clone would ignore prototype properties; and JSON does not serialize functions. Perf would already be bad using stringify/parse; now you have to accommodate cloning (or somehow reattaching) prototype properties as well?

So should you try to prove this concept, expect some skepticism. A comprehensive solution may not be so easy to reach.

3reactions
kedashoecommented, Jul 19, 2017

the second argument is the same for each function call. Is it correct?

I would not say that it is the same, the second argument is the initial value, and it is re-assigned at every step of the reduction: https://github.com/ramda/ramda/blob/v0.24.1/src/internal/_reduce.js#L11.

This argument is passed to our reducing function. In your case, you are mutating that argument:

acc[attr.name] = attr.value

, which is why you are seeing the behaviour that you are. If you were to rewrite it without using mutation, eg with R.assoc, which does not mutate its input:

const fromListToMap = R.reduce((acc, attr) => {
  return R.assoc(attr.name, attr.value, acc);
}, {})

const fromListToMapWithoutCurrying = list => R.reduce((acc, attr) => {
  return R.assoc(attr.name, attr.value, acc);
}, {})(list)

then I think you would get what you initially expected: https://goo.gl/KvxVtP

Read more comments on GitHub >

github_iconTop Results From Across the Web

node.js - Strange behaviour of reduce method in JavaScript?
Thank you for this. But I am looking for pushing element in an array (probably in a single function) until certain condition is...
Read more >
Reduce: Five Unusual Uses - Northcoders
Averaging. Here's an implementation of reduce that averages an array of numbers. It totals up, and then on the last element of the...
Read more >
Is reduce() bad? - DEV Community ‍ ‍
reduce , it's a generic function that takes two promises and returns a new one. When you add .reduce into the mix it...
Read more >
Oppositional Defiant Disorder (ODD): Symptoms & Treatment
This behavior often disrupts your child's normal daily functioning, including relationships and activities within their family and at school.
Read more >
JavaScript Array reduce() method - How it works - Codedamn
Arr.reduce() performs a reducer function on each element of the array and returns a single output. The reducer runs through all array elements...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found