📜 ⬆️ ⬇️

Implementing yield in Kotlin

A recent post about the release of Kotin M5 made me want to play a little with the language (it appeared before, but the hands did not reach). I was not interested in writing classic hello worlds, I decided to come up with some intricate puzzle that would allow using various interesting language features.
Let me remind you that Kotlin is a statically-typed programming language that can be compiled into JVM bytecode or JavaScript. Developed by Jetbrains.

Kotlin has many different syntactic sweets, which allows you to do quite interesting things. The official documentation has an example (see the Higher-order functions) of the implementation of the synchronized construction as a normal function, and exactly as it looks in Java.
I had the idea to realize a yield in a similar way.


Yield


Many C # developers know and use the yield construct.
Yield is an example of coroutine implementation. The coroutine is a generalization of the notion of procedure and supports multiple entry points. In the case of the C # language, coroutines written using yield allow you to generate IEnumerable elements on the fly:
static IEnumerable<int> CountToTen() { for (int i = 0; i <= 10; ++i) { yield return i; } } 

With yield, you can write an infinite list:
 IEnumerable<int> Fibonacci() { int a = 0, b = 1; while (true) { int sum = a + b; yield return sum; a = b; b = sum; } } //--- foreach (var i in Fibonacci().Take(10)) { Console.WriteLine(i); } 

')
In Sharpe, yield is implemented at the compiler level: the Enumerator, which is a state machine, is generated from the body of the yield method. More details can be read here.

And, although for Java there are yield implementations that work by modifying bytecode and generating similar state machines, this approach is very complicated and requires additional actions with the code: an additional compilation stage or the use of custom classloaders.
To solve our problem, we will go the other way - we will use an additional stream.

Implementation


So, the idea is quite transparent - you need to implement the Producer-Consumer scheme using an additional stream, which will directly calculate the next value of the sequence as required by the main stream.

As in the case of synchronized , our yield generators will be created using the external function (Kotlin supports functions outside the classes), which will take another function as an argument and return
 Iterable.   yieldfun .       : 
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src
Iterable. yieldfun . :
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src
 Iterable.   yieldfun .       : 
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src
Iterable. yieldfun . :
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src
 Iterable.   yieldfun .       : 
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)

Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src
Iterable. yieldfun . :
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src
 Iterable.   yieldfun .       : 
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src
Iterable. yieldfun . :
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src
 Iterable.   yieldfun .       : 
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src
Iterable. yieldfun . :
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src
 Iterable.   yieldfun .       : 
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src
Iterable. yieldfun . :
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src
 Iterable.   yieldfun .       : 
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src
Iterable. yieldfun . :
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src
 Iterable.   yieldfun .       : 
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src
Iterable. yieldfun . :
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src

Iterable. yieldfun . :
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src

Iterable. yieldfun . :
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src
Iterable. yieldfun . :
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src
Iterable. yieldfun . :
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src
 Iterable.   yieldfun .       : 
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src
Iterable. yieldfun . :
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src
 Iterable.   yieldfun .       : 
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)
body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src
Iterable. yieldfun . :
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src
 Iterable.   yieldfun .       : 
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src
Iterable. yieldfun . :
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src
 Iterable.   yieldfun .       : 
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)
, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src
Iterable. yieldfun . :
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src
 Iterable.   yieldfun .       : 
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src
Iterable. yieldfun . :
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src
 Iterable.   yieldfun .       : 
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src
Iterable. yieldfun . :
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src
Iterable. yieldfun . :
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src
Iterable. yieldfun . :
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src
 Iterable.   yieldfun .       : 
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src
Iterable. yieldfun . :
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src
 Iterable.   yieldfun .       : 
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src
Iterable. yieldfun . :
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src
 Iterable.   yieldfun .       : 
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src
Iterable. yieldfun . :
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src
 Iterable.   yieldfun .       : 
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src
Iterable. yieldfun . :
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src
 Iterable.   yieldfun .       : 
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src
Iterable. yieldfun . :
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src

Iterable. yieldfun . :
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src

Iterable. yieldfun . :
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src
 Iterable.   yieldfun .       : 
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src
Iterable. yieldfun . :
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src
 Iterable.   yieldfun .       : 
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src
Iterable. yieldfun . :
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src

Iterable. yieldfun . :
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src

Iterable. yieldfun . :
fun Test() = yieldfun<Int> { (context) -> for (val i in 0 .. 3) context.yield(i); }

context - , yield.

yieldfun , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> { return YieldIterable<T>(body) }
YieldIterable body - -. , :
fun yieldfun<T> (body : (YieldContext<T>) -> Unit) : Iterable<T> = YieldIterable<T>(body)


Iterable , Iterator, YieldIterable :
private class YieldIterable<T>(val body: (YieldContext<T>) -> Unit): Iterable<T>{ public override fun iterator(): Iterator<T> = YieldIterator<T>(body) }


body ( trait) YieldContext, :
trait YieldContext<T> { fun yield(value : T) }

, yield(T) .

yield - YieldIterator:
private class YieldIterator<T> (val body: (YieldContext<T>) -> Unit): Iterator<T>, YieldContext<T> { private var thread: Thread? = null private val resultQueue = SynchronousQueue<Message>() private val continuationSync = SynchronousQueue<Any>() private var currentMessage: Message? = null { val r = object : Runnable { public override fun run() { try { continuationSync.take() body(this@YieldIterator) resultQueue.put(CompletedMessage()) } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) } } } thread = Thread(r) thread!!.start() } override fun yield(value: T) { resultQueue.put(ValueMessage(value)) continuationSync.take() } public override fun next(): T { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception if (currentMessage !is ValueMessage) throw NoSuchElementException() val value = (currentMessage as ValueMessage).value as T currentMessage = null return value } public override fun hasNext(): Boolean { evaluateNext() if (currentMessage is ExceptionThrownMessage) throw (currentMessage as ExceptionThrownMessage).exception return currentMessage is ValueMessage } private val dummy = Any() private inline fun evaluateNext() { if (currentMessage == null) { continuationSync.put(dummy) currentMessage = resultQueue.take() } } }

, , :
, . , - , put take , ( ).

resultQueue thread , - continuationSync - , .

, continuationSync . :
1) next() hasNext() , , (. evaluateNext()), .
2) body, .. .
3) - yield(T), ( ) , . , .
4) body , , .

, :
private open class Message { } private class ValueMessage(public val value: Any): Message() { } private class CompletedMessage: Message() { } private class ExceptionThrownMessage(public val exception: Throwable): Message() { }

, Test() :
assertEquals(listOf(0, 1, 2, 3), Test().toList())


yieldfun .

context
, , . it :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) it.yield(i); }
.
.. Extension function literals - body , body . YieldContext :
public fun yieldfun<T: Any>(body: YieldContext<T>.() -> Unit): Iterable<T> = YieldIterable<T>(body)

body .
? :
fun Test() = yieldfun<Int> { for (val i in 0 .. 3) yield(i); }
.. yieldfun YieldContext, YieldContext this :
this.yield(i)

, this ,
yield(i)
.. body , :
continuationSync.take() body() resultQueue.put(CompletedMessage())
, YieldIterator YieldContext, body - extension-.


. - yield :)

YieldContext ret :
public trait YieldContext<T> { fun yield(value: T): Unit val ret: YieldContext<T> }

YieldIterator this :
override val ret: YieldContext<T> = this
? :
ret.yield(i)
, yield(T) this , :
ret yield i
, .

, C# Kotlin:
fun fibonacci(): Iterable<Int> = yieldfun { var a = 0 var b = 1 while (true) { val sum = a + b; ret yield sum; a = b; b = sum; } }
, , generic- yieldfun - .


, , . . finalize() :
protected fun finalize() { thread?.interrupt() }
catch :
try { continuationSync.take() body() resultQueue.put(CompletedMessage()) } catch (e: InterruptedException) { // if not all items were iterated yield will wait for signal, so finalizer should // interrupt the thread to exit } catch (e: Throwable) { resultQueue.put(ExceptionThrownMessage(e)) }
, continuationSync , .
, , , yieldfun , InterruptedException , yield try-catch , .


, extension- .Net, .. , "" . , , Jetbrains. , Kotlin .

UPD. bitbucket.org/Nerzhul500/kyield/src

Source: https://habr.com/ru/post/168571/


All Articles