A couple of questions about generators&iterators

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

A couple of questions about generators&iterators

Claus Reinke
I do not understand why (1) iterators are specified using a self-updating
API when a functional API would seem preferable, or why (2) generators
are linked to functions, when block-level generators would seem to be
sufficient and less complex. In some more detail:

1. Why do iterators have an imperative API?

    As currently specified, an Iterator's next returns a {done,value} pair
    (ItrResult), updating the Iterator in place. A functional alternative
    would have next return a {done,value,next} triple, leaving the original
    Iterator unmodified.

    It seems a lot easier to implement the imperative API in terms of
    the functional one than the other way round, if one needed both.
    In practice, I do not see any advantage to forcing an imperative API.

2. Why are generators linked to functions, and not to blocks?

    It is not difficult to implement a form of generators in ES5. Here
    is one using TypeScript for classes and arrow functions (it uses
    a functional Iterator API, and .then-chained expressions instead
    of ;-chained statements):

    definition:
    https://gist.github.com/clausreinke/5984869#file-monadic-ts-L91-L125

    usage examples:
    https://gist.github.com/clausreinke/5984869#file-monadic-ts-L492-L529

    The main source-level disadvantages of these user-defined
    generators wrt built-in generators are:

    (a) lack of syntax sugar for .then-chaining

    (b) no coverage of statement blocks and their built-in control
        structures

    (a) would be cheap to fix (monad comprehensions have been
    suggested here multiple times), (b) could be fixed by introducing
    block-level generators as built-ins.

    Block-level generators are shallower than function-level ones
    (continuation reaches to the end of the current block),
    expression-level generators are even shallower (continuation
    reaches to the end of the current .then-chained expression).

    This would allow us to introduce shallow generators without
    messing with "function" - generators would simply be another
    class of object that "function" allows us to write abstraction
    over. Composing shallow continuations could be left to user-
    level functions, not built-ins, so everything but the block-level
    generators would remain (re-)programmable.

Claus
http://clausreinke.github.com/ 
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: A couple of questions about generators&iterators

Tab Atkins Jr.
On Thu, Jul 25, 2013 at 8:44 AM, Claus Reinke <[hidden email]> wrote:

> I do not understand why (1) iterators are specified using a self-updating
> API when a functional API would seem preferable, or why (2) generators are
> linked to functions, when block-level generators would seem to be sufficient
> and less complex. In some more detail:
>
> 1. Why do iterators have an imperative API?
>
>    As currently specified, an Iterator's next returns a {done,value} pair
>    (ItrResult), updating the Iterator in place. A functional alternative
> would have next return a {done,value,next} triple, leaving the original
> Iterator unmodified.
>    It seems a lot easier to implement the imperative API in terms of
>    the functional one than the other way round, if one needed both.    In
> practice, I do not see any advantage to forcing an imperative API.

The imperative API is more performant in general, as it doesn't
require the allocation of a new iterable object at every iteration.

(I also prefer the functional approach, but I understand the arguments
against it, and am fairly comfortable with languages that use
imperative iterators, like Python and PHP.)

~TJ
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: A couple of questions about generators&iterators

Brendan Eich-3
Tab Atkins Jr. wrote:
> languages that use
> imperative iterators, like Python and PHP.

And JS -- JS has mutation and objects. It's not going to swerve toward
Haskell (sorry, Claus).

Your point about allocation is on target too.

/be
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: A couple of questions about generators&iterators

Claus Reinke
>> languages that use imperative iterators, like Python and PHP.
>
> And JS -- JS has mutation and objects. It's not going to swerve toward
> Haskell (sorry, Claus).

I never understood your automated dislike of Haskell. But if you are
speaking for tc39 when claiming that JS has no aspirations towards
supporting functional APIs when possible, that would be a serious
disappointment. Personally, I believe you're selling JS short here.
 
> Your point about allocation is on target too.

With a generational collector, short-lived allocation should be free
(provided all fields need to be filled anyway). When using generators
in standard iterators loop patterns, the first copy can be reused in
the second iteration, and so on, so only one extra copy per loop
should be needed.

Claus
 
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: A couple of questions about generators&iterators

Brendan Eich-3
Claus Reinke wrote:
>>> languages that use imperative iterators, like Python and PHP.
>>
>> And JS -- JS has mutation and objects. It's not going to swerve
>> toward Haskell (sorry, Claus).
>
> I never understood your automated dislike of Haskell.

You misread me pretty badly here. Why?

I never wrote anything showing "dislike" of Haskell. Rather, I said JS's
future standards-based evolution is not going to *swerve* toward
Haskell. We are not going to make extra allocations for unwanted next
funargs.

I like functional programming. I'm multi-paradigm. JS is too, but not to
this FP-till-it-hurts extent. Objects and functions, not functions first.

> But if you are
> speaking for tc39 when claiming that JS has no aspirations towards
> supporting functional APIs when possible, that would be a serious
> disappointment. Personally, I believe you're selling JS short here.

Besides misreading me, your recent points have misread "deep" as a
modifier to "continuation", and pushed internal iteration exclusively
(which does not work in all cases as Andy said).

These errors really get in the way of your making grander claims or
plans about JS!

/be
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: A couple of questions about generators&iterators

Brendan Eich-3
In reply to this post by Claus Reinke
Claus Reinke wrote:
> With a generational collector, short-lived allocation should be free
> (provided all fields need to be filled anyway).

This is badly wrong. Nothing is free, certainly not memory use, even
with great GGC. Assuming it flies in the face of evidence that
developers face all the time, even on V8. Yet another problem to
overcome before you sell FP-till-it-hurts...

/be
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: A couple of questions about generators&iterators

Claus Reinke
In reply to this post by Brendan Eich-3
>>>> languages that use imperative iterators, like Python and PHP.
>>> And JS -- JS has mutation and objects. It's not going to swerve
>>> toward Haskell (sorry, Claus).
>>
>> I never understood your automated dislike of Haskell.
>
> You misread me pretty badly here. Why?

Your dislike of Haskell as a reference/model for JS evolution is
explicit in your quoted message. It has been obvious from earlier
exchanges.

My message didn't even mention Haskell - it said that I would prefer
functional APIs to complement JS imperative APIs where possible,
and functional APIs if it is not possible to have both (because
imperative APIs can be implemented in terms of functional APIs
more easily than the other way round).
 
> I never wrote anything showing "dislike" of Haskell. Rather, I said JS's
> future standards-based evolution is not going to *swerve* toward
> Haskell.

There is no technical argument in there, so it is an opinion, or a
preference/like/dislike.

> We are not going to make extra allocations for unwanted next
> funargs.

Ok, that touches on a technical argument. I remain to be convinced
that the cost would be high, for the reasons I gave.
 
> I like functional programming. I'm multi-paradigm. JS is too, but not to
> this FP-till-it-hurts extent. Objects and functions, not functions first.

"FP-till-it-hurts"? Why the hyperbole? I want objects and functions,
not imperative first.
 
>> But if you are
>> speaking for tc39 when claiming that JS has no aspirations towards
>> supporting functional APIs when possible, that would be a serious
>> disappointment. Personally, I believe you're selling JS short here.
>
> Besides misreading me, your recent points have misread "deep" as a
> modifier to "continuation", and pushed internal iteration exclusively
> (which does not work in all cases as Andy said).

Do you now have a problem with interpreting "deep" continuations?

https://mail.mozilla.org/pipermail/es-discuss/2011-September/016484.html
https://mail.mozilla.org/pipermail/es-discuss/2011-October/017596.html

I did not push internal iteration. I am concerned about composition,
abstraction, and refactoring. In the other thread, I started from the
observation that .forEach does not play with yield, then I tried to
re-implement the built-in for-of as a user-level function and showed
some examples of abstraction being hampered.
 
> These errors really get in the way of your making grander claims or
> plans about JS!

Is that necessary?

Claus
 
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: A couple of questions about generators&iterators

Brendan Eich-3
Claus Reinke wrote:

>>>>> languages that use imperative iterators, like Python and PHP.
>>>> And JS -- JS has mutation and objects. It's not going to swerve
>>>> toward Haskell (sorry, Claus).
>>>
>>> I never understood your automated dislike of Haskell.
>>
>> You misread me pretty badly here. Why?
>
> Your dislike of Haskell as a reference/model for JS evolution is
> explicit in your quoted message.

No. First, "dislike" sounds subjective and hostile, which I objected to
last time. Please hear me on that.

Second, or zero'th: Haskell is a static non-strict-evaluation functional
language! Your hope to push JS in that direction is misconceived on
first principles. JS is strict-evaluation, full of mutation, dynamically
typed. To make a case for more Haskell and less other language influence
in JS's evolution, you need a principled argument that overcomes these
foundational differences.

People can use JS in an FP style, refraining from mutation, using
pretend-monads. That's all allowed. But it is not and will not be how
the core language and library evolve, especially not at the price of
extra allocations (one per iteration-step).

/be
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss