Skip to content

Conversation

@t-kalinowski
Copy link

@t-kalinowski t-kalinowski commented Jun 9, 2023

Building on earlier explorations, this PR implements an iterator protocol for R.

With this PR:

  • If the OBJECT bit is set, then for will invoke a new generic on the supplied iterable, as.iterable(). The default method just reflects back the original object, and all the same code paths still exist in C, so this is a non breaking change. All this does is provide a (user-extensible) mechanism for selectively changing the iteration behavior for some object types passed to for, like factors. as.iterable() methods are expected to return anything that for can handle directly, namely, vectors or pairlists, or (new) a closure.

  • for gains the ability to accept a closure for the iterable argument. The closure is called repeatedly for each loop iteration until it returns NULL, signaling exhaustion.

@t-kalinowski t-kalinowski changed the title add as.iterable() generic, call from for loop add as.iterable() generic, call from for loop Jun 9, 2023
@crowding
Copy link

NULL has so many overloaded uses in R that it seems like a very bad choice for a sentinel value.

One alternative is to introduce a new "stopIteration" sentinel, but I think a better answer is to make the sentinel value be an argument of the iterator function. This is the approach I've taken in the iterors package. and I quite like the results.

@t-kalinowski
Copy link
Author

t-kalinowski commented Jun 17, 2023

Thanks. I agree that signaling iterator exhaustion by having the iterator return NULL is not the right approach. I've updated the PR to pass an exhausted sentinel as the first argument to the closure. The closure can signal exhaustion by returning the supplied argument.

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.

2 participants