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.