oops, I forgot to force calls to the inner function * definitions. Another
hazard of the plan of record that my alternative proposal doesn't have. I
fixed occurrence of this bug below:
On Sep 11, 2012, at 9:42 PM, Allen Wirfs-Brock wrote:
>
> On Sep 11, 2012, at 7:48 PM, Jason Orendorff wrote:
>
>> I'd appreciate a less contrived motivating example. The best way to
>> implement this dataSnapshot() function is simply:
>>
>> function dataSnapshot(aCollection) {
>> return aCollection.clone();
>> }
>>
>> -j
>>
>
>
> My original example was something like:
>
> function *dataSnapshot(aDataSource) {
> let snapshot = aDataSource.captureCurrentState();
> for (let i=0; i<snapshot.length; i++) yield snapshot[i]
> }
>
> It wasn't actually quite as intentionally clear as the above and that
> allowed it to evolve within the thread into something that could arguably be
> restated as you show. But that was why I created the original example.
>
> The intent of the original was to show a situation where:
>
> there is a dynamically changing data source you want to analyze
> You need to capture it for the analysis while it is in a stable state
> The data capture process does not produce a "clone" but a different (perhaps
> more efficient for readonly access)
> You know how to navigate this captured data structure and want to provide a
> generator-based iteration that a analysis process can you to access its
> elements
> You need to be sure that the data is captured when at the exact point in
> program where "dataSnapshot" was invoked, not at some arbietrary later time
> when "next" is first called.
>
> I think these requirements are pretty typical of a common situation that
> occurs when you want to perform stable traversal over dynamically mutable
> object structures and the example was contrived to show some pitfalls that
> could occur if you try to do this using a generator.
>
> The original example fails for at least the last bullet. To fix that, it
> would have to be rewritten, something like:
>
> function dataSnapshot(aDataSource) {
> let snapshot = aDataSource.captureCurrentState();
> return function *() {
> for (let i=0; i<snapshot.length; i++) yield snapshot[i]
> }(); //<--- return generator instance, not the generator constructor
> }
>
> Note that this rewrite eliminates the need for an formal parameters on the
> actual generator definition.
>
> If dataSnapshot was a method on some object and the iteration results
> depended upon that object, you might have instead originally coded it as:
>
> class DataSourceAnalyzer {
> ... //a constructor and other methods
> *dataSnapshot(aDataSource) {
> let snapshot = aDataSource.captureCurrentState();
> for (let i=0; i<snapshot.length; i++) yield
> this.analyzeElement(snapshot[i]); // <--- note use of this
> }
> }
>
> This also falls the last requirement in the bullet list above. So, you might
> refactor similarly to what I did for the non-method form:
>
> class DataSourceAnalyzer {
> ... //a constructor and other methods
> dataSnapshot(aDataSource) {
> let snapshot = aDataSource.captureCurrentState();
> return function *() {
> for (let i=0; i<snapshot.length; i++) yield
> this.analyzeElement(snapshot[i]); // <--- note erroneous use of this
> }(); //<--- return generator instance, not the generator constructor
> }
> }
>
> and forget that the function * expression uses a dynamic this. If you
> remembered that you would instead have had to revert to ES<6 style this
> capture:
>
> class DataSourceAnalyzer {
> ... //a constructor and other methods
> dataSnapshot(aDataSource) {
> let snapshot = aDataSource.captureCurrentState();
> let self = this;
> return function *() {
> for (let i=0; i<snapshot.length; i++) yield
> self.analyzeElement(snapshot[i]); // <--- note use of self instead of this
> }(); //<--- return generator instance, not the generator constructor
> }
> }
>
> Using my alternative generator syntax, this would be written as:
>
> class DataSourceAnalyzer {
> ... //a constructor and other methods
> dataSnapshot(aDataSource) {
> let snapshot = aDataSource.captureCurrentState();
> return *=> for (let i=0; i<snapshot.length; i++) yield
> this(snapshot[i]); // <--- note valid of lexical this
> }
> }
>
>
>
>
>
>
> _______________________________________________
> es-discuss mailing list
> [email protected]
> https://mail.mozilla.org/listinfo/es-discuss
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss