Yield return in Java

399 views
Skip to first unread message

Jim Blackler

unread,
Oct 12, 2008, 5:20:33 PM10/12/08
to java...@googlegroups.com
Hello all

I've just finished a little library and article about my efforts to
emulate a form of C#'s yield return in Java.

It uses a new thread and a SynchronousQueue object to enable any
calculating function to return its output through a standard Java
iterator.

The post is here .. http://jimblackler.net/blog/?p=61

I'd be interested in any views.

Jim

Christian Catchpole

unread,
Oct 13, 2008, 12:11:02 AM10/13/08
to The Java Posse
Cool. I have become a real fan of iterators. Can you interrupt the
calculating function? What happens if you throw away the iterator
without fully iterating it? Will the thread block forever or does
finalize clean it up?

On Oct 13, 7:20 am, "Jim Blackler" <jimblack...@gmail.com> wrote:
> Hello all
>
> I've just finished a little library and article about my efforts to
> emulate a form of C#'s yield return in Java.
>
> It uses a new thread and a SynchronousQueue object to enable any
> calculating function to return its output through a standard Java
> iterator.
>
> The post is here ..http://jimblackler.net/blog/?p=61

Jim Blackler

unread,
Oct 13, 2008, 4:31:09 AM10/13/08
to java...@googlegroups.com
Thanks Christian.

Since the calculating thread is held between each result, if you stop
calling next() on the iterator it effectively suspends the calculation
process.

When the iterator drops out of scope if becomes eligible for
collection. On finalize() it interrupts the collecting thread
associated with it. I've written tests to make sure the threads get
cleared on garbage collection following incomplete reads.

If you don't want to wait for GC, you can call dispose() on the
iterators (provided you use their concrete type
YieldAdapterIterator<T>). This might be necessary if you had thousands
of semi-complete calculations as a lack of threads is not going to
trigger GC in the way lack of memory would. Alternatively you could
call System.gc() manually.

Jim

2008/10/13 Christian Catchpole <chri...@catchpole.net>:

Casper Bang

unread,
Oct 13, 2008, 6:50:57 AM10/13/08
to The Java Posse
Very cool, continuations is another thing we need to bring down
ceremony and housekeeping in Java. I would think your impl stands a
better chance at being adopted into Java than Aviad Ben Dov's Yielder,
although I am not sure about the (performance?) drawbacks of either
over native support.

/Casper

On Oct 12, 11:20 pm, "Jim Blackler" <jimblack...@gmail.com> wrote:
> Hello all
>
> I've just finished a little library and article about my efforts to
> emulate a form of C#'s yield return in Java.
>
> It uses a new thread and a SynchronousQueue object to enable any
> calculating function to return its output through a standard Java
> iterator.
>
> The post is here ..http://jimblackler.net/blog/?p=61

Christian Catchpole

unread,
Oct 14, 2008, 7:17:36 PM10/14/08
to The Java Posse
Obviously, you might try to write algorithms that operate as normal
iterators. I would be avoiding the multi-thread model if possible.
The yield approach I guess if for cases where this isn't practical.

I was thinking that you could even use this as an aggregator for
multiple threads. For example, multiple HTTP service threads could
all be delivering objects to a single iterator, which iterates
forever, processing the results on a single thread.

Jim Blackler

unread,
Oct 15, 2008, 8:17:42 AM10/15/08
to java...@googlegroups.com
Absolutely, the first option would be to return your own iterator and
handle the logic in that. It would be easier to debug and you'd have
no threading issues.

Where it is difficult to do that is when the calculating algorithm
uses recursion. For the examples of my yield return library I wrote an
algorithm that returns all combinations a word might have its letters
rearranged into, with no repeats. This uses recursion. A function
takes a StringBuffer and an array of letter frequencies. For each
letter in turn it is added to the string buffer, removed from the
frequency array and if any letters remain the function calls itself
back.

I attempted to write an alternative version that had all its logic in
an iterator.next(). I expected this to be longer and more complex than
the version that used recursion. However In the hour or so I put aside
for the task I couldn't even get a version working. I'm sure its
possible, but I learned that it can be extremely difficult to convert
from an algorithm that uses recursion and sends results during the
collection, to one that calculates each value on demand.

Jim

2008/10/15 Christian Catchpole <chri...@catchpole.net>:

mikeb01

unread,
Oct 15, 2008, 3:06:51 PM10/15/08
to The Java Posse
There is a yield implementation that is implemented using byte code
modification to get the same functionality:

http://code.google.com/p/infomancers-collections/

Mike.

On Oct 16, 1:17 am, "Jim Blackler" <jimblack...@gmail.com> wrote:
> Absolutely, the first option would be to return your own iterator and
> handle the logic in that. It would be easier to debug and you'd have
> no threading issues.
>
> Where it is difficult to do that is when the calculating algorithm
> uses recursion. For the examples of my yield return library I wrote an
> algorithm that returns all combinations a word might have its letters
> rearranged into, with no repeats. This uses recursion. A function
> takes a StringBuffer and an array of letter frequencies. For each
> letter in turn it is added to the string buffer, removed from the
> frequency array and if any letters remain the function calls itself
> back.
>
> I attempted to write an alternative version that had all its logic in
> an iterator.next(). I expected this to be longer and more complex than
> the version that used recursion. However In the hour or so I put aside
> for the task I couldn't even get a version working. I'm sure its
> possible, but I learned that it can be extremely difficult to convert
> from an algorithm that uses recursion and sends results during the
> collection, to one that calculates each value on demand.
>
> Jim
>
> 2008/10/15 Christian Catchpole <christ...@catchpole.net>:

Jim Blackler

unread,
Oct 15, 2008, 3:24:02 PM10/15/08
to java...@googlegroups.com
Hi Mike

That's the Aviad Ben Dov method mentioned in the article. I'm not sure
as to the state of that project as Aviad has described it as broken in
a reply to my article.

Jim

2008/10/15 mikeb01 <mik...@gmail.com>:

Reply all
Reply to author
Forward
0 new messages