1

The title is right, I want everything.

  • In eager evaluation the functions are evaluated always as soon as the assignment is done.
  • In lazy evaluation this is not done until the value is needed, but then it is a blocking operation, just like in eager evaluation, but delayed.
  • I would like to have something that starts the evaluation eagerly and concurrently (not blocking) until the value is needed.

I know this is a bit strange, so I made an illustrative gist.

It works perfectly in this example and the computation of the lazy eager value seems to be for free, while the other two values take 10 seconds each. Sure, things are happening in another thread and so on, but I'm fine with that, I would simply like to have some option to do things like this, sometimes, when needed.

I've been thinking in more elegant ways to define this, functions, annotations, etc. In the end the only possibility I found are macros, which are not available in Scala (AFAIK).

Is there any way to do this in an elegant way or what I wrote is as elegant as it gets?

PD: just to make it more clear. This is what it takes to do what I want to do:

val eager_lazy_aux = Future(longComputation(1))
lazy val eager_lazy = Await.result(eager_lazy_aux, Duration.Inf)

This is what I would like to do:

parallel val eager_lazy = longComputation(1)

I'm not a big fan of implicits, but maybe adding this is the best that we can get.

implicit def getFuture[T](f: Future[T]): T = Await.result(f, Duration.Inf)
Trylks
  • 1,458
  • 2
  • 18
  • 31
  • 3
    What is wrong with Future? – Jean Logeart Oct 28 '14 at 18:52
  • 2
    What you're describing seems pretty much the same as a Future, as @JeanLogeart says. – The Archetypal Paul Oct 28 '14 at 19:01
  • @JeanLogeart If you check the example you will see that I'm using Future, but it is more cumbersome than simply writing lazy in front of the variable (`val`), or @future or anything like that. In fact, I'm using two variables for that. The question is: is there any way to do this in an elegant way? (e.g. writing @future). – Trylks Oct 28 '14 at 19:23
  • @Paul please see previous comment (and the gist), Future is more cumbersome. – Trylks Oct 28 '14 at 19:23
  • The title seems to imply you were asking if it was possible, not that you just wanted something more convenient, So you just want a way to wrap a Future is some (for you) more elegant way? I guess I don't understand what you're after (Scala does have macros, btw). – The Archetypal Paul Oct 28 '14 at 20:21
  • The perfect solution for me would be to write `parallel` instead of `lazy` and get the computation to run in an eager but non-blocking (i.e. parallel) way. This is what the code I shared does, but using Future, not this fancier thing that I don't know whether is possible or not, I have seen the documentation for the macros now, but I'm going to need a while before I can figure put if doing this is possible and how to do it. Thank you. – Trylks Oct 28 '14 at 21:27
  • What is so cumbersome about `val f = Future(longComputation())` within a different `ExecutionContext` ??? – Michael Zajac Oct 29 '14 at 01:39
  • The type of `f` is not the return type of `longComputation`, is it? – Trylks Oct 29 '14 at 08:38
  • @Trylks It can't be. What you're asking is impossible then. What happens when the `Future` hasn't completed and you want to access the value? Then you have to block. – Michael Zajac Oct 29 '14 at 14:29
  • @LimbSoup I know... Please check the first code block I added. – Trylks Oct 29 '14 at 14:34
  • The problem I see here is that 'future' is not an adjective, how do you call this feature, 'futuristic evaluation'? – tribbloid Nov 02 '19 at 20:25
  • @tribbloid it is just parallel evaluation as in a normal `Future`. Except you use it as the type of the success of the `Future`, forgetting about it's `Future` nature, which would be transparent – Trylks Nov 02 '19 at 21:29

0 Answers0