Iterator/Generator methods and Iterator Generics

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Iterator/Generator methods and Iterator Generics

TOYAMA Nao
JS1.7 introduced iterators/generators from Python, but it misses
itertools functions [1].  I suggest ES4 supports these functions as
methods of iterators/generators and generic methods so that they can be
applied to custom generators.  For example, an implementation of
Python's ifilter in JS1.7 can be like:

var GeneratorPrototype = (function () { yield; })().__proto__;
Iterator.prototype.filter = GeneratorPrototype.filter =
function (callback, thisObject) {
  for (var i in this)
    if (callback.call(thisObject, i, this))
      yield i;
};
Iterator.filter = function (iter, callback, thisObject) {
  return Iterator.prototype.filter.call(iter, callback, thisObject);
};

Of course "Iterator" in above code will be "Enumerator" in ES4 as per
the iterators and generators proposal [2].

[1] http://docs.python.org/lib/itertools-functions.html
[2]
http://developer.mozilla.org/es4/proposals/iterators_and_generators.html#enumeration

Reply | Threaded
Open this post in threaded view
|

Re: Iterator/Generator methods and Iterator Generics

nanto_vi
Sorry, I mistook my e-mail account.

--
nanto_vi (TOYAMA Nao)
<[hidden email]>

Reply | Threaded
Open this post in threaded view
|

Re: Iterator/Generator methods and Iterator Generics

Brendan Eich-2
In reply to this post by TOYAMA Nao
On Jan 29, 2007, at 2:58 PM, TOYAMA Nao wrote:

> JS1.7 introduced iterators/generators from Python, but it misses
> itertools functions [1].  I suggest ES4 supports these functions as
> methods of iterators/generators and generic methods so that they  
> can be
> applied to custom generators.  For example, an implementation of
> Python's ifilter in JS1.7 can be like:
>
> var GeneratorPrototype = (function () { yield; })().__proto__;
> Iterator.prototype.filter = GeneratorPrototype.filter =
> function (callback, thisObject) {
>   for (var i in this)
>     if (callback.call(thisObject, i, this))
>       yield i;
> };

I was just working on this part of the proposal.

In theory it is easy to add standard library methods to the spec at  
this point if they can be expressed entirely in the new language.  In  
practice we are saying "no new features", especially to features that  
refract through the type system and runtime semantics.

However, I think the ML- and Haskell-inspired itertools from Python  
have no such effects, and should be considered for inclusion in the  
standard library specified by ES4, so we don't have to re-standardize  
them later after shipping them in Firefox N+1 without a spec ;-).

But I do not believe they should be fixed or prototype methods of  
nominal types (classes). Rather, they should simply be generic  
functions in the iterator namespace, (e.g. iterator::zip or use  
namespace iterator; ... zip(...)).

With Array and String, ES1-3 stipulated generic prototype methods,  
making for awkwardness when applying to other kinds of objects. For  
ES4, as in JS1.6+, we are reflecting these as static generic methods  
on their classes, simply using the classes as namespaces.  With the  
iterator namespace, we can do better and simply write functions.  
That's what zip, etc., are -- they are not methods.

Thanks for your timely mail.  Comments welcome.

/be

Reply | Threaded
Open this post in threaded view
|

Re: Iterator/Generator methods and Iterator Generics

Yuh-Ruey Chen
Well, you can add reimplement all the JS1.6 array extras (filter, etc.)
on Object.prototype meaningfully (except maybe map). That would make the
"intentionally generic" methods truly be generic in practice.

The downside would be the problem that all methods share: they must be
called on some non-null value. Taking the global function approach
avoids this problem - in fact, I suspect that is why Python chose this
approach. However, syntactically the method approach looks better, e.g.
array.length reads better than len(array) IMO.

-Yuh-Ruey Chen

Brendan Eich wrote:

> On Jan 29, 2007, at 2:58 PM, TOYAMA Nao wrote:
>
> > JS1.7 introduced iterators/generators from Python, but it misses
> > itertools functions [1].  I suggest ES4 supports these functions as
> > methods of iterators/generators and generic methods so that they  
> > can be
> > applied to custom generators.  For example, an implementation of
> > Python's ifilter in JS1.7 can be like:
> >
> > var GeneratorPrototype = (function () { yield; })().__proto__;
> > Iterator.prototype.filter = GeneratorPrototype.filter =
> > function (callback, thisObject) {
> >   for (var i in this)
> >     if (callback.call(thisObject, i, this))
> >       yield i;
> > };
>
> I was just working on this part of the proposal.
>
> In theory it is easy to add standard library methods to the spec at  
> this point if they can be expressed entirely in the new language.  In  
> practice we are saying "no new features", especially to features that  
> refract through the type system and runtime semantics.
>
> However, I think the ML- and Haskell-inspired itertools from Python  
> have no such effects, and should be considered for inclusion in the  
> standard library specified by ES4, so we don't have to re-standardize  
> them later after shipping them in Firefox N+1 without a spec ;-).
>
> But I do not believe they should be fixed or prototype methods of  
> nominal types (classes). Rather, they should simply be generic  
> functions in the iterator namespace, (e.g. iterator::zip or use  
> namespace iterator; ... zip(...)).
>
> With Array and String, ES1-3 stipulated generic prototype methods,  
> making for awkwardness when applying to other kinds of objects. For  
> ES4, as in JS1.6+, we are reflecting these as static generic methods  
> on their classes, simply using the classes as namespaces.  With the  
> iterator namespace, we can do better and simply write functions.  
> That's what zip, etc., are -- they are not methods.
>
> Thanks for your timely mail.  Comments welcome.
>
> /be
> _______________________________________________
> Es4-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es4-discuss
>
>  

Reply | Threaded
Open this post in threaded view
|

Re: Iterator/Generator methods and Iterator Generics

Yuh-Ruey Chen
In reply to this post by Brendan Eich-2
Brendan Eich wrote:

> But I do not believe they should be fixed or prototype methods of  
> nominal types (classes). Rather, they should simply be generic  
> functions in the iterator namespace, (e.g. iterator::zip or use  
> namespace iterator; ... zip(...)).
>
> With Array and String, ES1-3 stipulated generic prototype methods,  
> making for awkwardness when applying to other kinds of objects. For  
> ES4, as in JS1.6+, we are reflecting these as static generic methods  
> on their classes, simply using the classes as namespaces.  With the  
> iterator namespace, we can do better and simply write functions.  
> That's what zip, etc., are -- they are not methods

I was thinking about this some more. I'm not sure it's such a good idea
to put such iterator functions in the iterator namespace. |use namespace
iterator| would make the global iterator functions accessible without
qualifiers, but also make a public::get property unaccessible if
iterator::get was defined, so if I do obj.get, I can't tell whether I'm
getting public::get or iterator::get unless I manually test
obj.iterator::get, which kinda defeats the purpose of |use namespace
iterator|.

It would be nice if there was a convenient way to bind each iterator
function x to the public namespace in global scope, without having to
use |use namespace iterator| (to avoid the aforementioned problem) or
manually binding each such function x.

Furthermore, it seems inconsistent that the static versions of map,
every, replace, etc. is placed on the built-in classes/constructors (at
least in JS1.6+), e.g. String.replace, while the iterator functions get
placed in another namespace. The iterator functions could be static
methods of the Iterator class to be consistent. Or would all these
static functions be moved to other namespaces?

Since we have packages, why not place static functions in them instead
of namespaces or classes? itertools.ifilter instead of
iterator::ifilter. Then we could use the import statement to bind
itertools.ifilter to global.ifilter. It would be nice if iterator or
Iterator could be used as the package name, but that would result in a
name conflict with the iterator namespace, wouldn't it?


Reply | Threaded
Open this post in threaded view
|

Re: Iterator/Generator methods and Iterator Generics

Brendan Eich-2
On Feb 5, 2007, at 11:13 PM, Yuh-Ruey Chen wrote:

> Brendan Eich wrote:
>> But I do not believe they should be fixed or prototype methods of
>> nominal types (classes). Rather, they should simply be generic
>> functions in the iterator namespace, (e.g. iterator::zip or use
>> namespace iterator; ... zip(...)).
>>
>> With Array and String, ES1-3 stipulated generic prototype methods,
>> making for awkwardness when applying to other kinds of objects. For
>> ES4, as in JS1.6+, we are reflecting these as static generic methods
>> on their classes, simply using the classes as namespaces.  With the
>> iterator namespace, we can do better and simply write functions.
>> That's what zip, etc., are -- they are not methods
>
> I was thinking about this some more. I'm not sure it's such a good  
> idea
> to put such iterator functions in the iterator namespace. |use  
> namespace
> iterator| would make the global iterator functions accessible without
> qualifiers, but also make a public::get property unaccessible if
> iterator::get was defined

No, you could always say what you mean: obj.public::get.

> , so if I do obj.get, I can't tell whether I'm
> getting public::get or iterator::get unless I manually test
> obj.iterator::get, which kinda defeats the purpose of |use namespace
> iterator|.

Namespaces are like that. If you don't want implicit qualification,  
don't use namespace foo.

> It would be nice if there was a convenient way to bind each iterator
> function x to the public namespace in global scope, without having to
> use |use namespace iterator| (to avoid the aforementioned problem) or
> manually binding each such function x.

This is an argument for putting itertools-like functions in a package  
or namespace other than iterator. Which I see you propose below :-).

> Furthermore, it seems inconsistent that the static versions of map,
> every, replace, etc. is placed on the built-in classes/constructors  
> (at
> least in JS1.6+), e.g. String.replace, while the iterator functions  
> get
> placed in another namespace. The iterator functions could be static
> methods of the Iterator class to be consistent. Or would all these
> static functions be moved to other namespaces?

Having an Iterator class is problematic. I'm revising the wiki now  
and I'm not done yet, but one goal is to avoid telegraphing that  
there is some nominal-type-system protocol behind iteration, and to  
participate you have to subclass Iterator -- or any such thing.

> Since we have packages, why not place static functions in them instead
> of namespaces or classes? itertools.ifilter instead of
> iterator::ifilter. Then we could use the import statement to bind
> itertools.ifilter to global.ifilter.

This is the right way to go, especially if the Python itertools are  
ported under their names (but they want to drag in slice, map, and  
other Python generic functions). Still the right way to go, modulo  
that parenthetical concern.

> It would be nice if iterator or
> Iterator could be used as the package name, but that would result in a
> name conflict with the iterator namespace, wouldn't it?

iterator is the namespace name, a global constant binding. It seems  
from our spidering not to be taken (prototype.js uses iterator for  
local var names, no problem). Package names are a matter not  
addressed by ES4, but the obvious reversed FQDN prefixing seems  
likely. The Flex SDK does something like this, but IIRC the first  
component is "mx" (not com.macromedia or com.adobe ;-).

In any event, package names for standard library packages need to be  
sorted out for ES4, IMHO, but we haven't done it yet.

/be