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

_.reduceRight doesn't pass the correct arguments to iterator when iterating an object. #729

Closed
jdalton opened this issue Aug 31, 2012 · 10 comments

Comments

@jdalton
Copy link
Contributor

jdalton commented Aug 31, 2012

_.reduceRight doesn't pass the correct arguments to iterator when iterating an object.
For a test test.js#L1205-1219.

@jashkenas
Copy link
Owner

Thanks. As right folds don't have a defined order for objects, I'm just passing them straight through as a left fold.

@jdalton
Copy link
Contributor Author

jdalton commented Sep 19, 2012

As right folds don't have a defined order for objects, I'm just passing them straight through as a left fold.

No way! You can do this by getting the _.keys of an object and then reversing them so its the reverse of whatever implementation order that's normally produced.

@jashkenas
Copy link
Owner

Alright.

@michaelficarra
Copy link
Collaborator

@jdalton: for-in iteration order isn't even guaranteed to be the same between separate iterations over the same object.

@jdalton
Copy link
Contributor Author

jdalton commented Sep 19, 2012

@michaelficarra that's usually true if you do things like delete props between iterations but we aren't doing that. The gist of what we want is that reduceRight should be the opposite of whatever order reduce produces, which can be done by reversing the _.keys() result.

@michaelficarra
Copy link
Collaborator

@jdalton: But reduce doesn't even guarantee a deterministic order. So you can't predict the enumeration order even if given the enumeration order used in the last for-in -- regardless of mutation. You should assume it shuffles the properties before every for-in.

@jdalton
Copy link
Contributor Author

jdalton commented Sep 19, 2012

@michaelficarra _.reduce and _.reduceRight can operate with certain assumptions so that in the majority of cases (in practice all cases) reduceRight returns the opposite of whatever implementation dependent ordering is done for reduce. This would allow it to work for Chrome that may iterate alpha-numerically and allow iteration for versions of IE that may iterate in a different order after deleting a property. Since the contract for reduceRight is to just iterate the reverse of reduce, I think it's more than reasonable to use a reduce like iteration, _.keys, and then reverse it.

@michaelficarra
Copy link
Collaborator

whatever implementation dependent ordering is done for reduce

This quote indicates to me that you are missing my point. What I'm trying to say is that no consistent ordering is required. So not just "choose any ordering you want", but "every time you do a for-in, choose any ordering you want (independent of your last choice)".

@jdalton
Copy link
Contributor Author

jdalton commented Sep 19, 2012

This quote indicates to me that you are missing my point. What I'm trying to say is that no consistent ordering is required.

No I get your point. I'm letting you know that there is more than a reasonable assumption here, based on basic method contracts, and implementation history. Even if an implementation is produced that generates a different order each iteration the contract of being the reverse of reduce is preserved by taking the reverse of keys(...) (the equiv order, for that instance, of reduce).

@michaelficarra
Copy link
Collaborator

Okay, so if the ordering is consistently determined, reduceRight will iterate over the keys in the opposite order, but if the ordering is nondeterministically chosen, reduceRight is just as unpredictable. Okay, I can live with that.

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

No branches or pull requests

3 participants