4 ms·
Know what would be awesome? If you could use the monad syntax to clean up async, cb-passing code. I've been learning a lot of Haskell lately too, and I like to
by embwbam 15y ago
Know what would be awesome? If you could use the monad syntax to clean up async, cb-passing code. I've been learning a lot of Haskell lately too, and I like to think of the monads as returning a set of instructions with side effects to be executed in order. I think this example is kind of trivial. I'd love to see one that does something more than simple addition (IO!)
- alxv 15y agoWell, there is a Cont monad in Haskell (Control.Monad.Cont). I am not too familiar with it though I know there is a good chapter about it in the Haskell Wikibook (http://en.wikibooks.org/wiki/Haskell/Continuation_passing_style http://en.wikibooks.org/wiki/Haskell/Continuation_passing_st...).
- ufo 15y agoActually, there are already monadic interfaces for Javascript async code with widespread use. Promises! http://dojotoolkit.org/reference-guide/dojo/Deferred.html http://dojotoolkit.org/reference-guide/dojo/Deferred.html http://api.jquery.com/category/deferred-object/ http://api.jquery.com/category/deferred-object/ new deferred objects can be created manually or obtained from say, an AJAX function (this is the equivalent of "return") async operations can be chained with the deferred.then method (this is a hybrid of "fmap" and ">>=", aka "bind")
- pufuwozu 15y agoAuthor here, that's the plan! :)
- samdk 15y agoJane Street's Async library for OCaml does this: http://ocaml.janestreet.com/?q=node/100 http://ocaml.janestreet.com/?q=node/100. It's excellent, and I now miss it in every other language I use. Code looks something like this: ... (* long_running_call : unit -> string Deferred.t *) long_running_call () >>= fun result -> print_endline result ... Running calls in parallel is easy. Say we want to run a couple of queries against a db at once, and only perform an action once both return: ... (* Db.query : Db -> Db.Query -> Db.Result Deferred.t *) let d1 = Db.query db query1 in let d2 = Db.query db query2 in d1 >>= fun r1 -> d2 >>= fun r2 -> ... If you have questions about getting it set up/using it, the mailing list is the place to ask: https://groups.google.com/forum/#!forum/ocaml-core https://groups.google.com/forum/#!forum/ocaml-core
- Peaker 15y agoDoesn't this have the same problem that Python's Twisted does -- that async calls may lack handlers for error conditions, and so errors may be silently ignored?
- samdk 15y agoAsync includes a module called Monitor that lets you correctly handle exceptions in async code. The signature of one of the most commonly used methods is this: Monitor.try_with : ?name : string -> (unit -> 'a Deferred.t) -> ('a, exn) Result.t Deferred.t It takes two arguments. Name is used to tell you what monitor the error was caught by. The second is a function that returns some kind of Deferred.t. The whole thing returns a (deferred) Result.t (: [`Ok of 'a | `Error of exn]), letting you either do something with the results of the async call or handle the error. Usage might be something like this: (* query_or_print : Db.t -> Db.Query.t -> Db.Result.t option Deferred.t *) let query_or_print db query = Monitor.try_with (fun () -> Db.query db query) >>| function | `Ok result -> Some result | `Error e -> print_endline (Exn.to_string e); None