a promises based async implementation is not incredibly helpful when you have a strictly one-after-another ordering of data dependencies
I don't understand what you mean. Of course it's helpful.
memcached.get[String]("someKey") flatMap {
case Some(value) => Future.successful(value)
case None =>
database.query(...).flatMap { value =>
memcached.set("someKey", value, 10.minutes)
}
}
The above fetches a key from memcached and in case it doesn't exist, it fetches it from the database and once that's done, it sets the value in memcached and once that's done the processing is done and thus you can continue with other things. If the clients are non-blocking, than that's totally asynchronous and scalable.
In Clojure you don't see this because in Clojure people don't work with Monads.
Using promises doesn't make the Scala solution meaningfully or usefully asynchronous unless the handler is yielding its thread while blocking on I/O.
The idea of Futures is not to use blocking I/O, but rather to either:
1) use non-blocking I/O, or
2) delegate the blocking I/O call to some sort of actor, then continue the execution once that's done
Comments
I don't understand what you mean. Of course it's helpful.
The above fetches a key from memcached and in case it doesn't exist, it fetches it from the database and once that's done, it sets the value in memcached and once that's done the processing is done and thus you can continue with other things. If the clients are non-blocking, than that's totally asynchronous and scalable.In Clojure you don't see this because in Clojure people don't work with Monads.
The idea of Futures is not to use blocking I/O, but rather to either:
1) use non-blocking I/O, or
2) delegate the blocking I/O call to some sort of actor, then continue the execution once that's done
Both are possible and quite easy.
Monads are used in Clojure, just not for this particular use-case because it's unnecessary the majority of the time.
A good example of monad (and macros) use would be: http://github.com/clojure/core.async