Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

set() and over() always return a new object, even if nothing changed #2429

Closed
jedwards1211 opened this issue Jan 5, 2018 · 2 comments
Closed

Comments

@jedwards1211
Copy link

Returning the same object when nothing changed is a common convention when working with immutable objects, and I really don't see what reason there is not to do it.

var obj = {foo: {bar: 2}}
R.set(R.lensPath(['foo', 'bar']), 2, obj) === obj

Expected

Output of R.set is obj.

Actual

Output of R.set is a value deeply equal to obj.

@CrossEye
Copy link
Member

CrossEye commented Jan 7, 2018

We went down that route once before and ended up reverting it. The most relevant discussion is probably #1025.

The main point is one of being consistent in what we return. There is some small memory optimization in returning the existing object when we can, and fact we do that internally to the object, reusing what structures we can, but in a library for JS developers, this would seem fairly odd:

var objs = [{foo: {bar: 0}}, {foo: {bar: 1}}, {foo: {bar: 2}}, {foo: {bar: 3}}]
const newObjs = map(R.set(R.lensPath(['foo', 'bar']), 2), objs);

objs[0] == newObjs[0] //=> false
objs[1] == newObjs[1] //=> false
objs[2] == newObjs[2] //=> true  ???
objs[3] == newObjs[3] //=> false

@jedwards1211
Copy link
Author

jedwards1211 commented Jan 8, 2018

Yes, it is very odd to use == instead of triple equals to test equality in JS 😉

Surprising behavior is not necessarily bad; a more concrete argument in favor of always copying is that if someone mutates a return value expecting it to be a guaranteed clone, they could wind up with surprising bugs. And I can understand that you want to prevent that kind of surprise.

Immutable.js (the library I am used to) can get away with returning the same object in this case because it uses opaque data structures no one would want to mutate anyway. I decided to just make a microlibrary that mimics its API for plain JS objects in cases where I want this behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants