Brandon--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
clojure+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
Cheers,Brandon--
Thanks!
I don't do anything special for asynchronous code, this simply provides the primitives necessary. Which is, primarily, bound-fn. Which is, in turn, built on {get,pop,push}-thread-bindings.
There is some future work, which requires far more thinking, to accomplish something akin to C#'s async/await keywords.
ClojureScript doesn't have future-call or agents yet, but if they (or similar constructs) are to be implemented correctly, you need the ability to save and load a binding frame. That's what my changes accomplish.
What use cases do you have in mind?
Well, I suppose one could implement green threads in JavaScript ... :)
On Wednesday, February 15, 2012, Brandon Bloom <snpr...@gmail.com> wrote:.Step one is properly describing the problem. There are many possible solutions many which don't try to graft Clojure's concurrency concepts onto a single-threaded environment.
> There are analogous constructs in a single-threaded, async-callback world. In particular, many Javascript libraries have a concept of promises and futures for managing the async callback speghetti. Like I said, that part of the puzzle needs much more thought. This is step one: Implement robust dynamic binding.
You're working on a particular solution - others already exist in the JS world as you've mentioned. A robust solution can be implemented via CPS transformation, and that can be provided as a ClojureScript library without changing the meaning of binding as it's currently implemented.
I would expand your design notes before you continue down any particular solution. Otherwise it will have insufficient justification.
--
+1
> So I don't understand why you are rejecting the idea of adding support for
> them based on the argument that Javascript is monothread ...
Particularly when there is no guarantee that JS will stay that way
forever, and the general historic trend has been for languages to gain
multithreading that formerly lacked it.
Forgive me if I'm wrong, but global vars / dynamic variables have essentially more to do with scoping than multithreading, e.g. they existed in lisps and other languages way before thread support was added to them.
So I don't understand why you are rejecting the idea of adding support for them based on the argument that Javascript is monothread ...
On Fri, Feb 17, 2012 at 1:28 AM, Laurent PETIT <lauren...@gmail.com> wrote:Forgive me if I'm wrong, but global vars / dynamic variables have essentially more to do with scoping than multithreading, e.g. they existed in lisps and other languages way before thread support was added to them.
So I don't understand why you are rejecting the idea of adding support for them based on the argument that Javascript is monothread ...Dynamic binding already works in ClojureScript.
The discussion is about whether dynamic binding should be extended to address common async patterns in JavaScript applications.
--
> A robust solution can be implemented via CPS transformationForgive me for my ignorance, but how exactly would a CPS transformation enable one to capture and restore the current set of dynamic bindings?
The problem is dealing with with asynchronous code, right? Not capturing / restoring dynamic bindings.
The problem is dealing with with asynchronous code, right? Not capturing / restoring dynamic bindings.No, the problem is that there is no mechanism to capture and restore dynamic bindings.This is a shortcoming irrespective of asynchronous code.
The ClojureScript wiki states that "the user experience of [binding] is similar to that in Clojure" but my very first experiment produced wildly different results between platforms.Here's a Clojure on the JVM session:user=> (import java.lang.Thread)java.lang.Threaduser=> (defn set-timeout [ms fn] (.run (Thread. #(do (Thread/sleep ms) (fn)))))#'user/set-timeoutuser=> (def x "top level")#'user/xuser=> (binding [x "in binding"] (println x) (set-timeout 1000 #(println x)))in bindingin bindingnilAnd here's the analogous ClojureScript session:ClojureScript:cljs.user> (def x "top level")"top level"ClojureScript:cljs.user> (binding [x "in binding"] (println x) (js/setTimeout #(println x) 1000))in binding21top levelSo ignoring the sequencing and nil vs timeout-id return values, the binding of 'x wasn't preserved in the asynchronous callback.I raised this issue in #clojure and @dnolen said that "that's the behavior there's nothing much to fix", but that didn't sit right with me. This seems like either 'binding is bugged, or maybe I don't understand something about its intent.On the topic of "Vars" proper, I understand their usefulness in repl-centric development, where you can redefine functions at runtime. The wiki also makes some mention of this, but I can't wrap my head around the context and jargon. I've run into this problem before in Javascript, where some level of indirection is necessary to support run-time redefinitions. You can't do `var fn = package.fn;` and dynamically redefine `fn` from `package` later because a copy of the reference is made. How does ClojureScript address this problem?Cheers,Brandon
--