Thanks to visit codestin.com
Credit goes to github.com

Skip to content

change path functions to operate on lists of strings#876

Merged
davidchambers merged 1 commit intoramda:masterfrom
davidchambers:assoc-path
Mar 7, 2015
Merged

change path functions to operate on lists of strings#876
davidchambers merged 1 commit intoramda:masterfrom
davidchambers:assoc-path

Conversation

@davidchambers
Copy link
Member

Closes #637

This pull request introduces four new internal functions: _assoc, _assocPath, _dissoc, and _dissocPath. These are defined with as few dependencies as possible. _assoc, for example, has no dependencies whereas the existing assoc implementation depends on _extend, _map, createMapEntry, fromPairs, and keysIn!

Most significantly, this pull request changes the type of the path parameter from (dot-separated) String to [String], and updates the test suite accordingly.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What should happen if path is []?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return a clone of obj

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm thinking a no-op, just returning the obj supplied.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a question of philosophy. One can make an argument for either approach. One could argue that _assocPath (and by extension assocPath) should always return an object to which no one holds a reference. On the other hand one could argue that since Ramda promotes programming without mutation, cloning is unnecessary.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should also consider the current behaviour of R.path:

assert.strictEqual(R.path('', obj), undefined);

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

undefined is what you get for path('x', {y: 1}), yes? Seems like the same situation, analogous to find. Another unsafe function, to be sure

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the other hand one could argue that since Ramda promotes programming without mutation, cloning is unnecessary.

That's the argument I would make. I don't see a reason to treat the top-level object any different from the sub-object properties, which are references.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

noop is fine

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated.

@buzzdecafe
Copy link
Member

we should also update path* to have the same api

@CrossEye
Copy link
Member

CrossEye commented Mar 5, 2015

Is this the first internal recursion in Ramda? We've been pretty gun-shy about it after Eweda's stack problems. I don't mind here. The paths should never be long enough to worry us, but we need to note it and be wary.

This should close another issue that's been open for a while, but I'm too tired to try to find it.

@davidchambers davidchambers changed the title change R.assocPath and R.dissocPath to take a list of strings change R.path, R.assocPath, and R.dissocPath to take a list of strings Mar 5, 2015
@davidchambers
Copy link
Member Author

we should also update path* to have the same api

Good catch.

R.pathOn doesn't make sense now that we're specifying path as a list. Shall we remove it?

test/path.js Outdated
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should agree on how this should evaluate.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems to me to be the same case as this: assert.strictEqual(R.path(['j', '1'], obj), undefined);

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated.

@buzzdecafe
Copy link
Member

R.pathOn doesn't make sense now that we're specifying path as a list. Shall we remove it?

yes. do we need to deprecate first?

@davidchambers
Copy link
Member Author

do we need to deprecate first?

I don't think so. We're making breaking changes to R.path, R.pathEq, R.assocPath, and R.dissocPath. I don't see much value in preserving the old behaviour of R.pathOn for one release. Furthermore I'm against having the old R.pathOn function in a release alongside the new path functions.

@davidchambers davidchambers changed the title change R.path, R.assocPath, and R.dissocPath to take a list of strings change path functions to operate on lists of strings Mar 5, 2015
@buzzdecafe
Copy link
Member

agreed. this change has been in the air for a while anyways

@TheLudd
Copy link
Contributor

TheLudd commented Mar 5, 2015

Just curious, why is this preferred?

@buzzdecafe
Copy link
Member

Just curious, why is this preferred?

e.g. imagine you are modeling a filesystem as an object, you could have keys with '.' in them.

@buzzdecafe
Copy link
Member

🐄

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't love the obj == null guard, but removing it is a matter for a separate pull request.

@TheLudd
Copy link
Contributor

TheLudd commented Mar 6, 2015

@buzzdecafe

e.g. imagine you are modeling a filesystem as an object, you could have keys with '.' in them.

good point

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_pickBy is no longer used (except in pickBy).

@davidchambers
Copy link
Member Author

This pull request is ready for a final review.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😺

elegant

@buzzdecafe
Copy link
Member

🐄

davidchambers added a commit that referenced this pull request Mar 7, 2015
change path functions to operate on lists of strings
@davidchambers davidchambers merged commit e29cf51 into ramda:master Mar 7, 2015
@davidchambers davidchambers deleted the assoc-path branch March 7, 2015 01:03
@witoldsz
Copy link

It's too bad you did not let users using a path as a string to maintain backward compatibility and for simplicity (Ramda could internally split it on "dot" if an argumet was a string).

Sometimes it's so much easier and shorter to be able to specify "a.b.c.d" instead of awkward array notation (which is in itself useful some other times).

@CrossEye
Copy link
Member

TiIt's actually for reasons of simplicity (as opposed to those of ease) that we choose for our API not to do such different things on different input types.

However I'm with you on how nice the string-based API was compared to the array-based one. But I couldn't argue against the additional flexibility of the current approach. Luckily, it should be easy to write your own version on top of the existing one.

@witoldsz
Copy link

I wish I had convinced you to make an exception, for the sake of "a practical" adjective describing the library at the front page :)
Thanks for the Simple Made Easy link.

@CrossEye
Copy link
Member

I wish I had convinced you to make an exception, for the sake of "a practical" adjective describing the library at the front page

I discuss the notion of what we mean by "practical" in The Philosophy of Ramda and further in #1002 (comment) . I think there's a good reason not to do what you're suggesting, even though I initially argued for it as well, and even though we did it that way at first.

A number of our functions are dynamically dispatched, and we internally supply the version that works for lists or for plain objects. And we offer tranduced versions of many of our functions. But other than that, we don't vary our behavior based on argument type. I think that's a pretty clean line to draw. But creating a version that works the way you want should be as simple as:

var path = R.useWith(R.path, R.split('.'), R.identity);
path('a.b.c', {a: {b: {c: 'foo', d: 'bar'}}}); //=> 'foo'

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

Successfully merging this pull request may close these issues.

getIn (prop keypaths)

5 participants