This page is no longer maintained — Please continue to the home page at www.scala-lang.org

C# async implemented in scala (based on delimited continuations)

28 replies
daniel.kroeni
Joined: 2008-09-30,
User offline. Last seen 1 year 46 weeks ago.

Hi all

In order to get a better understanding about delimited continuations I
tried to implement something akin to C# async [1]. Since I think this
has the potential to be cool, I share it with you. I would appreciate
any hints and comments.

As a substitute for C#s Tasks I went with akka 2.0 Futures [2] since
those will eventually be integrated into the main library [3] afaik.
I have the following:

== Example ==

context(GUI) { implicit ec =>
async {
m("1")

val contentCom = await { dlWebSite("http://www.google.com") }
m("2 " + contentCom)

val contentCh = await { dlWebSite("http://www.google.ch") }
m("3 " + contentCh)

val contentDe = await { dlWebSite("http://www.google.de") }
m("4 " + contentDe)
}
}

// Returns a Future which will eventually hold the downloaded html.
// The download itself is scheduled on a thread pool.
def dlWebSite(url: String): Future[String] = Future {
m("downloading: " + url)
Source.fromURL(new URL(url))
(Codec.ISO8859).getLines.mkString.take(20)
}(ThreadPool)

// Prints msg prefixed with the name of the current thread
def m(msg: String) = println(Thread.currentThread().getName() + " '" +
msg + "'")

== Output ==

UI '1'
pool-1-thread-1 'downloading: http://www.google.com'
UI '2 Unit@suspendable): Unit = reset[Unit,Unit]
{ block }

// The await method takes a block which returns a Future[A] and
// pretends to return an A to the caller. Without continuations, this
would be
// only possible by waiting (blocking) on the future until the result
is ready.
def await[A](block: => Future[A])(implicit ec: ExecutionContext =
ThreadPool): A@suspendable = shift { cont: (A => Unit) =>
block onSuccess { case r => ec.execute{ cont(r) } }
}

// The context method is used to put an ExecutionContext into scope
// which runs the given block. It primarily exists to give nice
// looking examples.
def context[T](ec: ExecutionContext)(block: ExecutionContext => T)
{ ec.execute{ block(ec) } }

// Dummy placeholder to simulate the Swing event dispatching thread
val GUI =
ExecutionContexts.fromExecutor(Executors.newSingleThreadExecutor(
new ThreadFactory{ def newThread(r: Runnable): Thread = new
Thread(r,"UI")}))

// Thread pool for the heavy background work
val ThreadPool = ExecutionContexts.fromExecutorService(

Executors.newFixedThreadPool(10))

// Runnables without the noise
implicit def toRunnable[T](f: => T ): Runnable = new Runnable { def
run() = f }

== The Problem ==

I would like the async block to return a Future of its syntactic
return value:

val a: Future[Int] = async[Int] {
m("1")
val com = await[String,Int,NotLast] {
dlWebSite("http://www.google.com")
}
m("2 " + com)

val ch = await[String,Int,NotLast] {
dlWebSite("http://www.google.ch")
}
m("3 " + ch)

val de = await[String,Int,Last] {
dlWebSite("http://www.google.de")
}
m("4 " + de)

de.length() // this should be returned as a Future[Int]
}
a onSuccess { case r => m("res" + r) }

== Output ==

UI '1'
pool-1-thread-1 'downloading: http://www.google.com'
UI '2 B@cpsParam[B,Future[B]]): Future[B] =
reset[B,Future[B]] { block }

// The D[_] type parameter is required in @cpsParam.
// Depending on the given type the matching implicit is searched.
def await[A,B,D[_]] (block: => Future[A])
(implicit ec: ExecutionContext = ThreadPool,
f: (=> Future[A]) => ExecutionContext => A@cpsParam[D[B],Future[B]]
):A@cpsParam[D[B],Future[B]] = f(block)(ec)

type Last[X] = X

// The last await needs a continuation form A => Last[B] which is from
A => B
implicit def last[A,B]: (=> Future[A]) => ExecutionContext =>
A@cpsParam[Last[B],Future[B]] = {
block => ec => shift[A,Last[B],Future[B]] { cont: (A => Last[B]) =>
val p = Promise[B]()(ec)
block onSuccess { case a => ec.execute{ p.success(cont(a)) } }
p
}
}

type NotLast[X] = Future[X]

// All other awaits need a continuation from A => NotLast[B]
// which is from A => Future[B]
implicit def notLast[A,B]: (=> Future[A]) => ExecutionContext =>
A@cpsParam[NotLast[B],Future[B]] = {
block => ec => shift[A,NotLast[B],Future[B]] { cont: (A =>
NotLast[B]) =>
val p = Promise[B]()(ec)
block onSuccess { case a =>
ec.execute{ p.completeWith(cont(a)) } }
p
}
}

This was the best solution I was able to come up with. Of course I
could offer two different await methods which would be a simple
solution if they had different names. But that is not an option. BTW I
am fully aware that the presented code has at most toy quality (
handles only onSuccess, etc.). Anyway, thanks for reading that far. If
you want to learn about scala's continuations I recommend reading this
blog post [4] by Jim McBeath.

Thanks Daniel

[1] http://msdn.microsoft.com/en-us/vstudio/gg316360
[2] http://akka.io/docs/akka/2.0-RC1/scala/futures.html
[3] http://docs.scala-lang.org/sips/pending/futures-promises.html
[4] http://jim-mcbeath.blogspot.com/2010/08/delimited-continuations.html

Tiark Rompf
Joined: 2009-02-18,
User offline. Last seen 42 years 45 weeks ago.
Re: C# async implemented in scala (based on delimited continuat

Sweet! Would this version of async

def async[A](body: => A @suspendable) = {
val p = promise[A]
reset { p success body }
p
}

work for the extended case you mention?

val a: Future[Int] = async[Int] {
val com = await { dlWebSite("http://www.google.com") }
com.length
}

a onSuccess { case r => .... }

- Tiark

On Feb 16, 2012, at 1:28 AM, Daniel wrote:

> Hi all
>
> In order to get a better understanding about delimited continuations I
> tried to implement something akin to C# async [1]. Since I think this
> has the potential to be cool, I share it with you. I would appreciate
> any hints and comments.
>
> As a substitute for C#s Tasks I went with akka 2.0 Futures [2] since
> those will eventually be integrated into the main library [3] afaik.
> I have the following:
>
>
> == Example ==
>
> context(GUI) { implicit ec =>
> async {
> m("1")
>
> val contentCom = await { dlWebSite("http://www.google.com") }
> m("2 " + contentCom)
>
> val contentCh = await { dlWebSite("http://www.google.ch") }
> m("3 " + contentCh)
>
> val contentDe = await { dlWebSite("http://www.google.de") }
> m("4 " + contentDe)
> }
> }
>
> // Returns a Future which will eventually hold the downloaded html.
> // The download itself is scheduled on a thread pool.
> def dlWebSite(url: String): Future[String] = Future {
> m("downloading: " + url)
> Source.fromURL(new URL(url))
> (Codec.ISO8859).getLines.mkString.take(20)
> }(ThreadPool)
>
> // Prints msg prefixed with the name of the current thread
> def m(msg: String) = println(Thread.currentThread().getName() + " '" +
> msg + "'")
>
>
> == Output ==
>
> UI '1'
> pool-1-thread-1 'downloading: http://www.google.com'
> UI '2 pool-1-thread-3 'downloading: http://www.google.ch'
> UI '3 pool-1-thread-5 'downloading: http://www.google.de'
> UI '4
> As you can see, the hard work is executed on a thread pool but the
> results are again on the UI thread. No blocking behind the scenes.
>
>
> == Implementation ==
>
> // The async method is nothing more than a nice name for
> // scala.util.continuations.reset
> def async[B](block: => Unit@suspendable): Unit = reset[Unit,Unit]
> { block }
>
> // The await method takes a block which returns a Future[A] and
> // pretends to return an A to the caller. Without continuations, this
> would be
> // only possible by waiting (blocking) on the future until the result
> is ready.
> def await[A](block: => Future[A])(implicit ec: ExecutionContext =
> ThreadPool): A@suspendable = shift { cont: (A => Unit) =>
> block onSuccess { case r => ec.execute{ cont(r) } }
> }
>
> // The context method is used to put an ExecutionContext into scope
> // which runs the given block. It primarily exists to give nice
> // looking examples.
> def context[T](ec: ExecutionContext)(block: ExecutionContext => T)
> { ec.execute{ block(ec) } }
>
> // Dummy placeholder to simulate the Swing event dispatching thread
> val GUI =
> ExecutionContexts.fromExecutor(Executors.newSingleThreadExecutor(
> new ThreadFactory{ def newThread(r: Runnable): Thread = new
> Thread(r,"UI")}))
>
> // Thread pool for the heavy background work
> val ThreadPool = ExecutionContexts.fromExecutorService(
>
> Executors.newFixedThreadPool(10))
>
> // Runnables without the noise
> implicit def toRunnable[T](f: => T ): Runnable = new Runnable { def
> run() = f }
>
>
> == The Problem ==
>
> I would like the async block to return a Future of its syntactic
> return value:
>
> val a: Future[Int] = async[Int] {
> m("1")
> val com = await[String,Int,NotLast] {
> dlWebSite("http://www.google.com")
> }
> m("2 " + com)
>
> val ch = await[String,Int,NotLast] {
> dlWebSite("http://www.google.ch")
> }
> m("3 " + ch)
>
> val de = await[String,Int,Last] {
> dlWebSite("http://www.google.de")
> }
> m("4 " + de)
>
> de.length() // this should be returned as a Future[Int]
> }
> a onSuccess { case r => m("res" + r) }
>
>
> == Output ==
>
> UI '1'
> pool-1-thread-1 'downloading: http://www.google.com'
> UI '2 pool-1-thread-3 'downloading: http://www.google.ch'
> UI '3 pool-1-thread-5 'downloading: http://www.google.de'
> UI '4 UI 'res20'
>
> The good part is that it works. The problem is, that now all
> those hairy type declarations are required. I could life with
> await[String,Int] {...} but my solution requires a further type
> parameter to distinguish whether it is the last await in a reset
> block or not. The last await turns the Int into a Future[Int]
> and all awaits above that last one need to reflect this in their
> type. Here is the code:
>
> // Better name for reset. Takes a block with a syntactic return type
> // of B and returns a Future[B]
> def async[B](block: => B@cpsParam[B,Future[B]]): Future[B] =
> reset[B,Future[B]] { block }
>
> // The D[_] type parameter is required in @cpsParam.
> // Depending on the given type the matching implicit is searched.
> def await[A,B,D[_]] (block: => Future[A])
> (implicit ec: ExecutionContext = ThreadPool,
> f: (=> Future[A]) => ExecutionContext => A@cpsParam[D[B],Future[B]]
> ):A@cpsParam[D[B],Future[B]] = f(block)(ec)
>
>
> type Last[X] = X
>
> // The last await needs a continuation form A => Last[B] which is from
> A => B
> implicit def last[A,B]: (=> Future[A]) => ExecutionContext =>
> A@cpsParam[Last[B],Future[B]] = {
> block => ec => shift[A,Last[B],Future[B]] { cont: (A => Last[B]) =>
> val p = Promise[B]()(ec)
> block onSuccess { case a => ec.execute{ p.success(cont(a)) } }
> p
> }
> }
>
> type NotLast[X] = Future[X]
>
> // All other awaits need a continuation from A => NotLast[B]
> // which is from A => Future[B]
> implicit def notLast[A,B]: (=> Future[A]) => ExecutionContext =>
> A@cpsParam[NotLast[B],Future[B]] = {
> block => ec => shift[A,NotLast[B],Future[B]] { cont: (A =>
> NotLast[B]) =>
> val p = Promise[B]()(ec)
> block onSuccess { case a =>
> ec.execute{ p.completeWith(cont(a)) } }
> p
> }
> }
>
> This was the best solution I was able to come up with. Of course I
> could offer two different await methods which would be a simple
> solution if they had different names. But that is not an option. BTW I
> am fully aware that the presented code has at most toy quality (
> handles only onSuccess, etc.). Anyway, thanks for reading that far. If
> you want to learn about scala's continuations I recommend reading this
> blog post [4] by Jim McBeath.
>
> Thanks Daniel
>
>
> [1] http://msdn.microsoft.com/en-us/vstudio/gg316360
> [2] http://akka.io/docs/akka/2.0-RC1/scala/futures.html
> [3] http://docs.scala-lang.org/sips/pending/futures-promises.html
> [4] http://jim-mcbeath.blogspot.com/2010/08/delimited-continuations.html

Viktor Klang
Joined: 2008-12-17,
User offline. Last seen 1 year 27 weeks ago.
Re: C# async implemented in scala (based on delimited continuat

I think we already got this covered with the dataflow API in Akka:

http://akka.io/docs/akka/2.0-RC1/scala/dataflow.html

Cheers,

On Thu, Feb 16, 2012 at 12:40 PM, Tiark Rompf wrote:
> Sweet! Would this version of async
>
> def async[A](body: => A @suspendable) = {
>        val p = promise[A]
>        reset { p success body }
>        p
> }
>
> work for the extended case you mention?
>
> val a: Future[Int] = async[Int] {
>        val com = await { dlWebSite("http://www.google.com") }
>        com.length
> }
>
> a onSuccess { case r => .... }
>
>
> - Tiark
>
>
> On Feb 16, 2012, at 1:28 AM, Daniel wrote:
>
>> Hi all
>>
>> In order to get a better understanding about delimited continuations I
>> tried to implement something akin to C# async [1]. Since I think this
>> has the potential to be cool, I share it with you. I would appreciate
>> any hints and comments.
>>
>> As a substitute for C#s Tasks I went with akka 2.0 Futures [2] since
>> those will eventually be integrated into the main library [3] afaik.
>> I have the following:
>>
>>
>> == Example ==
>>
>> context(GUI) { implicit ec =>
>> async {
>>   m("1")
>>
>>   val contentCom = await { dlWebSite("http://www.google.com") }
>>   m("2 " + contentCom)
>>
>>   val contentCh =  await { dlWebSite("http://www.google.ch") }
>>   m("3 " + contentCh)
>>
>>   val contentDe = await { dlWebSite("http://www.google.de") }
>>   m("4 " + contentDe)
>> }
>> }
>>
>> // Returns a Future which will eventually hold the downloaded html.
>> // The download itself is scheduled on a thread pool.
>> def dlWebSite(url: String): Future[String] = Future {
>>  m("downloading: " + url)
>>  Source.fromURL(new URL(url))
>> (Codec.ISO8859).getLines.mkString.take(20)
>> }(ThreadPool)
>>
>> // Prints msg prefixed with the name of the current thread
>> def m(msg: String) = println(Thread.currentThread().getName() + " '" +
>> msg + "'")
>>
>>
>> == Output ==
>>
>> UI '1'
>> pool-1-thread-1 'downloading: http://www.google.com'
>> UI '2 > pool-1-thread-3 'downloading: http://www.google.ch'
>> UI '3 > pool-1-thread-5 'downloading: http://www.google.de'
>> UI '4 >
>> As you can see, the hard work is executed on a thread pool but the
>> results are again on the UI thread. No blocking behind the scenes.
>>
>>
>> == Implementation ==
>>
>> // The async method is nothing more than a nice name for
>> // scala.util.continuations.reset
>> def async[B](block: => Unit@suspendable): Unit = reset[Unit,Unit]
>> { block }
>>
>> // The await method takes a block which returns a Future[A] and
>> // pretends to return an A to the caller. Without continuations, this
>> would be
>> // only possible by waiting (blocking) on the future until the result
>> is ready.
>> def await[A](block: => Future[A])(implicit ec: ExecutionContext =
>> ThreadPool): A@suspendable = shift { cont: (A => Unit) =>
>> block onSuccess { case r => ec.execute{ cont(r) } }
>> }
>>
>> // The context method is used to put an ExecutionContext into scope
>> // which runs the given block. It primarily exists to give nice
>> // looking examples.
>> def context[T](ec: ExecutionContext)(block: ExecutionContext => T)
>> { ec.execute{ block(ec) } }
>>
>> // Dummy placeholder to simulate the Swing event dispatching thread
>> val GUI =
>> ExecutionContexts.fromExecutor(Executors.newSingleThreadExecutor(
>>  new ThreadFactory{ def newThread(r: Runnable): Thread = new
>> Thread(r,"UI")}))
>>
>> // Thread pool for the heavy background work
>> val ThreadPool = ExecutionContexts.fromExecutorService(
>>
>> Executors.newFixedThreadPool(10))
>>
>> // Runnables without the noise
>> implicit def toRunnable[T](f: => T ): Runnable = new Runnable { def
>> run() = f }
>>
>>
>> == The Problem ==
>>
>> I would like the async block to return a Future of its syntactic
>> return value:
>>
>> val a: Future[Int] = async[Int] {
>> m("1")
>> val com = await[String,Int,NotLast] {
>>    dlWebSite("http://www.google.com")
>> }
>> m("2 " + com)
>>
>> val ch =  await[String,Int,NotLast]  {
>>    dlWebSite("http://www.google.ch")
>> }
>> m("3 " + ch)
>>
>> val de = await[String,Int,Last] {
>>    dlWebSite("http://www.google.de")
>> }
>> m("4 " + de)
>>
>> de.length() // this should be returned as a Future[Int]
>> }
>> a onSuccess { case r => m("res" + r) }
>>
>>
>> == Output ==
>>
>> UI '1'
>> pool-1-thread-1 'downloading: http://www.google.com'
>> UI '2 > pool-1-thread-3 'downloading: http://www.google.ch'
>> UI '3 > pool-1-thread-5 'downloading: http://www.google.de'
>> UI '4 > UI 'res20'
>>
>> The good part is that it works. The problem is, that now all
>> those hairy type declarations are required. I could life with
>> await[String,Int] {...} but my solution requires a further type
>> parameter to distinguish whether it is the last await in a reset
>> block or not. The last await turns the Int into a Future[Int]
>> and all awaits above that last one need to reflect this in their
>> type. Here is the code:
>>
>> // Better name for reset. Takes a block with a syntactic return type
>> // of B and returns a Future[B]
>> def async[B](block: => B@cpsParam[B,Future[B]]): Future[B] =
>> reset[B,Future[B]] { block }
>>
>> // The D[_] type parameter is required in @cpsParam.
>> // Depending on the given type the matching implicit is searched.
>> def await[A,B,D[_]] (block: => Future[A])
>> (implicit ec: ExecutionContext = ThreadPool,
>> f: (=> Future[A]) => ExecutionContext => A@cpsParam[D[B],Future[B]]
>> ):A@cpsParam[D[B],Future[B]] = f(block)(ec)
>>
>>
>> type Last[X] = X
>>
>> // The last await needs a continuation form A => Last[B] which is from
>> A => B
>> implicit def last[A,B]: (=> Future[A]) => ExecutionContext =>
>> A@cpsParam[Last[B],Future[B]] = {
>> block => ec => shift[A,Last[B],Future[B]] { cont: (A => Last[B]) =>
>>   val p = Promise[B]()(ec)
>>   block onSuccess { case a =>  ec.execute{ p.success(cont(a)) } }
>>   p
>> }
>> }
>>
>> type NotLast[X] = Future[X]
>>
>> // All other awaits need a continuation from A => NotLast[B]
>> // which is from A => Future[B]
>> implicit def notLast[A,B]: (=> Future[A]) => ExecutionContext =>
>> A@cpsParam[NotLast[B],Future[B]] = {
>> block => ec => shift[A,NotLast[B],Future[B]] { cont: (A =>
>> NotLast[B]) =>
>>   val p = Promise[B]()(ec)
>>   block onSuccess { case a =>
>> ec.execute{ p.completeWith(cont(a))  } }
>>   p
>> }
>> }
>>
>> This was the best solution I was able to come up with. Of course I
>> could offer two different await methods which would be a simple
>> solution if they had different names. But that is not an option. BTW I
>> am fully aware that the presented code has at most toy quality (
>> handles only onSuccess, etc.). Anyway, thanks for reading that far. If
>> you want to learn about scala's continuations I recommend reading this
>> blog post [4] by Jim McBeath.
>>
>> Thanks Daniel
>>
>>
>> [1] http://msdn.microsoft.com/en-us/vstudio/gg316360
>> [2] http://akka.io/docs/akka/2.0-RC1/scala/futures.html
>> [3] http://docs.scala-lang.org/sips/pending/futures-promises.html
>> [4] http://jim-mcbeath.blogspot.com/2010/08/delimited-continuations.html
>

Tiark Rompf
Joined: 2009-02-18,
User offline. Last seen 42 years 45 weeks ago.
Re: C# async implemented in scala (based on delimited continuat

Yes, the differences are minor:

def flow[A](body: => A @cps[Future[Any]]): Future[A]

def async[A](body: => A @suspendable): Future[A]

this one avoids the Future[Any] part.

- Tiark

On Feb 16, 2012, at 12:48 PM, √iktor Ҡlang wrote:

> I think we already got this covered with the dataflow API in Akka:
>
> http://akka.io/docs/akka/2.0-RC1/scala/dataflow.html
>
> Cheers,
> √
>
> On Thu, Feb 16, 2012 at 12:40 PM, Tiark Rompf wrote:
>> Sweet! Would this version of async
>>
>> def async[A](body: => A @suspendable) = {
>> val p = promise[A]
>> reset { p success body }
>> p
>> }
>>
>> work for the extended case you mention?
>>
>> val a: Future[Int] = async[Int] {
>> val com = await { dlWebSite("http://www.google.com") }
>> com.length
>> }
>>
>> a onSuccess { case r => .... }
>>
>>
>> - Tiark
>>
>>
>> On Feb 16, 2012, at 1:28 AM, Daniel wrote:
>>
>>> Hi all
>>>
>>> In order to get a better understanding about delimited continuations I
>>> tried to implement something akin to C# async [1]. Since I think this
>>> has the potential to be cool, I share it with you. I would appreciate
>>> any hints and comments.
>>>
>>> As a substitute for C#s Tasks I went with akka 2.0 Futures [2] since
>>> those will eventually be integrated into the main library [3] afaik.
>>> I have the following:
>>>
>>>
>>> == Example ==
>>>
>>> context(GUI) { implicit ec =>
>>> async {
>>> m("1")
>>>
>>> val contentCom = await { dlWebSite("http://www.google.com") }
>>> m("2 " + contentCom)
>>>
>>> val contentCh = await { dlWebSite("http://www.google.ch") }
>>> m("3 " + contentCh)
>>>
>>> val contentDe = await { dlWebSite("http://www.google.de") }
>>> m("4 " + contentDe)
>>> }
>>> }
>>>
>>> // Returns a Future which will eventually hold the downloaded html.
>>> // The download itself is scheduled on a thread pool.
>>> def dlWebSite(url: String): Future[String] = Future {
>>> m("downloading: " + url)
>>> Source.fromURL(new URL(url))
>>> (Codec.ISO8859).getLines.mkString.take(20)
>>> }(ThreadPool)
>>>
>>> // Prints msg prefixed with the name of the current thread
>>> def m(msg: String) = println(Thread.currentThread().getName() + " '" +
>>> msg + "'")
>>>
>>>
>>> == Output ==
>>>
>>> UI '1'
>>> pool-1-thread-1 'downloading: http://www.google.com'
>>> UI '2 >> pool-1-thread-3 'downloading: http://www.google.ch'
>>> UI '3 >> pool-1-thread-5 'downloading: http://www.google.de'
>>> UI '4 >>
>>> As you can see, the hard work is executed on a thread pool but the
>>> results are again on the UI thread. No blocking behind the scenes.
>>>
>>>
>>> == Implementation ==
>>>
>>> // The async method is nothing more than a nice name for
>>> // scala.util.continuations.reset
>>> def async[B](block: => Unit@suspendable): Unit = reset[Unit,Unit]
>>> { block }
>>>
>>> // The await method takes a block which returns a Future[A] and
>>> // pretends to return an A to the caller. Without continuations, this
>>> would be
>>> // only possible by waiting (blocking) on the future until the result
>>> is ready.
>>> def await[A](block: => Future[A])(implicit ec: ExecutionContext =
>>> ThreadPool): A@suspendable = shift { cont: (A => Unit) =>
>>> block onSuccess { case r => ec.execute{ cont(r) } }
>>> }
>>>
>>> // The context method is used to put an ExecutionContext into scope
>>> // which runs the given block. It primarily exists to give nice
>>> // looking examples.
>>> def context[T](ec: ExecutionContext)(block: ExecutionContext => T)
>>> { ec.execute{ block(ec) } }
>>>
>>> // Dummy placeholder to simulate the Swing event dispatching thread
>>> val GUI =
>>> ExecutionContexts.fromExecutor(Executors.newSingleThreadExecutor(
>>> new ThreadFactory{ def newThread(r: Runnable): Thread = new
>>> Thread(r,"UI")}))
>>>
>>> // Thread pool for the heavy background work
>>> val ThreadPool = ExecutionContexts.fromExecutorService(
>>>
>>> Executors.newFixedThreadPool(10))
>>>
>>> // Runnables without the noise
>>> implicit def toRunnable[T](f: => T ): Runnable = new Runnable { def
>>> run() = f }
>>>
>>>
>>> == The Problem ==
>>>
>>> I would like the async block to return a Future of its syntactic
>>> return value:
>>>
>>> val a: Future[Int] = async[Int] {
>>> m("1")
>>> val com = await[String,Int,NotLast] {
>>> dlWebSite("http://www.google.com")
>>> }
>>> m("2 " + com)
>>>
>>> val ch = await[String,Int,NotLast] {
>>> dlWebSite("http://www.google.ch")
>>> }
>>> m("3 " + ch)
>>>
>>> val de = await[String,Int,Last] {
>>> dlWebSite("http://www.google.de")
>>> }
>>> m("4 " + de)
>>>
>>> de.length() // this should be returned as a Future[Int]
>>> }
>>> a onSuccess { case r => m("res" + r) }
>>>
>>>
>>> == Output ==
>>>
>>> UI '1'
>>> pool-1-thread-1 'downloading: http://www.google.com'
>>> UI '2 >> pool-1-thread-3 'downloading: http://www.google.ch'
>>> UI '3 >> pool-1-thread-5 'downloading: http://www.google.de'
>>> UI '4 >> UI 'res20'
>>>
>>> The good part is that it works. The problem is, that now all
>>> those hairy type declarations are required. I could life with
>>> await[String,Int] {...} but my solution requires a further type
>>> parameter to distinguish whether it is the last await in a reset
>>> block or not. The last await turns the Int into a Future[Int]
>>> and all awaits above that last one need to reflect this in their
>>> type. Here is the code:
>>>
>>> // Better name for reset. Takes a block with a syntactic return type
>>> // of B and returns a Future[B]
>>> def async[B](block: => B@cpsParam[B,Future[B]]): Future[B] =
>>> reset[B,Future[B]] { block }
>>>
>>> // The D[_] type parameter is required in @cpsParam.
>>> // Depending on the given type the matching implicit is searched.
>>> def await[A,B,D[_]] (block: => Future[A])
>>> (implicit ec: ExecutionContext = ThreadPool,
>>> f: (=> Future[A]) => ExecutionContext => A@cpsParam[D[B],Future[B]]
>>> ):A@cpsParam[D[B],Future[B]] = f(block)(ec)
>>>
>>>
>>> type Last[X] = X
>>>
>>> // The last await needs a continuation form A => Last[B] which is from
>>> A => B
>>> implicit def last[A,B]: (=> Future[A]) => ExecutionContext =>
>>> A@cpsParam[Last[B],Future[B]] = {
>>> block => ec => shift[A,Last[B],Future[B]] { cont: (A => Last[B]) =>
>>> val p = Promise[B]()(ec)
>>> block onSuccess { case a => ec.execute{ p.success(cont(a)) } }
>>> p
>>> }
>>> }
>>>
>>> type NotLast[X] = Future[X]
>>>
>>> // All other awaits need a continuation from A => NotLast[B]
>>> // which is from A => Future[B]
>>> implicit def notLast[A,B]: (=> Future[A]) => ExecutionContext =>
>>> A@cpsParam[NotLast[B],Future[B]] = {
>>> block => ec => shift[A,NotLast[B],Future[B]] { cont: (A =>
>>> NotLast[B]) =>
>>> val p = Promise[B]()(ec)
>>> block onSuccess { case a =>
>>> ec.execute{ p.completeWith(cont(a)) } }
>>> p
>>> }
>>> }
>>>
>>> This was the best solution I was able to come up with. Of course I
>>> could offer two different await methods which would be a simple
>>> solution if they had different names. But that is not an option. BTW I
>>> am fully aware that the presented code has at most toy quality (
>>> handles only onSuccess, etc.). Anyway, thanks for reading that far. If
>>> you want to learn about scala's continuations I recommend reading this
>>> blog post [4] by Jim McBeath.
>>>
>>> Thanks Daniel
>>>
>>>
>>> [1] http://msdn.microsoft.com/en-us/vstudio/gg316360
>>> [2] http://akka.io/docs/akka/2.0-RC1/scala/futures.html
>>> [3] http://docs.scala-lang.org/sips/pending/futures-promises.html
>>> [4] http://jim-mcbeath.blogspot.com/2010/08/delimited-continuations.html
>>
>
>
>

Viktor Klang
Joined: 2008-12-17,
User offline. Last seen 1 year 27 weeks ago.
Re: C# async implemented in scala (based on delimited continuat

2012/2/16 Tiark Rompf :
> Yes, the differences are minor:
>
>        def flow[A](body: => A @cps[Future[Any]]): Future[A]
>
>        def async[A](body: => A @suspendable): Future[A]
>
> this one avoids the Future[Any] part.

What are the pros/cons?

>
> - Tiark
>
> On Feb 16, 2012, at 12:48 PM, √iktor Ҡlang wrote:
>
>> I think we already got this covered with the dataflow API in Akka:
>>
>> http://akka.io/docs/akka/2.0-RC1/scala/dataflow.html
>>
>> Cheers,
>> √
>>
>> On Thu, Feb 16, 2012 at 12:40 PM, Tiark Rompf wrote:
>>> Sweet! Would this version of async
>>>
>>> def async[A](body: => A @suspendable) = {
>>>        val p = promise[A]
>>>        reset { p success body }
>>>        p
>>> }
>>>
>>> work for the extended case you mention?
>>>
>>> val a: Future[Int] = async[Int] {
>>>        val com = await { dlWebSite("http://www.google.com") }
>>>        com.length
>>> }
>>>
>>> a onSuccess { case r => .... }
>>>
>>>
>>> - Tiark
>>>
>>>
>>> On Feb 16, 2012, at 1:28 AM, Daniel wrote:
>>>
>>>> Hi all
>>>>
>>>> In order to get a better understanding about delimited continuations I
>>>> tried to implement something akin to C# async [1]. Since I think this
>>>> has the potential to be cool, I share it with you. I would appreciate
>>>> any hints and comments.
>>>>
>>>> As a substitute for C#s Tasks I went with akka 2.0 Futures [2] since
>>>> those will eventually be integrated into the main library [3] afaik.
>>>> I have the following:
>>>>
>>>>
>>>> == Example ==
>>>>
>>>> context(GUI) { implicit ec =>
>>>> async {
>>>>   m("1")
>>>>
>>>>   val contentCom = await { dlWebSite("http://www.google.com") }
>>>>   m("2 " + contentCom)
>>>>
>>>>   val contentCh =  await { dlWebSite("http://www.google.ch") }
>>>>   m("3 " + contentCh)
>>>>
>>>>   val contentDe = await { dlWebSite("http://www.google.de") }
>>>>   m("4 " + contentDe)
>>>> }
>>>> }
>>>>
>>>> // Returns a Future which will eventually hold the downloaded html.
>>>> // The download itself is scheduled on a thread pool.
>>>> def dlWebSite(url: String): Future[String] = Future {
>>>>  m("downloading: " + url)
>>>>  Source.fromURL(new URL(url))
>>>> (Codec.ISO8859).getLines.mkString.take(20)
>>>> }(ThreadPool)
>>>>
>>>> // Prints msg prefixed with the name of the current thread
>>>> def m(msg: String) = println(Thread.currentThread().getName() + " '" +
>>>> msg + "'")
>>>>
>>>>
>>>> == Output ==
>>>>
>>>> UI '1'
>>>> pool-1-thread-1 'downloading: http://www.google.com'
>>>> UI '2 >>> pool-1-thread-3 'downloading: http://www.google.ch'
>>>> UI '3 >>> pool-1-thread-5 'downloading: http://www.google.de'
>>>> UI '4 >>>
>>>> As you can see, the hard work is executed on a thread pool but the
>>>> results are again on the UI thread. No blocking behind the scenes.
>>>>
>>>>
>>>> == Implementation ==
>>>>
>>>> // The async method is nothing more than a nice name for
>>>> // scala.util.continuations.reset
>>>> def async[B](block: => Unit@suspendable): Unit = reset[Unit,Unit]
>>>> { block }
>>>>
>>>> // The await method takes a block which returns a Future[A] and
>>>> // pretends to return an A to the caller. Without continuations, this
>>>> would be
>>>> // only possible by waiting (blocking) on the future until the result
>>>> is ready.
>>>> def await[A](block: => Future[A])(implicit ec: ExecutionContext =
>>>> ThreadPool): A@suspendable = shift { cont: (A => Unit) =>
>>>> block onSuccess { case r => ec.execute{ cont(r) } }
>>>> }
>>>>
>>>> // The context method is used to put an ExecutionContext into scope
>>>> // which runs the given block. It primarily exists to give nice
>>>> // looking examples.
>>>> def context[T](ec: ExecutionContext)(block: ExecutionContext => T)
>>>> { ec.execute{ block(ec) } }
>>>>
>>>> // Dummy placeholder to simulate the Swing event dispatching thread
>>>> val GUI =
>>>> ExecutionContexts.fromExecutor(Executors.newSingleThreadExecutor(
>>>>  new ThreadFactory{ def newThread(r: Runnable): Thread = new
>>>> Thread(r,"UI")}))
>>>>
>>>> // Thread pool for the heavy background work
>>>> val ThreadPool = ExecutionContexts.fromExecutorService(
>>>>
>>>> Executors.newFixedThreadPool(10))
>>>>
>>>> // Runnables without the noise
>>>> implicit def toRunnable[T](f: => T ): Runnable = new Runnable { def
>>>> run() = f }
>>>>
>>>>
>>>> == The Problem ==
>>>>
>>>> I would like the async block to return a Future of its syntactic
>>>> return value:
>>>>
>>>> val a: Future[Int] = async[Int] {
>>>> m("1")
>>>> val com = await[String,Int,NotLast] {
>>>>    dlWebSite("http://www.google.com")
>>>> }
>>>> m("2 " + com)
>>>>
>>>> val ch =  await[String,Int,NotLast]  {
>>>>    dlWebSite("http://www.google.ch")
>>>> }
>>>> m("3 " + ch)
>>>>
>>>> val de = await[String,Int,Last] {
>>>>    dlWebSite("http://www.google.de")
>>>> }
>>>> m("4 " + de)
>>>>
>>>> de.length() // this should be returned as a Future[Int]
>>>> }
>>>> a onSuccess { case r => m("res" + r) }
>>>>
>>>>
>>>> == Output ==
>>>>
>>>> UI '1'
>>>> pool-1-thread-1 'downloading: http://www.google.com'
>>>> UI '2 >>> pool-1-thread-3 'downloading: http://www.google.ch'
>>>> UI '3 >>> pool-1-thread-5 'downloading: http://www.google.de'
>>>> UI '4 >>> UI 'res20'
>>>>
>>>> The good part is that it works. The problem is, that now all
>>>> those hairy type declarations are required. I could life with
>>>> await[String,Int] {...} but my solution requires a further type
>>>> parameter to distinguish whether it is the last await in a reset
>>>> block or not. The last await turns the Int into a Future[Int]
>>>> and all awaits above that last one need to reflect this in their
>>>> type. Here is the code:
>>>>
>>>> // Better name for reset. Takes a block with a syntactic return type
>>>> // of B and returns a Future[B]
>>>> def async[B](block: => B@cpsParam[B,Future[B]]): Future[B] =
>>>> reset[B,Future[B]] { block }
>>>>
>>>> // The D[_] type parameter is required in @cpsParam.
>>>> // Depending on the given type the matching implicit is searched.
>>>> def await[A,B,D[_]] (block: => Future[A])
>>>> (implicit ec: ExecutionContext = ThreadPool,
>>>> f: (=> Future[A]) => ExecutionContext => A@cpsParam[D[B],Future[B]]
>>>> ):A@cpsParam[D[B],Future[B]] = f(block)(ec)
>>>>
>>>>
>>>> type Last[X] = X
>>>>
>>>> // The last await needs a continuation form A => Last[B] which is from
>>>> A => B
>>>> implicit def last[A,B]: (=> Future[A]) => ExecutionContext =>
>>>> A@cpsParam[Last[B],Future[B]] = {
>>>> block => ec => shift[A,Last[B],Future[B]] { cont: (A => Last[B]) =>
>>>>   val p = Promise[B]()(ec)
>>>>   block onSuccess { case a =>  ec.execute{ p.success(cont(a)) } }
>>>>   p
>>>> }
>>>> }
>>>>
>>>> type NotLast[X] = Future[X]
>>>>
>>>> // All other awaits need a continuation from A => NotLast[B]
>>>> // which is from A => Future[B]
>>>> implicit def notLast[A,B]: (=> Future[A]) => ExecutionContext =>
>>>> A@cpsParam[NotLast[B],Future[B]] = {
>>>> block => ec => shift[A,NotLast[B],Future[B]] { cont: (A =>
>>>> NotLast[B]) =>
>>>>   val p = Promise[B]()(ec)
>>>>   block onSuccess { case a =>
>>>> ec.execute{ p.completeWith(cont(a))  } }
>>>>   p
>>>> }
>>>> }
>>>>
>>>> This was the best solution I was able to come up with. Of course I
>>>> could offer two different await methods which would be a simple
>>>> solution if they had different names. But that is not an option. BTW I
>>>> am fully aware that the presented code has at most toy quality (
>>>> handles only onSuccess, etc.). Anyway, thanks for reading that far. If
>>>> you want to learn about scala's continuations I recommend reading this
>>>> blog post [4] by Jim McBeath.
>>>>
>>>> Thanks Daniel
>>>>
>>>>
>>>> [1] http://msdn.microsoft.com/en-us/vstudio/gg316360
>>>> [2] http://akka.io/docs/akka/2.0-RC1/scala/futures.html
>>>> [3] http://docs.scala-lang.org/sips/pending/futures-promises.html
>>>> [4] http://jim-mcbeath.blogspot.com/2010/08/delimited-continuations.html
>>>
>>
>>
>>
>> --
>> Viktor Klang
>>
>> Akka Tech Lead
>> Typesafe - The software stack for applications that scale
>>
>> Twitter: @viktorklang
>

daniel.kroeni
Joined: 2008-09-30,
User offline. Last seen 1 year 46 weeks ago.
Re: C# async implemented in scala (based on delimited continuati

Hi Tiark

> Sweet! Would this version of async
>
> def async[A](body: => A @suspendable) = {
>         val p = promise[A]
>         reset { p success body }
>         p
> }
>
> work for the extended case you mention?

Yes it does. I really should have asked earlier =) Many thanks for
this simple solution!

def async[A](body: => A @suspendable): Future[A] = {
val p = Promise[A]()
reset { p success body; () } // The '()' is required for
successful type inference
p
}

def await[A](block: => Future[A])(implicit ec: ExecutionContext):
A@suspendable = shift { cont: (A => Unit) =>
block onSuccess { case r => ec.execute{ cont(r) } }
}

Cheers Daniel

///////////////////////////////// full
example ////////////////////////////

import scala.util.continuations._
import akka.dispatch._
import java.util.concurrent.Executors
import java.net.URL
import java.util.concurrent.ThreadFactory

object TiarkExample extends App {
implicit def toRunnable[T](f: => T): Runnable = new Runnable { def
run() = f }
implicit val GUI =
ExecutionContexts.fromExecutor(Executors.newSingleThreadExecutor(new
ThreadFactory{ def newThread(r: Runnable): Thread = new
Thread(r,"UI")}))
val POOL =
ExecutionContexts.fromExecutor(Executors.newFixedThreadPool(2))

def async[A](body: => A @suspendable): Future[A] = {
val p = Promise[A]()
reset { p success body; () }
p
}

def await[A](block: => Future[A])(implicit ec: ExecutionContext):
A@suspendable = shift { cont: (A => Unit) =>
block onSuccess { case r => ec.execute{ cont(r) } }
}

val a = async {
m("1")
val com = await { downloadWebSiteTask("http://www.google.com")}
m("2")
val ch = await { downloadWebSiteTask("http://www.google.ch")}
m("3")
ch.length + com.length
}

a onSuccess { case r => m("result: " + r)}

def downloadWebSiteTask(url: String): Future[String] = Future {
m("downloading: " + url)
io.Source.fromURL(new URL(url))
(io.Codec.ISO8859).getLines.mkString.take(20)
}(POOL)

def m(msg: String) = println(Thread.currentThread().getName() + " '"
+ msg + "'")
}

daniel.kroeni
Joined: 2008-09-30,
User offline. Last seen 1 year 46 weeks ago.
Re: C# async implemented in scala (based on delimited continuati

Hi Victor

> I think we already got this covered with the dataflow API in Akka:

Right! I just tried it:

  val a = flow {
    m("1")
    val com = downloadWebSiteTask("http://www.google.com")()
    m("2")
    val ch = downloadWebSiteTask("http://www.google.ch")()
    m("3")
    ch.length + com.length
  }
  a onSuccess { case r => m("result: " + r)}

Output:

UI '1'
pool-1-thread-1 'downloading: http://www.google.com'
pool-1-thread-2 '2'   HERE
pool-1-thread-1 'downloading: http://www.google.ch'
pool-1-thread-1 '3'   HERE
pool-1-thread-1 'result: 40'  HERE

What would I have to do if I need the 'callbacks' to be executed on
the implicit ExecutionContext (the one that flow{..}(ctx) captures)?

Daniel

Viktor Klang
Joined: 2008-12-17,
User offline. Last seen 1 year 27 weeks ago.
Re: Re: C# async implemented in scala (based on delimited conti

On Thu, Feb 16, 2012 at 3:34 PM, Daniel wrote:
> Hi Victor
>
>> I think we already got this covered with the dataflow API in Akka:
>
> Right! I just tried it:
>
>   val a = flow {
>     m("1")
>     val com = downloadWebSiteTask("http://www.google.com")()
>     m("2")
>     val ch = downloadWebSiteTask("http://www.google.ch")()
>     m("3")
>     ch.length + com.length
>   }
>   a onSuccess { case r => m("result: " + r)}
>
> Output:
>
> UI '1'
> pool-1-thread-1 'downloading: http://www.google.com'
> pool-1-thread-2 '2'   HERE
> pool-1-thread-1 'downloading: http://www.google.ch'
> pool-1-thread-1 '3'   HERE
> pool-1-thread-1 'result: 40'  HERE
>
> What would I have to do if I need the 'callbacks' to be executed on
> the implicit ExecutionContext (the one that flow{..}(ctx) captures)?

That's a good one! Let me see what we can do about that.

Cheers,

>
> Daniel

daniel.kroeni
Joined: 2008-09-30,
User offline. Last seen 1 year 46 weeks ago.
Re: Re: C# async implemented in scala (based on delimited conti

Hi Victor

This is maybe also worth a discussion:

def namedCtx(n: String) = ExecutionContexts.fromExecutor(
Executors.newSingleThreadExecutor( new ThreadFactory {
def newThread(r: Runnable) = new Thread(r,n)
}))

val A = namedCtx("A")
val B = namedCtx("B")

// create a promise with ctx A
val p = Promise[String]()(A)

// I would expect that any callback from p
// is executed in the context of p
p onSuccess{
case r => println(Thread.currentThread().getName() + " " + r)
}

p.completeWith(Future{"Hi"}(B))

The above prints "B Hi"

What do you think?

Viktor Klang
Joined: 2008-12-17,
User offline. Last seen 1 year 27 weeks ago.
Re: Re: C# async implemented in scala (based on delimited conti

Hi Daniel,

2012/2/16 Daniel Kröni :
> Hi Victor
>
> This is maybe also worth a discussion:
>
> def namedCtx(n: String) = ExecutionContexts.fromExecutor(
>    Executors.newSingleThreadExecutor( new ThreadFactory {
>           def newThread(r: Runnable) = new Thread(r,n)
>    }))
>
> val A = namedCtx("A")
> val B = namedCtx("B")
>
> // create a promise with ctx A
> val p = Promise[String]()(A)
>
> // I would expect that any callback from p
> // is executed in the context of p
> p onSuccess{
>  case r => println(Thread.currentThread().getName() + " " + r)
> }
>
> p.completeWith(Future{"Hi"}(B))
>
> The above prints "B Hi"
>
> What do you think?

final def completeWith(other: Future[T]): this.type = {
    other onComplete { tryComplete(_) }
    this
  }

Cheers,

Derek Williams 3
Joined: 2011-08-12,
User offline. Last seen 42 years 45 weeks ago.
Re: C# async implemented in scala (based on delimited continuat
2012/2/16 √iktor Ҡlang <viktor [dot] klang [at] gmail [dot] com>
2012/2/16 Tiark Rompf <tiark [dot] rompf [at] epfl [dot] ch>:
> Yes, the differences are minor:
>
>        def flow[A](body: => A @cps[Future[Any]]): Future[A]
>
>        def async[A](body: => A @suspendable): Future[A]
>
> this one avoids the Future[Any] part.

What are the pros/cons?


They handle exceptions differently. 'flow' propagates the exception through the futures, and it looks like 'async' ignores it (although some cases could probably be implemented).
I originally did 'flow' with @suspendable, but there was a situation where I just couldn't get the exception to continue through, causing the final future to timeout. I think it had something to do with having the type inferred as a Future[Nothing] (back in the olden days).
--
Derek Williams
daniel.kroeni
Joined: 2008-09-30,
User offline. Last seen 1 year 46 weeks ago.
Re: C# async implemented in scala (based on delimited continuati

Hi Derek, All

> They handle exceptions differently. 'flow' propagates the exception through
> the futures, and it looks like 'async' ignores it (although some cases
> could probably be implemented).

I implement some exception handling [1] and polished the example [2].
Any comments?

Thanks Daniel

[1] https://github.com/danielkroeni/scala-async/blob/master/src/main/scala/a...
[2] https://github.com/danielkroeni/scala-async/blob/master/src/main/scala/a...

kolotyluk
Joined: 2010-06-04,
User offline. Last seen 5 weeks 15 hours ago.
Re: Re: C# async implemented in scala (based on delimited conti
I have been trying to follow this discussion, as it really fascinates me, and while I get the gist of it, I cannot grok it.

I still struggle with continuations in Scala
  1. I have never been able to get them to work in the Eclipse/Scala environment. It would be nice if they could 'just work' - but they don't. Consequently I cannot even play with them.
  2. I have not internalized the concepts the way one would internalize say recursion or closures.
I have an interest in continuations particularly in the context of being able to write UI code that can only run on a single thread, but has to interact with background tasks and asynchronous activities.

I would appreciate it if someone could take the time explain what is going on in this particular discussion as I do find it fascinating.

Cheers, Eric
vpatryshev
Joined: 2009-02-16,
User offline. Last seen 1 year 24 weeks ago.
Re: Re: C# async implemented in scala (based on delimited conti
Hmm, did you develop in JS? Closures everywhere.
Thanks,
-Vlad


On Fri, Feb 17, 2012 at 3:23 PM, Eric Kolotyluk <eric [dot] kolotyluk [at] gmail [dot] com> wrote:
I have been trying to follow this discussion, as it really fascinates me, and while I get the gist of it, I cannot grok it.

I still struggle with continuations in Scala
  1. I have never been able to get them to work in the Eclipse/Scala environment. It would be nice if they could 'just work' - but they don't. Consequently I cannot even play with them.
  2. I have not internalized the concepts the way one would internalize say recursion or closures.
I have an interest in continuations particularly in the context of being able to write UI code that can only run on a single thread, but has to interact with background tasks and asynchronous activities.

I would appreciate it if someone could take the time explain what is going on in this particular discussion as I do find it fascinating.

Cheers, Eric

DaveScala
Joined: 2011-03-18,
User offline. Last seen 1 year 21 weeks ago.
Re: C# async implemented in scala (based on delimited continuati

Have you in Eclipse entered continuations:enable in the P textbox?
You can find it in Preferences > Scala > Compiler on the Standard tab

Maybe you have to clean you project too (if you have a false
NoSuchMethod error bugging you).

That is all there is. (No Xplugin path to continuations.jar necessary
on the Advanced tab, someone suggested that in scala-ide bugreport,
but I don't have it and it works too)

Create a scala project

This code works with scala-ide

Main.scala
==========
import scala.util.continuations._

object Main extends App {

def is123(n:Int):Boolean = {
reset {
shift { k : (Int=>String) =>
(k(n) == "123")
}.toString
}
}

println("the result is " +
reset {
shift { k: (Int=>Int) =>
k(k(k(7)))
} + 1
})

println("123 == 123? result is " + is123(123))
println("567 == 123? result is " + is123(567))
}

Output:
======

the result is 10
123 == 123? result is true
567 == 123? result is false

On 18 feb, 00:23, Eric Kolotyluk wrote:
> I have been trying to follow this discussion, as it really fascinates
> me, and while I get the gist of it, I cannot grok it.
>
> I still struggle with continuations in Scala
>
>  1. I have never been able to get them to work in the Eclipse/Scala
>     environment. It would be nice if they could 'just work' - but they
>     don't. Consequently I cannot even play with them.
>  2. I have not internalized the concepts the way one would internalize
>     say recursion or closures.
>
> I have an interest in continuations particularly in the context of being
> able to write UI code that can only run on a single thread, but has to
> interact with background tasks and asynchronous activities.
>
> I would appreciate it if someone could take the time explain what is
> going on in this particular discussion as I do find it fascinating.
>
> Cheers, Eric

DaveScala
Joined: 2011-03-18,
User offline. Last seen 1 year 21 weeks ago.
Re: C# async implemented in scala (based on delimited continuati

Interesting link about Swarm + Scala Delimited Continuations:

http://code.google.com/p/swarm-dpl/

kolotyluk
Joined: 2010-06-04,
User offline. Last seen 5 weeks 15 hours ago.
Re: Re: C# async implemented in scala (based on delimited conti
What is JS?

Cheers, Eric

On 2012-02-18 12:39 AM, Vlad Patryshev wrote:
iUyp809vgnJn_aA-+d0WBWN1h3mBAEE+cx-LQ [at] mail [dot] gmail [dot] com" type="cite">Hmm, did you develop in JS? Closures everywhere.
Thanks,
-Vlad


On Fri, Feb 17, 2012 at 3:23 PM, Eric Kolotyluk <eric [dot] kolotyluk [at] gmail [dot] com" rel="nofollow">eric [dot] kolotyluk [at] gmail [dot] com> wrote:
I have been trying to follow this discussion, as it really fascinates me, and while I get the gist of it, I cannot grok it.

I still struggle with continuations in Scala
  1. I have never been able to get them to work in the Eclipse/Scala environment. It would be nice if they could 'just work' - but they don't. Consequently I cannot even play with them.
  2. I have not internalized the concepts the way one would internalize say recursion or closures.
I have an interest in continuations particularly in the context of being able to write UI code that can only run on a single thread, but has to interact with background tasks and asynchronous activities.

I would appreciate it if someone could take the time explain what is going on in this particular discussion as I do find it fascinating.

Cheers, Eric

Constantine
Joined: 2011-05-29,
User offline. Last seen 42 years 45 weeks ago.
Re: Re: C# async implemented in scala (based on delimited conti
You might consider using AsyncScala library for the task. Then annonce on LtU was:  http://lambda-the-ultimate.org/node/4289 

It has explicit support for E-style actor-based programming over GUI event loop and much more (like RX-like event streams). There even samples related to it. Out-of-the box AWT event loop is supported. But adding support for SWT, should be very easy.
Thanks,Constantine


On Sat, Feb 18, 2012 at 3:23 AM, Eric Kolotyluk <eric [dot] kolotyluk [at] gmail [dot] com> wrote:
I have been trying to follow this discussion, as it really fascinates me, and while I get the gist of it, I cannot grok it.

I still struggle with continuations in Scala
  1. I have never been able to get them to work in the Eclipse/Scala environment. It would be nice if they could 'just work' - but they don't. Consequently I cannot even play with them.
  2. I have not internalized the concepts the way one would internalize say recursion or closures.
I have an interest in continuations particularly in the context of being able to write UI code that can only run on a single thread, but has to interact with background tasks and asynchronous activities.

I would appreciate it if someone could take the time explain what is going on in this particular discussion as I do find it fascinating.

Cheers, Eric

daniel.kroeni
Joined: 2008-09-30,
User offline. Last seen 1 year 46 weeks ago.
Re: C# async implemented in scala (based on delimited continuati

Hi Eric

I really recommend reading the blog post by Jim McBeath [1]. I will
not be able to give a better explanation. But I will try to explain
how delimited continuations can be used to simplify asynchronous
programming.

Consider the following code fragment:

reset {
  VAL A: A = shift { cont: (A => B) =>
    // do something with cont.
  }
  VAL B: B = ...
  B
}
println("after reset")

The code will be transformed in a way, that everything between shift
and the end of reset (all in UPPERcase) will be passed as the function
'cont' to shift. In other words: The uppercase part becomes the
function cont. Compare how the type of cont (A => B) aligns exactly
with the uppercase part.

After the transformation you have a situation similar to the following
where 'cont' is the upper-case part.

{ cont: (A => B) =>
  // do something with cont.
}
println("after reset")

If you don't call the cont function, the uppercase part will not be
executed at all and control flow goes on with the part which was
originally after the reset block. If you call the cont function, it
will execute the uppercase part.

Let's see how we can use this for asynchronous programming:

reset {
  val s: String = reset {  cont: (String => Unit) =>
     new Thread() {
       def run {
          val news = downloadNews("www.cnn.com")
          cont(news) // call the cont with the result
       }
     }.start
  }
  println("news: " + s)
}
println("after reset")

In the above fragment, the call to reset returns after the new
background thread has been created and started. It will immediately
print "after reset". In the meantime the background thread loaded the
news from a webservice. Now it will call 'cont' with the downloaded
news. The val s will get assigned to the news argument passed to cont
and "news: ..." will be printed.

Instead of calling cont(news) in the background thread, one can use
for example SwingHelper to execute the 'cont' on the Swing EDT.

reset {
  val s: String = reset {  cont: (String => Unit) =>
     new Thread() {
       def run {
          val news = downloadNews("www.cnn.com")
          SwingUtilities.invokeLater(new Runnable { def run
{ cont(news)} })
       }
     }.start
  }
  println("news: " + s)
}

In the above code, the continuation 'cont' will be called on the Swing
thread. This means that println("news: " + s) will be executed on the
swing thread. You could directly assign the s to a Swing Textbox or
similar.

Not sure if this helps.

Cheers
Daniel

[1] http://jim-mcbeath.blogspot.com/2010/08/delimited-continuations.html

On Feb 18, 12:23 am, Eric Kolotyluk wrote:
> I have been trying to follow this discussion, as it really fascinates
> me, and while I get the gist of it, I cannot grok it.
>
> I still struggle with continuations in Scala
>
>  1. I have never been able to get them to work in the Eclipse/Scala
>     environment. It would be nice if they could 'just work' - but they
>     don't. Consequently I cannot even play with them.
>  2. I have not internalized the concepts the way one would internalize
>     say recursion or closures.
>
> I have an interest in continuations particularly in the context of being
> able to write UI code that can only run on a single thread, but has to
> interact with background tasks and asynchronous activities.
>
> I would appreciate it if someone could take the time explain what is
> going on in this particular discussion as I do find it fascinating.
>
> Cheers, Eric

kolotyluk
Joined: 2010-06-04,
User offline. Last seen 5 weeks 15 hours ago.
Re: Re: C# async implemented in scala (based on delimited conti

The Eclipse IDE shows

bad option: -P:continuations:enable

On 2012-02-18 7:04 AM, Dave wrote:
> Have you in Eclipse entered continuations:enable in the P textbox?
> You can find it in Preferences> Scala> Compiler on the Standard tab
>
> Maybe you have to clean you project too (if you have a false
> NoSuchMethod error bugging you).
>
> That is all there is. (No Xplugin path to continuations.jar necessary
> on the Advanced tab, someone suggested that in scala-ide bugreport,
> but I don't have it and it works too)
>
> Create a scala project
>
> This code works with scala-ide
>
> Main.scala
> ==========
> import scala.util.continuations._
>
> object Main extends App {
>
> def is123(n:Int):Boolean = {
> reset {
> shift { k : (Int=>String) =>
> (k(n) == "123")
> }.toString
> }
> }
>
> println("the result is " +
> reset {
> shift { k: (Int=>Int) =>
> k(k(k(7)))
> } + 1
> })
>
> println("123 == 123? result is " + is123(123))
> println("567 == 123? result is " + is123(567))
> }
>
>
> Output:
> ======
>
> the result is 10
> 123 == 123? result is true
> 567 == 123? result is false
>
>
>
>
>
> On 18 feb, 00:23, Eric Kolotyluk wrote:
>> I have been trying to follow this discussion, as it really fascinates
>> me, and while I get the gist of it, I cannot grok it.
>>
>> I still struggle with continuations in Scala
>>
>> 1. I have never been able to get them to work in the Eclipse/Scala
>> environment. It would be nice if they could 'just work' - but they
>> don't. Consequently I cannot even play with them.
>> 2. I have not internalized the concepts the way one would internalize
>> say recursion or closures.
>>
>> I have an interest in continuations particularly in the context of being
>> able to write UI code that can only run on a single thread, but has to
>> interact with background tasks and asynchronous activities.
>>
>> I would appreciate it if someone could take the time explain what is
>> going on in this particular discussion as I do find it fascinating.
>>
>> Cheers, Eric

DaveScala
Joined: 2011-03-18,
User offline. Last seen 1 year 21 weeks ago.
Re: C# async implemented in scala (based on delimited continuati

> That is all there is. (No Xplugin path to continuations.jar necessary
> on the Advanced tab, someone suggested that in scala-ide bugreport,
> but I don't have it and it works too)

After retesting today it seems that the reference to continuations.jar
is necessary
So on Advanced tab Textbox Xplugin enter the path to continuations.jar
e.g.
C:\scala-2.9.1.final\misc\scala-devel\plugins\continuations.jar

DaveScala
Joined: 2011-03-18,
User offline. Last seen 1 year 21 weeks ago.
Re: C# async implemented in scala (based on delimited continuati

Hi Daniel, the second reset should be a shift and run should have an
override keyword>

I add it to the previous example:

import scala.util.continuations._

object Main extends App {

def is123(n:Int):Boolean = {
reset {
shift { k : (Int=>String) =>
(k(n) == "123")
}.toString
}
}

def downloadNews(s: String) = { Thread.sleep(5000); "cnn news
headlines" }

reset {
val s: String = shift { cont: (String => Unit) =>
new Thread() {
override def run {
val news = downloadNews("www.cnn.com")
cont(news)
}
}.start
}
println("news: " + s)
}
println("after reset")

println("the result is " +
reset {
shift { k: (Int=>Int) =>
k(k(k(7)))
} + 1
})

println("123 == 123? result is " + is123(123))
println("567 == 123? result is " + is123(567))
}

Output:
after reset
the result is 10
123 == 123? result is true
567 == 123? result is false
news: cnn news headlines

and the last line shows up after 5 seconds

On 19 feb, 16:17, Daniel wrote:
> Hi Eric
>
> I really recommend reading the blog post by Jim McBeath [1]. I will
> not be able to give a better explanation. But I will try to explain
> how delimited continuations can be used to simplify asynchronous
> programming.
>
> Consider the following code fragment:
>
> reset {
>   VAL A: A = shift { cont: (A => B) =>
>     // do something with cont.
>   }
>   VAL B: B = ...
>   B}
>
> println("after reset")
>
> The code will be transformed in a way, that everything between shift
> and the end of reset (all in UPPERcase) will be passed as the function
> 'cont' to shift. In other words: The uppercase part becomes the
> function cont. Compare how the type of cont (A => B) aligns exactly
> with the uppercase part.
>
> After the transformation you have a situation similar to the following
> where 'cont' is the upper-case part.
>
> { cont: (A => B) =>
>   // do something with cont.}
>
> println("after reset")
>
> If you don't call the cont function, the uppercase part will not be
> executed at all and control flow goes on with the part which was
> originally after the reset block. If you call the cont function, it
> will execute the uppercase part.
>
> Let's see how we can use this for asynchronous programming:
>
> reset {
>   val s: String = reset {  cont: (String => Unit) =>
>      new Thread() {
>        def run {
>           val news = downloadNews("www.cnn.com")
>           cont(news) // call the cont with the result
>        }
>      }.start
>   }
>   println("news: " + s)}
>
> println("after reset")
>
> In the above fragment, the call to reset returns after the new
> background thread has been created and started. It will immediately
> print "after reset". In the meantime the background thread loaded the
> news from a webservice. Now it will call 'cont' with the downloaded
> news. The val s will get assigned to the news argument passed to cont
> and "news: ..." will be printed.
>
> Instead of calling cont(news) in the background thread, one can use
> for example SwingHelper to execute the 'cont' on the Swing EDT.
>
> reset {
>   val s: String = reset {  cont: (String => Unit) =>
>      new Thread() {
>        def run {
>           val news = downloadNews("www.cnn.com")
>           SwingUtilities.invokeLater(new Runnable { def run
> { cont(news)} })
>        }
>      }.start
>   }
>   println("news: " + s)
>
> }
>
> In the above code, the continuation 'cont' will be called on the Swing
> thread. This means that println("news: " + s) will be executed on the
> swing thread. You could directly assign the s to a Swing Textbox or
> similar.
>
> Not sure if this helps.
>
> Cheers
> Daniel
>
> [1]http://jim-mcbeath.blogspot.com/2010/08/delimited-continuations.html
>
> On Feb 18, 12:23 am, Eric Kolotyluk wrote:
>
>
>
> > I have been trying to follow this discussion, as it really fascinates
> > me, and while I get the gist of it, I cannot grok it.
>
> > I still struggle with continuations in Scala
>
> >  1. I have never been able to get them to work in the Eclipse/Scala
> >     environment. It would be nice if they could 'just work' - but they
> >     don't. Consequently I cannot even play with them.
> >  2. I have not internalized the concepts the way one would internalize
> >     say recursion or closures.
>
> > I have an interest in continuations particularly in the context of being
> > able to write UI code that can only run on a single thread, but has to
> > interact with background tasks and asynchronous activities.
>
> > I would appreciate it if someone could take the time explain what is
> > going on in this particular discussion as I do find it fascinating.
>
> > Cheers, Eric- Tekst uit oorspronkelijk bericht niet weergeven -
>
> - Tekst uit oorspronkelijk bericht weergeven -

DaveScala
Joined: 2011-03-18,
User offline. Last seen 1 year 21 weeks ago.
Re: C# async implemented in scala (based on delimited continuati

You shouldn't use -P:
only

continuations:enable

On 19 feb, 17:03, Eric Kolotyluk wrote:
> The Eclipse IDE shows
>
> bad option: -P:continuations:enable
>
> On 2012-02-18 7:04 AM, Dave wrote:
>
>
>
> > Have you in Eclipse entered continuations:enable in the P textbox?
> > You can find it in Preferences>  Scala>  Compiler on the Standard tab
>
> > Maybe you have to clean you project too (if you have a false
> > NoSuchMethod error bugging you).
>
> > That is all there is. (No Xplugin path to continuations.jar necessary
> > on the Advanced tab, someone suggested that in scala-ide bugreport,
> > but I don't have it and it works too)
>
> > Create a scala project
>
> > This code works with scala-ide
>
> > Main.scala
> > ==========
> > import scala.util.continuations._
>
> > object Main extends App {
>
> >    def is123(n:Int):Boolean = {
> >      reset {
> >        shift { k : (Int=>String) =>
> >          (k(n) == "123")
> >        }.toString
> >      }
> >    }
>
> >    println("the result is " +
> >    reset {
> >      shift { k: (Int=>Int) =>
> >        k(k(k(7)))
> >      } + 1
> >    })
>
> >    println("123 == 123? result is " + is123(123))
> >    println("567 == 123? result is " + is123(567))
> > }
>
> > Output:
> > ======
>
> > the result is 10
> > 123 == 123? result is true
> > 567 == 123? result is false
>
> > On 18 feb, 00:23, Eric Kolotyluk  wrote:
> >> I have been trying to follow this discussion, as it really fascinates
> >> me, and while I get the gist of it, I cannot grok it.
>
> >> I still struggle with continuations in Scala
>
> >>   1. I have never been able to get them to work in the Eclipse/Scala
> >>      environment. It would be nice if they could 'just work' - but they
> >>      don't. Consequently I cannot even play with them.
> >>   2. I have not internalized the concepts the way one would internalize
> >>      say recursion or closures.
>
> >> I have an interest in continuations particularly in the context of being
> >> able to write UI code that can only run on a single thread, but has to
> >> interact with background tasks and asynchronous activities.
>
> >> I would appreciate it if someone could take the time explain what is
> >> going on in this particular discussion as I do find it fascinating.
>
> >> Cheers, Eric- Tekst uit oorspronkelijk bericht niet weergeven -
>
> - Tekst uit oorspronkelijk bericht weergeven -

DaveScala
Joined: 2011-03-18,
User offline. Last seen 1 year 21 weeks ago.
Re: C# async implemented in scala (based on delimited continuati

Maybe you have Use Project Properties enabled

Then you can fill them in on project level in Project > Properties >
Scala Compiler

and clean project before running

On 19 feb, 17:03, Eric Kolotyluk wrote:
> The Eclipse IDE shows
>
> bad option: -P:continuations:enable
>
> On 2012-02-18 7:04 AM, Dave wrote:
>
>
>
> > Have you in Eclipse entered continuations:enable in the P textbox?
> > You can find it in Preferences>  Scala>  Compiler on the Standard tab
>
> > Maybe you have to clean you project too (if you have a false
> > NoSuchMethod error bugging you).
>
> > That is all there is. (No Xplugin path to continuations.jar necessary
> > on the Advanced tab, someone suggested that in scala-ide bugreport,
> > but I don't have it and it works too)
>
> > Create a scala project
>
> > This code works with scala-ide
>
> > Main.scala
> > ==========
> > import scala.util.continuations._
>
> > object Main extends App {
>
> >    def is123(n:Int):Boolean = {
> >      reset {
> >        shift { k : (Int=>String) =>
> >          (k(n) == "123")
> >        }.toString
> >      }
> >    }
>
> >    println("the result is " +
> >    reset {
> >      shift { k: (Int=>Int) =>
> >        k(k(k(7)))
> >      } + 1
> >    })
>
> >    println("123 == 123? result is " + is123(123))
> >    println("567 == 123? result is " + is123(567))
> > }
>
> > Output:
> > ======
>
> > the result is 10
> > 123 == 123? result is true
> > 567 == 123? result is false
>
> > On 18 feb, 00:23, Eric Kolotyluk  wrote:
> >> I have been trying to follow this discussion, as it really fascinates
> >> me, and while I get the gist of it, I cannot grok it.
>
> >> I still struggle with continuations in Scala
>
> >>   1. I have never been able to get them to work in the Eclipse/Scala
> >>      environment. It would be nice if they could 'just work' - but they
> >>      don't. Consequently I cannot even play with them.
> >>   2. I have not internalized the concepts the way one would internalize
> >>      say recursion or closures.
>
> >> I have an interest in continuations particularly in the context of being
> >> able to write UI code that can only run on a single thread, but has to
> >> interact with background tasks and asynchronous activities.
>
> >> I would appreciate it if someone could take the time explain what is
> >> going on in this particular discussion as I do find it fascinating.
>
> >> Cheers, Eric- Tekst uit oorspronkelijk bericht niet weergeven -
>
> - Tekst uit oorspronkelijk bericht weergeven -

kolotyluk
Joined: 2010-06-04,
User offline. Last seen 5 weeks 15 hours ago.
Re: Re: C# async implemented in scala (based on delimited conti

I did not have "Use Project Settings" enabled previously.

I tried enabling "Use Project Settings" and setting
"continuations:enable" in the P field, but that just produces "bad
option: -P:continuations:enable" as well.

This has been my ongoing problem with continuations in Scala - it is
simply too difficult to configure it to work in Eclipse - consequently I
cannot even experiment with the feature.

Should I create a JIRA issue on this?

Cheers, Eric

On 2012-02-20 4:26 AM, Dave wrote:
> Maybe you have Use Project Properties enabled
>
> Then you can fill them in on project level in Project> Properties>
> Scala Compiler
>
> and clean project before running
>
> On 19 feb, 17:03, Eric Kolotyluk wrote:
>> The Eclipse IDE shows
>>
>> bad option: -P:continuations:enable
>>
>> On 2012-02-18 7:04 AM, Dave wrote:
>>
>>
>>
>>> Have you in Eclipse entered continuations:enable in the P textbox?
>>> You can find it in Preferences> Scala> Compiler on the Standard tab
>>> Maybe you have to clean you project too (if you have a false
>>> NoSuchMethod error bugging you).
>>> That is all there is. (No Xplugin path to continuations.jar necessary
>>> on the Advanced tab, someone suggested that in scala-ide bugreport,
>>> but I don't have it and it works too)
>>> Create a scala project
>>> This code works with scala-ide
>>> Main.scala
>>> ==========
>>> import scala.util.continuations._
>>> object Main extends App {
>>> def is123(n:Int):Boolean = {
>>> reset {
>>> shift { k : (Int=>String) =>
>>> (k(n) == "123")
>>> }.toString
>>> }
>>> }
>>> println("the result is " +
>>> reset {
>>> shift { k: (Int=>Int) =>
>>> k(k(k(7)))
>>> } + 1
>>> })
>>> println("123 == 123? result is " + is123(123))
>>> println("567 == 123? result is " + is123(567))
>>> }
>>> Output:
>>> ======
>>> the result is 10
>>> 123 == 123? result is true
>>> 567 == 123? result is false
>>> On 18 feb, 00:23, Eric Kolotyluk wrote:
>>>> I have been trying to follow this discussion, as it really fascinates
>>>> me, and while I get the gist of it, I cannot grok it.
>>>> I still struggle with continuations in Scala
>>>> 1. I have never been able to get them to work in the Eclipse/Scala
>>>> environment. It would be nice if they could 'just work' - but they
>>>> don't. Consequently I cannot even play with them.
>>>> 2. I have not internalized the concepts the way one would internalize
>>>> say recursion or closures.
>>>> I have an interest in continuations particularly in the context of being
>>>> able to write UI code that can only run on a single thread, but has to
>>>> interact with background tasks and asynchronous activities.
>>>> I would appreciate it if someone could take the time explain what is
>>>> going on in this particular discussion as I do find it fascinating.
>>>> Cheers, Eric- Tekst uit oorspronkelijk bericht niet weergeven -
>> - Tekst uit oorspronkelijk bericht weergeven -

dcsobral
Joined: 2009-04-23,
User offline. Last seen 38 weeks 5 days ago.
Re: Re: C# async implemented in scala (based on delimited conti

On Mon, Feb 20, 2012 at 13:29, Eric Kolotyluk wrote:
> I did not have "Use Project Settings" enabled previously.
>
> I tried enabling "Use Project Settings" and setting "continuations:enable"
> in the P field, but that just produces "bad option: -P:continuations:enable"
> as well.

It sounds like you are using Scala 2.8.x... are you?

>
> This has been my ongoing problem with continuations in Scala - it is simply
> too difficult to configure it to work in Eclipse - consequently I cannot
> even experiment with the feature.
>
> Should I create a JIRA issue on this?
>
> Cheers, Eric
>
>
> On 2012-02-20 4:26 AM, Dave wrote:
>>
>> Maybe you have Use Project Properties enabled
>>
>> Then you can fill them in on project level in Project>  Properties>
>> Scala Compiler
>>
>> and clean project before running
>>
>> On 19 feb, 17:03, Eric Kolotyluk  wrote:
>>>
>>> The Eclipse IDE shows
>>>
>>> bad option: -P:continuations:enable
>>>
>>> On 2012-02-18 7:04 AM, Dave wrote:
>>>
>>>
>>>
>>>> Have you in Eclipse entered continuations:enable in the P textbox?
>>>> You can find it in Preferences>    Scala>    Compiler on the Standard
>>>> tab
>>>> Maybe you have to clean you project too (if you have a false
>>>> NoSuchMethod error bugging you).
>>>> That is all there is. (No Xplugin path to continuations.jar necessary
>>>> on the Advanced tab, someone suggested that in scala-ide bugreport,
>>>> but I don't have it and it works too)
>>>> Create a scala project
>>>> This code works with scala-ide
>>>> Main.scala
>>>> ==========
>>>> import scala.util.continuations._
>>>> object Main extends App {
>>>>    def is123(n:Int):Boolean = {
>>>>      reset {
>>>>        shift { k : (Int=>String) =>
>>>>          (k(n) == "123")
>>>>        }.toString
>>>>      }
>>>>    }
>>>>    println("the result is " +
>>>>    reset {
>>>>      shift { k: (Int=>Int) =>
>>>>        k(k(k(7)))
>>>>      } + 1
>>>>    })
>>>>    println("123 == 123? result is " + is123(123))
>>>>    println("567 == 123? result is " + is123(567))
>>>> }
>>>> Output:
>>>> ======
>>>> the result is 10
>>>> 123 == 123? result is true
>>>> 567 == 123? result is false
>>>> On 18 feb, 00:23, Eric Kolotyluk    wrote:
>>>>>
>>>>> I have been trying to follow this discussion, as it really fascinates
>>>>> me, and while I get the gist of it, I cannot grok it.
>>>>> I still struggle with continuations in Scala
>>>>>   1. I have never been able to get them to work in the Eclipse/Scala
>>>>>      environment. It would be nice if they could 'just work' - but they
>>>>>      don't. Consequently I cannot even play with them.
>>>>>   2. I have not internalized the concepts the way one would internalize
>>>>>      say recursion or closures.
>>>>> I have an interest in continuations particularly in the context of
>>>>> being
>>>>> able to write UI code that can only run on a single thread, but has to
>>>>> interact with background tasks and asynchronous activities.
>>>>> I would appreciate it if someone could take the time explain what is
>>>>> going on in this particular discussion as I do find it fascinating.
>>>>> Cheers, Eric- Tekst uit oorspronkelijk bericht niet weergeven -
>>>
>>> - Tekst uit oorspronkelijk bericht weergeven -

kolotyluk
Joined: 2010-06-04,
User offline. Last seen 5 weeks 15 hours ago.
Re: Re: C# async implemented in scala (based on delimited conti

As far as I can tell I am using Scala 2.9.0.1 - at least that is all I
have installed - unless Scala on Eclipse is using some embedded Scala.

Cheers, Eric

On 2012-02-20 8:12 AM, Daniel Sobral wrote:
> On Mon, Feb 20, 2012 at 13:29, Eric Kolotyluk wrote:
>> I did not have "Use Project Settings" enabled previously.
>>
>> I tried enabling "Use Project Settings" and setting "continuations:enable"
>> in the P field, but that just produces "bad option: -P:continuations:enable"
>> as well.
> It sounds like you are using Scala 2.8.x... are you?
>
>> This has been my ongoing problem with continuations in Scala - it is simply
>> too difficult to configure it to work in Eclipse - consequently I cannot
>> even experiment with the feature.
>>
>> Should I create a JIRA issue on this?
>>
>> Cheers, Eric
>>
>>
>> On 2012-02-20 4:26 AM, Dave wrote:
>>> Maybe you have Use Project Properties enabled
>>>
>>> Then you can fill them in on project level in Project> Properties>
>>> Scala Compiler
>>>
>>> and clean project before running
>>>
>>> On 19 feb, 17:03, Eric Kolotyluk wrote:
>>>> The Eclipse IDE shows
>>>>
>>>> bad option: -P:continuations:enable
>>>>
>>>> On 2012-02-18 7:04 AM, Dave wrote:
>>>>
>>>>
>>>>
>>>>> Have you in Eclipse entered continuations:enable in the P textbox?
>>>>> You can find it in Preferences> Scala> Compiler on the Standard
>>>>> tab
>>>>> Maybe you have to clean you project too (if you have a false
>>>>> NoSuchMethod error bugging you).
>>>>> That is all there is. (No Xplugin path to continuations.jar necessary
>>>>> on the Advanced tab, someone suggested that in scala-ide bugreport,
>>>>> but I don't have it and it works too)
>>>>> Create a scala project
>>>>> This code works with scala-ide
>>>>> Main.scala
>>>>> ==========
>>>>> import scala.util.continuations._
>>>>> object Main extends App {
>>>>> def is123(n:Int):Boolean = {
>>>>> reset {
>>>>> shift { k : (Int=>String) =>
>>>>> (k(n) == "123")
>>>>> }.toString
>>>>> }
>>>>> }
>>>>> println("the result is " +
>>>>> reset {
>>>>> shift { k: (Int=>Int) =>
>>>>> k(k(k(7)))
>>>>> } + 1
>>>>> })
>>>>> println("123 == 123? result is " + is123(123))
>>>>> println("567 == 123? result is " + is123(567))
>>>>> }
>>>>> Output:
>>>>> ======
>>>>> the result is 10
>>>>> 123 == 123? result is true
>>>>> 567 == 123? result is false
>>>>> On 18 feb, 00:23, Eric Kolotyluk wrote:
>>>>>> I have been trying to follow this discussion, as it really fascinates
>>>>>> me, and while I get the gist of it, I cannot grok it.
>>>>>> I still struggle with continuations in Scala
>>>>>> 1. I have never been able to get them to work in the Eclipse/Scala
>>>>>> environment. It would be nice if they could 'just work' - but they
>>>>>> don't. Consequently I cannot even play with them.
>>>>>> 2. I have not internalized the concepts the way one would internalize
>>>>>> say recursion or closures.
>>>>>> I have an interest in continuations particularly in the context of
>>>>>> being
>>>>>> able to write UI code that can only run on a single thread, but has to
>>>>>> interact with background tasks and asynchronous activities.
>>>>>> I would appreciate it if someone could take the time explain what is
>>>>>> going on in this particular discussion as I do find it fascinating.
>>>>>> Cheers, Eric- Tekst uit oorspronkelijk bericht niet weergeven -
>>>> - Tekst uit oorspronkelijk bericht weergeven -
>
>

DaveScala
Joined: 2011-03-18,
User offline. Last seen 1 year 21 weeks ago.
Re: C# async implemented in scala (based on delimited continuati

And you have set textbox Xplugin on the Advanced tab the path to
continuations.jar
e.g.
C:\scala-2.9.1.final\misc\scala-devel\plugins\continuations.jar

Probably for you it is
C:\scala-2.9.0.1\misc\scala-devel\plugins\continuations.jar
otherwise you can search

You can see what version of Scala your project is using see Scala
Library and then between the square brackets is the version

On 20 feb, 17:47, Eric Kolotyluk wrote:
> As far as I can tell I am using Scala 2.9.0.1 - at least that is all I
> have installed - unless Scala on Eclipse is using some embedded Scala.
>
> Cheers, Eric
>
> On 2012-02-20 8:12 AM, Daniel Sobral wrote:
>
>
>
> > On Mon, Feb 20, 2012 at 13:29, Eric Kolotyluk  wrote:
> >> I did not have "Use Project Settings" enabled previously.
>
> >> I tried enabling "Use Project Settings" and setting "continuations:enable"
> >> in the P field, but that just produces "bad option: -P:continuations:enable"
> >> as well.
> > It sounds like you are using Scala 2.8.x... are you?
>
> >> This has been my ongoing problem with continuations in Scala - it is simply
> >> too difficult to configure it to work in Eclipse - consequently I cannot
> >> even experiment with the feature.
>
> >> Should I create a JIRA issue on this?
>
> >> Cheers, Eric
>
> >> On 2012-02-20 4:26 AM, Dave wrote:
> >>> Maybe you have Use Project Properties enabled
>
> >>> Then you can fill them in on project level in Project>    Properties>
> >>> Scala Compiler
>
> >>> and clean project before running
>
> >>> On 19 feb, 17:03, Eric Kolotyluk    wrote:
> >>>> The Eclipse IDE shows
>
> >>>> bad option: -P:continuations:enable
>
> >>>> On 2012-02-18 7:04 AM, Dave wrote:
>
> >>>>> Have you in Eclipse entered continuations:enable in the P textbox?
> >>>>> You can find it in Preferences>      Scala>      Compiler on the Standard
> >>>>> tab
> >>>>> Maybe you have to clean you project too (if you have a false
> >>>>> NoSuchMethod error bugging you).
> >>>>> That is all there is. (No Xplugin path to continuations.jar necessary
> >>>>> on the Advanced tab, someone suggested that in scala-ide bugreport,
> >>>>> but I don't have it and it works too)
> >>>>> Create a scala project
> >>>>> This code works with scala-ide
> >>>>> Main.scala
> >>>>> ==========
> >>>>> import scala.util.continuations._
> >>>>> object Main extends App {
> >>>>>     def is123(n:Int):Boolean = {
> >>>>>       reset {
> >>>>>         shift { k : (Int=>String) =>
> >>>>>           (k(n) == "123")
> >>>>>         }.toString
> >>>>>       }
> >>>>>     }
> >>>>>     println("the result is " +
> >>>>>     reset {
> >>>>>       shift { k: (Int=>Int) =>
> >>>>>         k(k(k(7)))
> >>>>>       } + 1
> >>>>>     })
> >>>>>     println("123 == 123? result is " + is123(123))
> >>>>>     println("567 == 123? result is " + is123(567))
> >>>>> }
> >>>>> Output:
> >>>>> ======
> >>>>> the result is 10
> >>>>> 123 == 123? result is true
> >>>>> 567 == 123? result is false
> >>>>> On 18 feb, 00:23, Eric Kolotyluk      wrote:
> >>>>>> I have been trying to follow this discussion, as it really fascinates
> >>>>>> me, and while I get the gist of it, I cannot grok it.
> >>>>>> I still struggle with continuations in Scala
> >>>>>>    1. I have never been able to get them to work in the Eclipse/Scala
> >>>>>>       environment. It would be nice if they could 'just work' - but they
> >>>>>>       don't. Consequently I cannot even play with them.
> >>>>>>    2. I have not internalized the concepts the way one would internalize
> >>>>>>       say recursion or closures.
> >>>>>> I have an interest in continuations particularly in the context of
> >>>>>> being
> >>>>>> able to write UI code that can only run on a single thread, but has to
> >>>>>> interact with background tasks and asynchronous activities.
> >>>>>> I would appreciate it if someone could take the time explain what is
> >>>>>> going on in this particular discussion as I do find it fascinating.
> >>>>>> Cheers, Eric- Tekst uit oorspronkelijk bericht niet weergeven -
> >>>> - Tekst uit oorspronkelijk bericht weergeven -- Tekst uit oorspronkelijk bericht niet weergeven -
>
> - Tekst uit oorspronkelijk bericht weergeven -

kolotyluk
Joined: 2010-06-04,
User offline. Last seen 5 weeks 15 hours ago.
Re: Re: C# async implemented in scala (based on delimited conti

Wha-Hoo - got it to compile and run. Thanks so much :-)

Kinda sucks that the path in the Xplugin cannot have any spaces in the
name. I had to move the plug-in somewhere else. My Scala is installed in

C:\Program Files (Open)\Scala\scala-2.9.0.1

I guess continuations are still consider experimental which is why there
is so much fuss around setting them up in Eclipse.

Cheers, Eric

On 2012-02-20 10:23 AM, Dave wrote:
> And you have set textbox Xplugin on the Advanced tab the path to
> continuations.jar
> e.g.
> C:\scala-2.9.1.final\misc\scala-devel\plugins\continuations.jar
>
>
> Probably for you it is
> C:\scala-2.9.0.1\misc\scala-devel\plugins\continuations.jar
> otherwise you can search
>
> You can see what version of Scala your project is using see Scala
> Library and then between the square brackets is the version
>
> On 20 feb, 17:47, Eric Kolotyluk wrote:
>> As far as I can tell I am using Scala 2.9.0.1 - at least that is all I
>> have installed - unless Scala on Eclipse is using some embedded Scala.
>>
>> Cheers, Eric
>>
>> On 2012-02-20 8:12 AM, Daniel Sobral wrote:
>>
>>
>>
>>> On Mon, Feb 20, 2012 at 13:29, Eric Kolotyluk wrote:
>>>> I did not have "Use Project Settings" enabled previously.
>>>> I tried enabling "Use Project Settings" and setting "continuations:enable"
>>>> in the P field, but that just produces "bad option: -P:continuations:enable"
>>>> as well.
>>> It sounds like you are using Scala 2.8.x... are you?
>>>> This has been my ongoing problem with continuations in Scala - it is simply
>>>> too difficult to configure it to work in Eclipse - consequently I cannot
>>>> even experiment with the feature.
>>>> Should I create a JIRA issue on this?
>>>> Cheers, Eric
>>>> On 2012-02-20 4:26 AM, Dave wrote:
>>>>> Maybe you have Use Project Properties enabled
>>>>> Then you can fill them in on project level in Project> Properties>
>>>>> Scala Compiler
>>>>> and clean project before running
>>>>> On 19 feb, 17:03, Eric Kolotyluk wrote:
>>>>>> The Eclipse IDE shows
>>>>>> bad option: -P:continuations:enable
>>>>>> On 2012-02-18 7:04 AM, Dave wrote:
>>>>>>> Have you in Eclipse entered continuations:enable in the P textbox?
>>>>>>> You can find it in Preferences> Scala> Compiler on the Standard
>>>>>>> tab
>>>>>>> Maybe you have to clean you project too (if you have a false
>>>>>>> NoSuchMethod error bugging you).
>>>>>>> That is all there is. (No Xplugin path to continuations.jar necessary
>>>>>>> on the Advanced tab, someone suggested that in scala-ide bugreport,
>>>>>>> but I don't have it and it works too)
>>>>>>> Create a scala project
>>>>>>> This code works with scala-ide
>>>>>>> Main.scala
>>>>>>> ==========
>>>>>>> import scala.util.continuations._
>>>>>>> object Main extends App {
>>>>>>> def is123(n:Int):Boolean = {
>>>>>>> reset {
>>>>>>> shift { k : (Int=>String) =>
>>>>>>> (k(n) == "123")
>>>>>>> }.toString
>>>>>>> }
>>>>>>> }
>>>>>>> println("the result is " +
>>>>>>> reset {
>>>>>>> shift { k: (Int=>Int) =>
>>>>>>> k(k(k(7)))
>>>>>>> } + 1
>>>>>>> })
>>>>>>> println("123 == 123? result is " + is123(123))
>>>>>>> println("567 == 123? result is " + is123(567))
>>>>>>> }
>>>>>>> Output:
>>>>>>> ======
>>>>>>> the result is 10
>>>>>>> 123 == 123? result is true
>>>>>>> 567 == 123? result is false
>>>>>>> On 18 feb, 00:23, Eric Kolotyluk wrote:
>>>>>>>> I have been trying to follow this discussion, as it really fascinates
>>>>>>>> me, and while I get the gist of it, I cannot grok it.
>>>>>>>> I still struggle with continuations in Scala
>>>>>>>> 1. I have never been able to get them to work in the Eclipse/Scala
>>>>>>>> environment. It would be nice if they could 'just work' - but they
>>>>>>>> don't. Consequently I cannot even play with them.
>>>>>>>> 2. I have not internalized the concepts the way one would internalize
>>>>>>>> say recursion or closures.
>>>>>>>> I have an interest in continuations particularly in the context of
>>>>>>>> being
>>>>>>>> able to write UI code that can only run on a single thread, but has to
>>>>>>>> interact with background tasks and asynchronous activities.
>>>>>>>> I would appreciate it if someone could take the time explain what is
>>>>>>>> going on in this particular discussion as I do find it fascinating.
>>>>>>>> Cheers, Eric- Tekst uit oorspronkelijk bericht niet weergeven -
>>>>>> - Tekst uit oorspronkelijk bericht weergeven -- Tekst uit oorspronkelijk bericht niet weergeven -
>> - Tekst uit oorspronkelijk bericht weergeven -

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland