3 ms·
"Combining for-comprehensions with composable futures makes asynchronous concurrency look like straightforward synchronous code." I would really enjoy seeing t
by hythloday 13y ago
"Combining for-comprehensions with composable futures makes asynchronous concurrency look like straightforward synchronous code."
I would really enjoy seeing this in Java.
- courtf 13y agoFair enough, the syntax is rather pleasing.
- agumonkey 13y agomore than syntax, immutable functional idioms are pretty good defaults, shorter both syntactic and semantic wise
- RyanZAG 13y agoJust curious, but have you used Java8 much? Or barring that, something like quasar? Qasar in particular is about writing async code as if it were sync code...
- lmm 13y agoJava's future API is inadequate - you can only block on a future or poll it, not ask to be notified when it completes, so you end up needing a thread for each future which loses a lot of the benefits. I haven't used Qasar specifically but I did use other java extensions that add some scala features for a while (Lombok and the Checkers Framework). The thing is, once you're using those you're effectively using a different language ("extended java") with its own bugs - and the community for that language is much smaller than that for scala.
- justinsb 13y agoIt is a weird omission, not least because it seems that anyone that wants to use Futures ends up extending it in the same (but incompatible) way. Guava has ListenableFuture, Netty has its own version, etc. I'm not sure how this happened, but I just use Guava's ListenableFuture and am happy again.
- RyanZAG 13y agoIt was omitted because it's a complex design issue. Someone using the future would assume that if they added a callback, it would run on the same thread that they called it from. That's not possible in the general case: the thread they called it on may not have an event loop and so could not be directly notified. It's better to leave this to frameworks or libraries that have their own event loop mechanism to handle callbacks.
- laureny 13y ago> not ask to be notified when it completes This is trivial to add (Guava offers it as ListenableFuture), but either way, it's a library concern, not a language one, so I don't think it makes sense to pit Java and Scala over this.
- lmm 13y agoThe standard library matters, particularly because Java doesn't let you smooth over these incompatibilities with implicits. But you're right, I should've said that the syntax (while a vast improvement over previous Java) is not as nice as for/yield, and the lack of higher-kinded types in Java means you can't write functions that handle Futures and other types with similar semantics generically.
- laureny 13y agoI'd like to see the Scala code too. I've played with both and in the end, both codes are pretty complex, just complex in different ways. It's a complex problem with a lot of edge cases and tricky error cases that need to be handled properly, which is where the elegance of the language or the programming paradigm usually goes down the drain. I'd like to see a fully functional snippet of code that gracefully handles errors in both languages.
- noelwelsh 13y agofor { a <- doSomething1() b <- domSomething2() } yield { foo(a, b) } Use a Future + \/ monad.
- hythloday 13y agoOK. Something like: val fNotifications: Future[List[Notification]] = // get notifications from the database val fPosts: Future[List[Post]] = // get posts from a different database // If getting notifications fail, log the error and pretend there are no notifications val safeNotifications = fNotifications rescue { t: Throwable => log.error(t); Future(Nil) } // If getting posts fails, log the error and try retrieving stale posts from the cached post server val safePosts = fPosts rescue { t: Throwable => log.error(t) // If the cached post server fails too, just pretend there are no posts cachedPostsDatabase.getForCurrentUser rescue { t: Throwable => log.error(t); Future(Nil) } } val facebookPage: Future[Page] = for { notifications: List[Notification] <- safeNotifications posts: List[Post] <- safePosts } yield { // Code here executes when both/all outer futures are ready renderFBPage(notifications, posts) } // We can return the future or call more rescues on it or combine it with more futures is a thumbnail sketch of how you'd implement the facebook timeline in Scala if you were doing so. There are even better abstractions that I've started using (functional reactive programming specifically) but none of them come with the standard library, so I thought that was a bit unfair.