-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Initial transducers implementation #878
Conversation
Alternative to #865 |
Note, the mocha tests pass, but it is failing on creation of |
thanks for doing this so fast @kevinbeaty .
have you tried |
a3fff44
to
7439d16
Compare
All is well now. |
Man, this is a lot of work! I dropped the ball on this because i got very discouraged by the perf numbers. However, there is much that is good about this impl (if I say so myself) and there may be opportunities to optimize later. I am thinking more and more about using properties on functions to store metadata about them, as recommended long ago by @megawac . I wonder if we could include an iteration strategy on a function, s.t. when called e.g. That would address one of my primary concerns about this approach as it stands today: It is very invasive, essentially routing all iteration through |
Wow. This is amazing. |
I think we could change the iteration strategy internally to the Something like: var symRamdaMeta = typeof Symbol !== 'undefined' ? Symbol('ramdaMeta') : '@@ramdaMeta'
fn[symRamdaMeta] = {}
// in _transduceDispatch or transduce... whatever makes sense
fn[symRamdaMeta].iterationStrategy = 'transduce' |
👍
I was imagining a reference to a function, maybe something like: fn[symRamdaMeta].strategy = {
lazy: lzIter,
xf: xfIter,
//... etc.
}; then the implementation of |
Ah. Gotcha. That could work well.
Do you want me to propose something and update the PR, or are you saying this is a separate issue? |
I would like to build/see a smaller scale proof of concept first. So I think a separate issue/PR makes sense |
ada9d83
to
ae33328
Compare
I updated the PR with a few minor changes to Using old version (map through reduce in common case on my laptop):
Using new version (map using internal _map in common case):
Does this make you feel better about things? I can update the other functions to fallback to the internal versions if you like this approach. |
fc7730e
to
4c6fcf8
Compare
wow @kevinbeaty that is quite an improvement |
Latest update, after a few more tweaks to
|
🎆 |
Yeah. So TIL that So is that a 👍 to convert the rest of the |
i'm pretty gobsmacked actually. well done! and yes, let's proceed. Anyone else have $0.02 to contribute? |
Ok. Converted the other functions and removed no longer needed helper functions (including A few notes:
|
do any other libs have these object methods that we want to enable point-free composition for? most of these seem to be pretty array specific. |
took a quick look:
so for the most part i guess we do want to dispatch on these; in some cases we may have to alias 😱 if we want interoperability |
Incorporated latest tweaks from @AutoSponge and @davidchambers |
* used to convert the final accumulator into the return type and in most cases is R.identity. | ||
* The init function is used to provide the initial accumulator. | ||
* | ||
* The iteration is performed with R.reduce after initializing the transducer. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Terrific description!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
👍 looks pretty much good to me. I would say making a |
* @func | ||
* @memberOf R | ||
* @category List | ||
* @sig a -> b -> c -> a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't quite right. Perhaps something like this:
a -> (b -> b) -> [c] -> a
I sense there's some relationship between a
, b
, and c
, but this might only be apparent in b
's methods.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will change here and similarly in transduce.
This is fantastic. I've finally gotten through a once-over of everything and managed to run some performance tests (no significant changes for current benchmarks; presumably there would be speed-ups in combination ones we never wrote.) I'm very, very impressed! I was barely listening as the initial passes at this stuff was going on. I knew what you were talking about but not much about how you were going about it. This looks really well-done. I wouldn't delay merging the code for this, as we can address it later. But I'd like to either have a discussion or to learn about reasons already discussed for choosing function constructors over var _curry2 = require('./_curry2');
module.exports = _curry2(function _xmap(f, xf) {
return {
xf: xf,
f: f,
init: function() {
return this.xf.init();
},
result: function(result) {
return this.xf.result(result);
},
step: function(result, input) {
return this.xf.step(result, this.f(input));
}
};
}); It's not at all that I think one of these other options is necessarily better, but I think we should consider them... unless this was already hashed out when I was not paying attention. Really nice work! |
- Squashed from buzzedecafe:transduce - Rebased to master - Discussed in ramduce - Credits to @buzzdecafe and @kedashoe Squashed Commits: - we have a map transducer - reduce uses _xwrap for use with functions - _dispatchable as transducers when passed a transformer - _isIterable uses _symIterator - Fix filter/map to use _dispatchable appropriately - Curry _xany, _xfilter, _xmap for use with _dispatchable - Transducers for take, takeWhile, drop, dropWhile - transduce tests - Add into - all and any working - Add find, findLast, findIndex and findLastIndex transducers - Allow null/undefined accumulators when checking reduced - groupBy transducer
|
All options worth exploring.
👍 Please :) |
Everyone ok with merging this one? This is one of our most sweeping changes to date, so I'd really like to hear from @buzzdecafe, @davidchambers, @kedashoe, and (I suppose 😉) @kevinbeaty if there any objections. Of course anyone is free to chime in. (Especially you @megawac. 😉) |
let's do it -- big thanks to @kevinbeaty and @kedashoe for their great work -- particularly reviving this when i had dropped the ball. One caveat -- this now means we have clojure-style iterators when transducing. SO they support array-like, string, iterator-protocol, and object; this means weird unspecified behavior when iterating objects because of indeterminate iteration order. |
👍 Great work. One question, would this constitute a major or minor version? |
since we're pre-1.0 I think we can get away with a minor bump |
Actually, there is no implicit object iteration in this PR for this very reason (we could certainly add it in the future). It currently supports merging objects on the accumulator side but iteration of objects must be explicit (using ES6 style |
i stand corrected! thanks @kevinbeaty |
🌳 |
Initial transducers implementation
🎉 |
🎊 👯 🎈 |
Fantastic work! |
Awesome. I have to admit, hitting that "Delete Branch" button felt pretty good ;) Thanks all. |
Squashed Commits: