- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
results from long computation
Mon, 2009-03-02, 10:51
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
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
Mon, 2009-03-02, 11:47
#2
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".
>
Mon, 2009-03-02, 11:57
#3
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>
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
Mon, 2009-03-02, 12:37
#4
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>
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
Mon, 2009-03-02, 12:57
#5
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>
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
Mon, 2009-03-02, 13:07
#6
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>
- 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
Mon, 2009-03-02, 13:37
#7
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>
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
Mon, 2009-03-02, 18:47
#8
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
>>>>>>
>>>>>
>>>>>
>>>>
>>>
>>
>
Mon, 2009-03-02, 18:57
#9
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
>>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
>
Mon, 2009-03-02, 18:57
#10
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
Mon, 2009-03-02, 19:07
#11
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
// 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
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>