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

results from long computation

11 replies
Ishaaq Chandy
Joined: 2009-02-16,
User offline. Last seen 42 years 45 weeks ago.
Hi all,

I have a function (lets call it 'foo') that does a long computation that is supposed to run at application startup.

The application takes user input and so I would like to start up the app without calling foo so that the user gets access to the app straight away and get foo to run in the background while waiting for user input.

However, upon receiving input from the user, I need the result from foo before I can process the user's input, so, if foo hasn't already completed by the time the user completes input, I need the main thread to block and wait for foo.

Once foo has completed, I should also be able to reuse the same result for multiple iterations of user inputs.

I am also trying to avoid mutability - i.e. no mutable objects or vars.

I have a feeling I can use scala.actors.Future but am unsure how to do this. Any suggestions?

Thanks,
Ishaaq
Ricky Clarkson
Joined: 2008-12-19,
User offline. Last seen 3 years 2 weeks ago.
Re: results from long computation
I don't know Scala's actors library very well, but java.util.concurrent.Future has .get(), which does what you want (it advances the world's time until the point at which the result is available - what a side-effect!).

You could also use Thread directly and join() it from the user input thread when you need to wait on it.

2009/3/2 Ishaaq Chandy <ishaaq@gmail.com>
Hi all,

I have a function (lets call it 'foo') that does a long computation that is supposed to run at application startup.

The application takes user input and so I would like to start up the app without calling foo so that the user gets access to the app straight away and get foo to run in the background while waiting for user input.

However, upon receiving input from the user, I need the result from foo before I can process the user's input, so, if foo hasn't already completed by the time the user completes input, I need the main thread to block and wait for foo.

Once foo has completed, I should also be able to reuse the same result for multiple iterations of user inputs.

I am also trying to avoid mutability - i.e. no mutable objects or vars.

I have a feeling I can use scala.actors.Future but am unsure how to do this. Any suggestions?

Thanks,
Ishaaq

Russel Winder
Joined: 2009-02-13,
User offline. Last seen 42 years 45 weeks ago.
Re: results from long computation

On Mon, 2009-03-02 at 10:10 +0000, Ricky Clarkson wrote:
> I don't know Scala's actors library very well, but
> java.util.concurrent.Future has .get(), which does what you want (it
> advances the world's time until the point at which the result is
> available - what a side-effect!).

Not quite the description I would have given, future.get ( ) just blocks
till the result is ready.

> You could also use Thread directly and join() it from the user input
> thread when you need to wait on it.

I think there is a good moral here "do not use the low-level building
blocks when there are high-level abstractions available". In this case
if futures are usable then they are the things to use since the abstract
away from the detail of thread management. Think of threads as a
"necessary evil".

>

Ricky Clarkson
Joined: 2008-12-19,
User offline. Last seen 3 years 2 weeks ago.
Re: results from long computation
If you are building your own high-level abstractions, then building on top of other high-level abstractions can be difficult, because they might wrap the underlying functionality in a different way than you want.

Threads as a necessary evil?  I'm not sure I'd call anything necessary an evil.  It's worth knowing about and using threads directly sometimes, at least so you understand what your abstractions are doing for you (and hence their holes).

2009/3/2 Russel Winder <russel.winder@concertant.com>
On Mon, 2009-03-02 at 10:10 +0000, Ricky Clarkson wrote:
> I don't know Scala's actors library very well, but
> java.util.concurrent.Future has .get(), which does what you want (it
> advances the world's time until the point at which the result is
> available - what a side-effect!).

Not quite the description I would have given, future.get ( ) just blocks
till the result is ready.

> You could also use Thread directly and join() it from the user input
> thread when you need to wait on it.

I think there is a good moral here "do not use the low-level building
blocks when there are high-level abstractions available".  In this case
if futures are usable then they are the things to use since the abstract
away from the detail of thread management.  Think of threads as a
"necessary evil".


>
--
Russel.
====================================================
Dr Russel Winder                 Partner

Concertant LLP                   t: +44 20 7585 2200, +44 20 7193 9203
41 Buckmaster Road,              f: +44 8700 516 084
London SW11 1EN, UK.             m: +44 7770 465 077

Ishaaq Chandy
Joined: 2009-02-16,
User offline. Last seen 42 years 45 weeks ago.
Re: results from long computation
Java's Future implementation or Thread.join is what I would have used if I was building a Java app - I wanted to know what solution (if any) the scala actor framework could give me.

Remember, one of the goals I stated was immutability, so Thread.join possibly would require some funky coding to get around having to use a var for the result.

Ishaaq

2009/3/2 Ricky Clarkson <ricky.clarkson@gmail.com>
If you are building your own high-level abstractions, then building on top of other high-level abstractions can be difficult, because they might wrap the underlying functionality in a different way than you want.

Threads as a necessary evil?  I'm not sure I'd call anything necessary an evil.  It's worth knowing about and using threads directly sometimes, at least so you understand what your abstractions are doing for you (and hence their holes).

2009/3/2 Russel Winder <russel.winder@concertant.com>
On Mon, 2009-03-02 at 10:10 +0000, Ricky Clarkson wrote:
> I don't know Scala's actors library very well, but
> java.util.concurrent.Future has .get(), which does what you want (it
> advances the world's time until the point at which the result is
> available - what a side-effect!).

Not quite the description I would have given, future.get ( ) just blocks
till the result is ready.

> You could also use Thread directly and join() it from the user input
> thread when you need to wait on it.

I think there is a good moral here "do not use the low-level building
blocks when there are high-level abstractions available".  In this case
if futures are usable then they are the things to use since the abstract
away from the detail of thread management.  Think of threads as a
"necessary evil".


>
--
Russel.
====================================================
Dr Russel Winder                 Partner

Concertant LLP                   t: +44 20 7585 2200, +44 20 7193 9203
41 Buckmaster Road,              f: +44 8700 516 084
London SW11 1EN, UK.             m: +44 7770 465 077


Ricky Clarkson
Joined: 2008-12-19,
User offline. Last seen 3 years 2 weeks ago.
Re: results from long computation
I can't think of a reason for choosing a lib written in Scala over one written in Java, unless it somehow provides an API that works better in Scala.  Also, don't mistake immutability for "not having vars".

2009/3/2 Ishaaq Chandy <ishaaq@gmail.com>
Java's Future implementation or Thread.join is what I would have used if I was building a Java app - I wanted to know what solution (if any) the scala actor framework could give me.

Remember, one of the goals I stated was immutability, so Thread.join possibly would require some funky coding to get around having to use a var for the result.

Ishaaq

2009/3/2 Ricky Clarkson <ricky.clarkson@gmail.com>
If you are building your own high-level abstractions, then building on top of other high-level abstractions can be difficult, because they might wrap the underlying functionality in a different way than you want.

Threads as a necessary evil?  I'm not sure I'd call anything necessary an evil.  It's worth knowing about and using threads directly sometimes, at least so you understand what your abstractions are doing for you (and hence their holes).

2009/3/2 Russel Winder <russel.winder@concertant.com>
On Mon, 2009-03-02 at 10:10 +0000, Ricky Clarkson wrote:
> I don't know Scala's actors library very well, but
> java.util.concurrent.Future has .get(), which does what you want (it
> advances the world's time until the point at which the result is
> available - what a side-effect!).

Not quite the description I would have given, future.get ( ) just blocks
till the result is ready.

> You could also use Thread directly and join() it from the user input
> thread when you need to wait on it.

I think there is a good moral here "do not use the low-level building
blocks when there are high-level abstractions available".  In this case
if futures are usable then they are the things to use since the abstract
away from the detail of thread management.  Think of threads as a
"necessary evil".


>
--
Russel.
====================================================
Dr Russel Winder                 Partner

Concertant LLP                   t: +44 20 7585 2200, +44 20 7193 9203
41 Buckmaster Road,              f: +44 8700 516 084
London SW11 1EN, UK.             m: +44 7770 465 077



Ishaaq Chandy
Joined: 2009-02-16,
User offline. Last seen 42 years 45 weeks ago.
Re: results from long computation
"....unless it somehow provides an API that works better in Scala..."

- which is exactly why I asked. I know the Java Future implementation will work - I've used it in previously in Java code. I just wanted to know if there is an equivalent, better way to do it using Scala - the answer to this question could very well be "No there isn't", but I wanted to ask the question.

Ishaaq

2009/3/2 Ricky Clarkson <ricky.clarkson@gmail.com>
I can't think of a reason for choosing a lib written in Scala over one written in Java, unless it somehow provides an API that works better in Scala.  Also, don't mistake immutability for "not having vars".

2009/3/2 Ishaaq Chandy <ishaaq@gmail.com>
Java's Future implementation or Thread.join is what I would have used if I was building a Java app - I wanted to know what solution (if any) the scala actor framework could give me.

Remember, one of the goals I stated was immutability, so Thread.join possibly would require some funky coding to get around having to use a var for the result.

Ishaaq

2009/3/2 Ricky Clarkson <ricky.clarkson@gmail.com>
If you are building your own high-level abstractions, then building on top of other high-level abstractions can be difficult, because they might wrap the underlying functionality in a different way than you want.

Threads as a necessary evil?  I'm not sure I'd call anything necessary an evil.  It's worth knowing about and using threads directly sometimes, at least so you understand what your abstractions are doing for you (and hence their holes).

2009/3/2 Russel Winder <russel.winder@concertant.com>
On Mon, 2009-03-02 at 10:10 +0000, Ricky Clarkson wrote:
> I don't know Scala's actors library very well, but
> java.util.concurrent.Future has .get(), which does what you want (it
> advances the world's time until the point at which the result is
> available - what a side-effect!).

Not quite the description I would have given, future.get ( ) just blocks
till the result is ready.

> You could also use Thread directly and join() it from the user input
> thread when you need to wait on it.

I think there is a good moral here "do not use the low-level building
blocks when there are high-level abstractions available".  In this case
if futures are usable then they are the things to use since the abstract
away from the detail of thread management.  Think of threads as a
"necessary evil".


>
--
Russel.
====================================================
Dr Russel Winder                 Partner

Concertant LLP                   t: +44 20 7585 2200, +44 20 7193 9203
41 Buckmaster Road,              f: +44 8700 516 084
London SW11 1EN, UK.             m: +44 7770 465 077




Ishaaq Chandy
Joined: 2009-02-16,
User offline. Last seen 42 years 45 weeks ago.
Re: results from long computation
Ok, I think I've worked it out:

val fooFuture = Futures.future(foo)
lazy val returnedFoo = fooFuture.apply

Then the client just uses the lazy returnedFoo reference. If it is already populated then it will not block, but if not then it will.

The advantage over the Java Future implementation is I don't have to worry about setting up an ExecutorService. Of course, if I needed to pool threads this is probably not the best way to go.

Am I making any obvious mistakes here?

Ishaaq

2009/3/2 Ishaaq Chandy <ishaaq@gmail.com>
"....unless it somehow provides an API that works better in Scala..."

- which is exactly why I asked. I know the Java Future implementation will work - I've used it in previously in Java code. I just wanted to know if there is an equivalent, better way to do it using Scala - the answer to this question could very well be "No there isn't", but I wanted to ask the question.

Ishaaq

2009/3/2 Ricky Clarkson <ricky.clarkson@gmail.com>
I can't think of a reason for choosing a lib written in Scala over one written in Java, unless it somehow provides an API that works better in Scala.  Also, don't mistake immutability for "not having vars".

2009/3/2 Ishaaq Chandy <ishaaq@gmail.com>
Java's Future implementation or Thread.join is what I would have used if I was building a Java app - I wanted to know what solution (if any) the scala actor framework could give me.

Remember, one of the goals I stated was immutability, so Thread.join possibly would require some funky coding to get around having to use a var for the result.

Ishaaq

2009/3/2 Ricky Clarkson <ricky.clarkson@gmail.com>
If you are building your own high-level abstractions, then building on top of other high-level abstractions can be difficult, because they might wrap the underlying functionality in a different way than you want.

Threads as a necessary evil?  I'm not sure I'd call anything necessary an evil.  It's worth knowing about and using threads directly sometimes, at least so you understand what your abstractions are doing for you (and hence their holes).

2009/3/2 Russel Winder <russel.winder@concertant.com>
On Mon, 2009-03-02 at 10:10 +0000, Ricky Clarkson wrote:
> I don't know Scala's actors library very well, but
> java.util.concurrent.Future has .get(), which does what you want (it
> advances the world's time until the point at which the result is
> available - what a side-effect!).

Not quite the description I would have given, future.get ( ) just blocks
till the result is ready.

> You could also use Thread directly and join() it from the user input
> thread when you need to wait on it.

I think there is a good moral here "do not use the low-level building
blocks when there are high-level abstractions available".  In this case
if futures are usable then they are the things to use since the abstract
away from the detail of thread management.  Think of threads as a
"necessary evil".


>
--
Russel.
====================================================
Dr Russel Winder                 Partner

Concertant LLP                   t: +44 20 7585 2200, +44 20 7193 9203
41 Buckmaster Road,              f: +44 8700 516 084
London SW11 1EN, UK.             m: +44 7770 465 077





Naftoli Gugenheim
Joined: 2008-12-17,
User offline. Last seen 42 years 45 weeks ago.
Re: results from long computation

Check out scala.concurrency.op iirc.

On 3/2/09, Ishaaq Chandy wrote:
> Ok, I think I've worked it out:
>
> val fooFuture = Futures.future(foo)
> lazy val returnedFoo = fooFuture.apply
>
> Then the client just uses the lazy returnedFoo reference. If it is already
> populated then it will not block, but if not then it will.
>
> The advantage over the Java Future implementation is I don't have to worry
> about setting up an ExecutorService. Of course, if I needed to pool threads
> this is probably not the best way to go.
>
> Am I making any obvious mistakes here?
>
> Ishaaq
>
> 2009/3/2 Ishaaq Chandy
>
>> "....unless it somehow provides an API that works better in Scala..."
>>
>> - which is exactly why I asked. I know the Java Future implementation will
>> work - I've used it in previously in Java code. I just wanted to know if
>> there is an equivalent, better way to do it using Scala - the answer to
>> this
>> question could very well be "No there isn't", but I wanted to ask the
>> question.
>>
>>
>> Ishaaq
>>
>> 2009/3/2 Ricky Clarkson
>>
>>> I can't think of a reason for choosing a lib written in Scala over one
>>> written in Java, unless it somehow provides an API that works better in
>>> Scala. Also, don't mistake immutability for "not having vars".
>>>
>>> 2009/3/2 Ishaaq Chandy
>>>
>>>> Java's Future implementation or Thread.join is what I would have used if
>>>> I was building a Java app - I wanted to know what solution (if any) the
>>>> scala actor framework could give me.
>>>>
>>>>
>>>> Remember, one of the goals I stated was immutability, so Thread.join
>>>> possibly would require some funky coding to get around having to use a
>>>> var
>>>> for the result.
>>>>
>>>> Ishaaq
>>>>
>>>> 2009/3/2 Ricky Clarkson
>>>>
>>>> If you are building your own high-level abstractions, then building on
>>>>> top of other high-level abstractions can be difficult, because they
>>>>> might
>>>>> wrap the underlying functionality in a different way than you want.
>>>>>
>>>>> Threads as a necessary evil? I'm not sure I'd call anything necessary
>>>>> an evil. It's worth knowing about and using threads directly
>>>>> sometimes, at
>>>>> least so you understand what your abstractions are doing for you (and
>>>>> hence
>>>>> their holes).
>>>>>
>>>>> 2009/3/2 Russel Winder
>>>>>
>>>>> On Mon, 2009-03-02 at 10:10 +0000, Ricky Clarkson wrote:
>>>>>> > I don't know Scala's actors library very well, but
>>>>>> > java.util.concurrent.Future has .get(), which does what you want (it
>>>>>> > advances the world's time until the point at which the result is
>>>>>> > available - what a side-effect!).
>>>>>>
>>>>>> Not quite the description I would have given, future.get ( ) just
>>>>>> blocks
>>>>>> till the result is ready.
>>>>>>
>>>>>> > You could also use Thread directly and join() it from the user input
>>>>>> > thread when you need to wait on it.
>>>>>>
>>>>>> I think there is a good moral here "do not use the low-level building
>>>>>> blocks when there are high-level abstractions available". In this
>>>>>> case
>>>>>> if futures are usable then they are the things to use since the
>>>>>> abstract
>>>>>> away from the detail of thread management. Think of threads as a
>>>>>> "necessary evil".
>>>>>>
>>>>>>
>>>>>> >
>>>>>> --
>>>>>> Russel.
>>>>>> ====================================================
>>>>>> Dr Russel Winder Partner
>>>>>>
>>>>>> Concertant LLP t: +44 20 7585 2200, +44 20 7193 9203
>>>>>> 41 Buckmaster Road, f: +44 8700 516 084
>>>>>> London SW11 1EN, UK. m: +44 7770 465 077
>>>>>>
>>>>>
>>>>>
>>>>
>>>
>>
>

Naftoli Gugenheim
Joined: 2008-12-17,
User offline. Last seen 42 years 45 weeks ago.
Re: results from long computation

Also the end of Scala By Example IIRC.

On 3/2/09, Naftoli Gugenheim wrote:
> Check out scala.concurrency.op iirc.
>
> On 3/2/09, Ishaaq Chandy wrote:
>> Ok, I think I've worked it out:
>>
>> val fooFuture = Futures.future(foo)
>> lazy val returnedFoo = fooFuture.apply
>>
>> Then the client just uses the lazy returnedFoo reference. If it is
>> already
>> populated then it will not block, but if not then it will.
>>
>> The advantage over the Java Future implementation is I don't have to
>> worry
>> about setting up an ExecutorService. Of course, if I needed to pool
>> threads
>> this is probably not the best way to go.
>>
>> Am I making any obvious mistakes here?
>>
>> Ishaaq
>>
>> 2009/3/2 Ishaaq Chandy
>>
>>> "....unless it somehow provides an API that works better in Scala..."
>>>
>>> - which is exactly why I asked. I know the Java Future implementation
>>> will
>>> work - I've used it in previously in Java code. I just wanted to know if
>>> there is an equivalent, better way to do it using Scala - the answer to
>>> this
>>> question could very well be "No there isn't", but I wanted to ask the
>>> question.
>>>
>>>
>>> Ishaaq
>>>
>>> 2009/3/2 Ricky Clarkson
>>>
>>>> I can't think of a reason for choosing a lib written in Scala over one
>>>> written in Java, unless it somehow provides an API that works better in
>>>> Scala. Also, don't mistake immutability for "not having vars".
>>>>
>>>> 2009/3/2 Ishaaq Chandy
>>>>
>>>>> Java's Future implementation or Thread.join is what I would have used
>>>>> if
>>>>> I was building a Java app - I wanted to know what solution (if any)
>>>>> the
>>>>> scala actor framework could give me.
>>>>>
>>>>>
>>>>> Remember, one of the goals I stated was immutability, so Thread.join
>>>>> possibly would require some funky coding to get around having to use a
>>>>> var
>>>>> for the result.
>>>>>
>>>>> Ishaaq
>>>>>
>>>>> 2009/3/2 Ricky Clarkson
>>>>>
>>>>> If you are building your own high-level abstractions, then building on
>>>>>> top of other high-level abstractions can be difficult, because they
>>>>>> might
>>>>>> wrap the underlying functionality in a different way than you want.
>>>>>>
>>>>>> Threads as a necessary evil? I'm not sure I'd call anything
>>>>>> necessary
>>>>>> an evil. It's worth knowing about and using threads directly
>>>>>> sometimes, at
>>>>>> least so you understand what your abstractions are doing for you (and
>>>>>> hence
>>>>>> their holes).
>>>>>>
>>>>>> 2009/3/2 Russel Winder
>>>>>>
>>>>>> On Mon, 2009-03-02 at 10:10 +0000, Ricky Clarkson wrote:
>>>>>>> > I don't know Scala's actors library very well, but
>>>>>>> > java.util.concurrent.Future has .get(), which does what you want
>>>>>>> > (it
>>>>>>> > advances the world's time until the point at which the result is
>>>>>>> > available - what a side-effect!).
>>>>>>>
>>>>>>> Not quite the description I would have given, future.get ( ) just
>>>>>>> blocks
>>>>>>> till the result is ready.
>>>>>>>
>>>>>>> > You could also use Thread directly and join() it from the user
>>>>>>> > input
>>>>>>> > thread when you need to wait on it.
>>>>>>>
>>>>>>> I think there is a good moral here "do not use the low-level
>>>>>>> building
>>>>>>> blocks when there are high-level abstractions available". In this
>>>>>>> case
>>>>>>> if futures are usable then they are the things to use since the
>>>>>>> abstract
>>>>>>> away from the detail of thread management. Think of threads as a
>>>>>>> "necessary evil".
>>>>>>>
>>>>>>>
>>>>>>> >
>>>>>>> --
>>>>>>> Russel.
>>>>>>> ====================================================
>>>>>>> Dr Russel Winder Partner
>>>>>>>
>>>>>>> Concertant LLP t: +44 20 7585 2200, +44 20 7193
>>>>>>> 9203
>>>>>>> 41 Buckmaster Road, f: +44 8700 516 084
>>>>>>> London SW11 1EN, UK. m: +44 7770 465 077
>>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
>

Martin S. Weber
Joined: 2008-12-23,
User offline. Last seen 42 years 45 weeks ago.
Re: results from long computation

Quoting Naftoli Gugenheim :

> Check out scala.concurrency.op iirc.

scala.concurrent.ops . Which sadly reminds any reader of it (the scala
api doc of this object or package scala.concurrent in general) of the
sorry state of scala documentation :(

-Martin

Alex Boisvert
Joined: 2008-12-16,
User offline. Last seen 42 years 45 weeks ago.
Re: results from long computation
Here's perhaps a better example using actors...  java.util.concurrent.Future is kind of low-tech ;)

// This is your application
object Demo extends Application {
  import FutureActor._
 
  val message = new FutureActor[String]
 
  // code that needs to use future value at some point
  actor {
    // do stuff
    val m = (message !? GetValue)
    Console println m
    exit()
  }

  // meanwhile, application is initializing
  actor { 
    Console println "Initializing..."
    Thread.sleep(5000) // pretend to initialize
    Console println "Initialization completed."
    message ! SetValue("Hello World!")
    exit()
  }

  // hook to kill the application
  actor {
    Thread.sleep(8000)
    Console readLine "Press [ENTER] to quit"
    Scheduler.shutdown
  }
}

See attached for full code.

alex

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