Self-Contained Generator Function (JavaScript)

1

Create a function that takes in a generator function as its only parameter, and returns an object that can be used as both as a generator and a generator function for said generator. The idea is to be able to create an object that behaves like a generator (that is, it follows the iteration protocols) but also has the ability to restart itself.

For the rules:

  • SelfGenerator is the function you're creating.

  • sg is the return value of SelfGenerator.

  • genFunc is the parameter passed into SelfGenerator.

Rules:

  • sg must have a start method that returns a generator that behaves the same as the generator that would be returned by genFunc.

  • sg.start must accept parameters that will be used to create the generator it returns such that it is the same as the generator returned by passing those parameters into genFunc.

  • After sg.start(...params) has been executed, if genFunc(...params)[prop] is callable, then sg[prop] is also callable and will return the same value.

  • sg.start(...params).next(value); let a = sg.next(); and sg.start(...params); sg.next(value); let a = sg.next(); must end up with the same value for a.

  • smallest source code wins

Example:

let sg = SelfGenerator(function*(n) {
    yield n;
    yield n + 1;
    yield n + 2;
});

sg.start(1);         // Generator
sg.next();           // {value: 1, done: false}
sg.next();           // {value: 2, done: false}
sg.start(10).next(); // {value: 10, done: false}
sg.next();           // {value: 11, done: false}

Mason

Posted 2019-08-08T20:21:32.573

Reputation: 1 199

Question was closed 2019-08-10T08:21:33.087

Welcome to the site! You have tagged this [tag:code-golf] and [tag:javascript] but you have not mentioned either of those things in the body of the question. Is it meant to be code-golf? Is this meant to be Javascript only? Your question is also lacking on expectations for answers. The sentence at the top is a good start and the test cases are helpful but this really needs a thorough explanation of what makes an answer valid or invalid. – Post Rock Garf Hunter – 2019-08-08T20:42:47.850

I will also mention that in general challenges that restrict to a single language without good reason are not well received here. A good reason is usually that the concepts at play in the challenge only fit well in and are clear the language and extending them to other languages tends to be vague or unclear. – Post Rock Garf Hunter – 2019-08-08T20:44:48.917

@SriotchilismO'Zaic sorry, I thought they would be implied the code-golf and javascript would be implied, I'll incorporate your suggestions. – Mason – 2019-08-08T20:46:00.083

1@SriotchilismO'Zaic Well I have no idea how this challenge would apply to other languages. I did it in JavaScript because accomplishing this in JavaScript specifically was a fun challenge and required decent knowledge of how js object behave. – Mason – 2019-08-08T20:49:52.940

1@SriotchilismO'Zaic I would say that it's perfectly justified to place such a restriction here. Many languages don't even have a concept of functions, much less generators and objects, and trying to phrase this in a language-agnostic way would be next to impossible. – Esolanging Fruit – 2019-08-08T23:50:48.117

1What does sg must also behave as a superset of the generator returned by sg.start mean? Is this statement covered by the testcase? – tsh – 2019-08-09T01:45:40.660

@tsh I mean that if you wanted to treat sg as a generator and only use generator methods on it, it would behave exactly the same as the generator, but it also may have behaviour of its own outside the scope of a generator, e.g., the start method.

Edit: after you've called sg.start at least once. – Mason – 2019-08-09T03:15:17.143

Sorry I didn't catch your idea. Could you please add this required behavior to testcase? Should we invoke sg.next()? And what should be returned if so? – tsh – 2019-08-09T03:28:12.473

@tsh sg.start(...params).next() (just sg.next() if start has already been called) should return the same thing as argFunc(...params).next() – Mason – 2019-08-09T04:00:28.220

Should we only support the given code? Or should sg be a real generator? For example, should (function*(){}()).next.apply(sg) work? – tsh – 2019-08-09T05:50:53.787

@tsh No that needn't work, I have updated the rules to be more clear. – Mason – 2019-08-09T18:04:01.843

Let us continue this discussion in chat.

– Mason – 2019-08-09T21:07:39.173

1It's not clear to me how multiple invocations should behave: a generator function should allow the creation of independent generators, but what if the wrapped generator has side-effects? – Peter Taylor – 2019-08-10T08:25:16.410

@PeterTaylor I don't know what you mean, show me an example in the chat. – Mason – 2019-08-10T20:09:07.630

var n=0; function* gen() { while (true) yield n++; } var sg = SelfGenerator(gen); var it1 = sg.start(); it1.next(); var it2 = sg.start(); it2.next(); console.log(it1.next()); – Peter Taylor – 2019-08-10T20:33:14.050

@PeterTaylor I don't care how it1 behaves after sg.start() has been called again. The point is to have an object that behaves like a generator but can reset itself. – Mason – 2019-08-10T21:57:46.377

No answers