Internal iterators in ruby

So, if I understand well, the problem with iterating over different
enumerables synchronously has to do with the absence of a #rewind and
#next method for enumerables. The Generator class solves this using the
slow #callcc method and allows one to step through the Enumerable#each
method, element by element. Wouldn't it be better if the enumerable
required a #rewind and #next method and constructs the #each method out
of these instead of doing the reverse using #callcc?
Greetings,
Geert Fannes.

You code works only for arrays, but it's quite efficient.

This works for all Enumerable types, is less efficient - and it's part
of
the std lib:

http://www.ruby-doc.org/stdlib/libdoc/generator/rdoc/classes/SyncEnumera
tor.html

Know your standard libs... :slight_smile:

Kind regards

    robert

Geert Fannes wrote:

So, if I understand well, the problem with iterating over different
enumerables synchronously has to do with the absence of a #rewind and
#next method for enumerables. The Generator class solves this using
the slow #callcc method and allows one to step through the
Enumerable#each method, element by element. Wouldn't it be better if
the enumerable required a #rewind and #next method and constructs the
#each method out of these instead of doing the reverse using #callcc?

No, this would not be better because then you would have to place
iteration state into the Enumerable which is at least ugly (it wastes
memory most of the time, i.e. the time when there is no iteration) and it
doesn't allow for multiple concurrent iterations on the same instance.

A better alternative would be to encourage providers of Enumerables to
provide an external iterator for special cases. This then will be more
efficient than callcc.

Kind regards

    robert

Geert Fannes wrote:

So, if I understand well, the problem with iterating over different
enumerables synchronously has to do with the absence of a #rewind and
#next method for enumerables. The Generator class solves this using the
slow #callcc method and allows one to step through the Enumerable#each
method, element by element. Wouldn't it be better if the enumerable
required a #rewind and #next method and constructs the #each method out
of these instead of doing the reverse using #callcc?
Greetings,
Geert Fannes.

You code works only for arrays, but it's quite efficient.

This works for all Enumerable types, is less efficient - and it's part
of
the std lib:

http://www.ruby-doc.org/stdlib/libdoc/generator/rdoc/classes/SyncEnumera
tor.html

Know your standard libs... :slight_smile:

Kind regards

   robert

This is one of the reasons that I feel that mixins should be inheritable. What you really want to do is define a descendant of Enumerable that implements those methods.

I suppose that what one could do is define a new mixin, say "TwoWayEnumerable" that implements the standard ops of a doubly linked list (getting most of them by requiring Enumerable) and use that. Since it would include the definition of Enumerable, it could be used whenever Enumerable was needed, but it could also be used in other instances, such as the one that you are proposing.

But I still feel that inheriting from SuperModules would be nicer syntactically.

Note that an internal iterator is a (capable of being atomic) method,
whereas an external iterator is an *object* holding the state of the
iterator. If you want to implement #next, you need somewhere to store
@current, and the object you're iterating over is not that place.

martin

···

Geert Fannes <Geert.Fannes@ikanconsulting.com> wrote:

So, if I understand well, the problem with iterating over different
enumerables synchronously has to do with the absence of a #rewind and
#next method for enumerables. The Generator class solves this using the
slow #callcc method and allows one to step through the Enumerable#each
method, element by element. Wouldn't it be better if the enumerable
required a #rewind and #next method and constructs the #each method out
of these instead of doing the reverse using #callcc?

Geert Fannes wrote:

So, if I understand well, the problem with iterating over different
enumerables synchronously has to do with the absence of a #rewind and
#next method for enumerables. The Generator class solves this using the
slow #callcc method and allows one to step through the Enumerable#each
method, element by element. Wouldn't it be better if the enumerable
required a #rewind and #next method and constructs the #each method out
of these instead of doing the reverse using #callcc?
Greetings,
Geert Fannes.

You code works only for arrays, but it's quite efficient.

This works for all Enumerable types, is less efficient - and it's part
of
the std lib:

http://www.ruby-doc.org/stdlib/libdoc/generator/rdoc/classes/SyncEnumera
tor.html

Know your standard libs... :slight_smile:

Kind regards

   robert

This is one of the reasons that I feel that mixins should be
inheritable. What you really want to do is define a descendant of
Enumerable that implements those methods.

You can always #include the module in your module. Or, if you
want to get fancy and it happens to suit your purposes, you
can have your module #extend another module.

I suppose that what one could do is define a new mixin, say
"TwoWayEnumerable" that implements the standard ops of a doubly linked
list (getting most of them by requiring Enumerable) and use that. Since
it would include the definition of Enumerable, it could be used whenever
Enumerable was needed, but it could also be used in other instances,
such as the one that you are proposing.

But I still feel that inheriting from SuperModules would be nicer
syntactically.

E

···

Le 4/6/2005, "Charles Hixson" <charleshixsn@earthlink.net> a écrit:

--
template<typename duck>
void quack(duck& d) { d.quack(); }

this limits you to sharing the functionality of exactly one mixin. the
current implementation allows sharing of code from many mixins.

   class TwoWayEnumerable
     include Enumerable
     include SomeMoreNiftyMethods
     include EvenMoreFunctionality
   end

ruby's single inheritence would preclude this as a possibility - at least it
would be precluded from doing in a nice way syntactically.

cheers.

-a

···

On Sun, 5 Jun 2005, Charles Hixson wrote:

Geert Fannes wrote:

So, if I understand well, the problem with iterating over different
enumerables synchronously has to do with the absence of a #rewind and
#next method for enumerables. The Generator class solves this using the
slow #callcc method and allows one to step through the Enumerable#each
method, element by element. Wouldn't it be better if the enumerable
required a #rewind and #next method and constructs the #each method out
of these instead of doing the reverse using #callcc?
Greetings,
Geert Fannes.

You code works only for arrays, but it's quite efficient.

This works for all Enumerable types, is less efficient - and it's part
of
the std lib:

http://www.ruby-doc.org/stdlib/libdoc/generator/rdoc/classes/SyncEnumera
tor.html

Know your standard libs... :slight_smile:

Kind regards

   robert

This is one of the reasons that I feel that mixins should be inheritable. What you really want to do is define a descendant of Enumerable that implements those methods.

I suppose that what one could do is define a new mixin, say "TwoWayEnumerable" that implements the standard ops of a doubly linked list (getting most of them by requiring Enumerable) and use that. Since it would include the definition of Enumerable, it could be used whenever Enumerable was needed, but it could also be used in other instances, such as the one that you are proposing.

But I still feel that inheriting from SuperModules would be nicer syntactically.

--

email :: ara [dot] t [dot] howard [at] noaa [dot] gov
phone :: 303.497.6469
My religion is very simple. My religion is kindness.
--Tenzin Gyatso

===============================================================================

Ara.T.Howard wrote:

Geert Fannes wrote:

So, if I understand well, the problem with iterating over different
enumerables synchronously has to do with the absence of a #rewind and
#next method for enumerables. The Generator class solves this using the
slow #callcc method and allows one to step through the Enumerable#each
method, element by element. Wouldn't it be better if the enumerable
required a #rewind and #next method and constructs the #each method out
of these instead of doing the reverse using #callcc?
Greetings,
Geert Fannes.

You code works only for arrays, but it's quite efficient.

This works for all Enumerable types, is less efficient - and it's part
of
the std lib:

http://www.ruby-doc.org/stdlib/libdoc/generator/rdoc/classes/SyncEnumera

tor.html

Know your standard libs... :slight_smile:

Kind regards

   robert

This is one of the reasons that I feel that mixins should be inheritable. What you really want to do is define a descendant of Enumerable that implements those methods.

I suppose that what one could do is define a new mixin, say "TwoWayEnumerable" that implements the standard ops of a doubly linked list (getting most of them by requiring Enumerable) and use that. Since it would include the definition of Enumerable, it could be used whenever Enumerable was needed, but it could also be used in other instances, such as the one that you are proposing.

But I still feel that inheriting from SuperModules would be nicer syntactically.

this limits you to sharing the functionality of exactly one mixin. the
current implementation allows sharing of code from many mixins.

  class TwoWayEnumerable
    include Enumerable
    include SomeMoreNiftyMethods
    include EvenMoreFunctionality
  end

ruby's single inheritence would preclude this as a possibility - at least it
would be precluded from doing in a nice way syntactically.

cheers.

-a

You are correct, if I had been thinking of TwoWayEnumerable as a class. What I was wishing was to use the same inheritance semantics on Modules. Since no class would be involved, there wouldn't be any restriction to "single inheritance". (Actually, I'd prefer multiple inheritance ala Eiffel or Python, but I understood when I came to Ruby that this was one feature I was abandoning.)

OTOH, I realize that this would just be equivalent to:
module TwoWayEnumerable
   include Enumerable
   include TwoWayList
  ...
end # TwoWayEnumerable

But I would prefer the look of:
module TwoWayEnumerable < Enumerable, TwoWayList
  ...
end # TwoWayEnumerable

That said, I realize that this is a truly minor point, and only a matter of taste.
(Also that the include method would need to be maintained, because sometimes on wants inclusion to be the result of a test, or to occur after a certain point in the class.)

···

On Sun, 5 Jun 2005, Charles Hixson wrote: