On Nov 1, 2011, at 10:20 PM, Tim Allen wrote:

> On Tue, Nov 01, 2011 at 02:48:02PM -0400, Glyph wrote:
>> If you can think of a better solution that addresses all of these
>> concerns simultaneously somehow, please share, I'd love to hear it
>> :-).
> 
> I'm not sure if it addresses all your concerns, but
> twisted.python.context will let you set a particular value for things
> you call and all their descendants (unless one of them sets a new value
> in the context). I can imagine interleaving code that passes a reactor
> parameter explicitly and code that grabs a reactor from the current
> context without much hassle.

I invented twisted.python.context for this very reason!

But... I find the idea of encouraging its widespread use disconcerting.

There are a couple of issues (and if you search the web for "emacs lisp dynamic 
scope" you will find a whole bunch of them) but the main problem is this:

When you do context.get(something) and something isn't there... what do you do? 
 Whose fault is it?

As a parallel example, when a function gets called with the wrong argument, 
it's quite easy to figure out where the problem is: you just look at the 
caller, and the caller almost certainly knows who they are.  The caller somehow 
has to know about the signature of the callee and if they get it wrong it's an 
immediate and obvious runtime error.

But when code has a relationship to its caller's caller's caller's caller's 
caller, and there may be any amount of indirection in there (callbacks 
registered on Deferreds, for example) how do you find the place that really 
should have been the one to pass the result?  How do you know at the time you 
invoke something, all the context that it may require?

The immediate place I can think of where this would cause issues is with GUI 
callbacks.  Right now Twisted goes out of its way to make sure that you can 
'.connect("clicked", ...)' on a GTK widget and use any old python callback you 
want.  If we made the reactor context-driven, then that would work... mostly.  
If Twisted's callbacks were run with the reactor present, then the GUI's 
callbacks might not have the reactor available to them because they lack some 
setup.

Of course you can probably fix that problem, but there are other places where 
it will crop up again; the standard idiom is to call a bunch of functions to 
set up event handlers, then call reactor.run().  But what if the reactor isn't 
available to those functions before it's run?

Et cetera, et cetera.

If you can think of a solid, robust way to specify contracts that describe what 
context is expected, by whom, and how it can be filled at the right time 
without surprising consequences, I'd love to hear it, but I won't hold my 
breath :).

-glyph


_______________________________________________
Twisted-Python mailing list
Twisted-Python@twistedmatrix.com
http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python

Reply via email to