Hey Axel, thanks for the response.

   /The general reason this has not been accepted for Go, is that
   passing a Context explicitly removes ambiguities what is meant, in
   the presence of closures and goroutines./
   /If you pass a closure to a different execution context (e.g. via a
   channel), it has two bindings for any dynamically scoped variable:
   One in the source stack and one in the destination stack. Neither of
   these seems more clearly correct than the other. Note, for example,
   that a callback could be called from a different goroutine
   altogether, yet close over the lexical scope of the function it's
   defined in./

It's an interesting question, however we don't need to use goroutines and channels to evoke this issue.  Closures are enough.  That is, if you make a closure in one function, save it somewhere, and then invoke it from a second location, then the closure has two potential scopes that could apply.

I would argue that the matter can be simply decided by choosing the /calling/ stack, not the destination stack.  Choosing the destination stack would mean that the closure no longer really closes over its calling context.  It is also possible, where semantics require, to pass in specific context variables by value to the closure, and that closure can set them in its immediate (and any potential lower) scopes as needed.

If you want the opposite; context carries from the caller of the func, instead return a bound method call.  The bound method call can have an identical type to a closure, and logically it is the same thing, where the struct is the "closure" of state, but it does not restore the context register when invoked.  This seems like a clear way to choose you want this func to use the /destination/ stack.

   /Goroutines also open some questions on how to efficiently implement
   this without races. To be fair, Context has the same issue, but by
   being a library type, it's used more sparingly, so the performance
   question is less critical./

I don't believe the data structure in Context presents any race conditions, and I also don't believe it's necessary for it to remain a deep linked list to retain that quality.

For instance, Context could create (static) map[any]any data structures for the subsequent contexts it spawns, eg it might decide to do this if the number of new contexts that have been created from it exceeds the "depth" to the next context with a "flattened" map by some threshold.  So if it starts to get deep for a context that is creating a bunch of new contexts, it creates a flattened map and then switches an internal flag.  This can be race–free.  Would an implementation of this help move the needle on this, in your view?

Cheers & Happy Friday,
Sam.

--
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/ca15b6de-1e48-4861-ae2c-c9851479f083%40vilain.net.

Reply via email to