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

add iterator functionality and tests #235

Merged
merged 2 commits into from
Feb 23, 2015

Conversation

svozza
Copy link
Collaborator

@svozza svozza commented Feb 22, 2015

Resolves #131. I separated the iterator functionality out into a private function so that the try/catch block doesn't cause the compiler to deoptimise the whole constructor. I was also thinking it might be nice to just be able to pass an ES6 collection like a map or a set in directly and automatically have the stream return the entries but I don't think we guarantee that every iterable will have a .entries() function so I just left it.

push(null, _.nil);
}
else if (iterElem.done) {
if (iterElem.value) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

This should check specifically for undefined right? All other falsy values should be passed on.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Also, add a test for this case. done === true and value === false or something.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Sorry, yeah, that's a mistake. Whendone gets set to true value will always be undefined unless we're dealing with an iterator from a generator that uses the return keyword. I should be checking for the specific case of when done is true and value is not undefined. Not sure why there needs to be a test for value being false though?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Just a regression test for the corner case. To make sure that we correctly pass through the value when it is not undefined even though it == false.

I think the spec allows any iterator to specify a return value and not just one that vomes from a generator.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Ah sorry, I thought you meant a test in the generator function. No probs.

@vqvu
Copy link
Collaborator

vqvu commented Feb 22, 2015

Every iterable has a Symbol.iterator property though. I think if we ever support iterables, that's the iterator we should ask for, not entries.

I'm curious, does a try-catch deoptimize all enclosing functions, not just the innermost one? That's interesting if true.

};

//ES6 iterators Begin
if(global.Map && global.Symbol) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Probably no need to check for Symbol if you don't use Symbol.iterator (my original comment assumed that you would).

Also style note: space in between if and first parentheses (here and elsewhere).

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Actually, that's a good point we should just default to the Symbol.iterator property if we're given an iterable. I think it makes sense to support both as they're two sides of the same coin. One thing though, when I do something like:

else if (typeof Symbol !== 'undefined' && xs[Symbol.iterator]) {
            return iteratorGenerator(xs[Symbol.iterator]());
        }

ESLint gives me an error saying Symbol is not defined, should I be checking for global variables using the _global object where the global nil object gets deined?

Also, I think you're right about the deoptimisation only applying to the inner function, I was misremembering that Bluebird performance doc.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yeah, it think just using _global would work.

@svozza svozza force-pushed the 130-accept-iterators-as-source branch from 318d410 to d526171 Compare February 23, 2015 09:31
//probably a promise
return promiseGenerator(xs);
}
else if (_.isFunction(xs.next)) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Oh, and maybe a comment here saying not to swap the order of the iterator and iterable checks.

Generators are both, and their Symbol.iterator returns this, so swapping the checks will result in an infinite loop.

@svozza svozza force-pushed the 130-accept-iterators-as-source branch from e2f5cd5 to e1a5a3a Compare February 23, 2015 12:51
add node v0.12 test env

add iterable support

use falsy value in custom iterator test

update comments/docs and add check undefined function

fix typo

use of Set in docs was incorrect
@svozza svozza force-pushed the 130-accept-iterators-as-source branch from e1a5a3a to f4b070f Compare February 23, 2015 13:01
push(null, _.nil);
}
else if (iterElem.done) {
if (iterElem.value !== void 0) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Use _.isUndefined here too?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done.

@vqvu
Copy link
Collaborator

vqvu commented Feb 23, 2015

Alright. Thanks for bearing with me! :)

This is awesome, by the way.

vqvu added a commit that referenced this pull request Feb 23, 2015
Add support for constructing from iterator/iterable. Resolves #131.
@vqvu vqvu merged commit 10a516a into caolan:master Feb 23, 2015
@svozza
Copy link
Collaborator Author

svozza commented Feb 23, 2015

Not all all, a proper and thorough code review saves so much pain down the road. :)

@svozza svozza deleted the 130-accept-iterators-as-source branch February 23, 2015 14:11
@svozza
Copy link
Collaborator Author

svozza commented Feb 23, 2015

Just noticed a problem with the docs, the link to the iterator protocol wasn't being created properly. I've fixed it but will I reopen and commit the change to this branch or just create a new PR?

@vqvu
Copy link
Collaborator

vqvu commented Feb 23, 2015

Just make a new PR.

@svozza svozza mentioned this pull request Apr 9, 2015
@vqvu vqvu added this to the v2.5.0 milestone Apr 17, 2015
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.

Create a Highland Stream directly from an ES6 Iterator/Generator
2 participants