[TransWarp] Proposed peak.binding API change

Phillip J. Eby pje at telecommunity.com
Tue Sep 2 22:55:51 EDT 2003

As I've been preparing to update the tutorial for the 0.5a3 release, the 
current binding API has been bothering me; I've found it hard to explain, 
and sometimes difficult to use.  There are just too many functions/classes, 
even though they all do almost the same thing.  Further, their names focus 
on *how* they work -- their differences -- rather than their commonality.

So my first proposal was to get rid of all the zillions of different 
binding types and replace them with a single 'binding.Attribute' class, or 
'binding.Attr' for typing convenience.  Such an API would focus more 
clearly on "what" bindings are: attributes.  But feedback from Ty and Lynn 
suggested that what we really need to emphasize is *why* bindings are; 
i.e., what they are for.  Neither the current spelling nor my first 
proposal addressed this very well.

So, here's my "new new proposal"...


binding.requireBinding("what's required")

binding.Provide(lambda: expr)

binding.Require(doc="what's required")
binding.Require(key, offerAs=[key])
binding.Require( [key1,key2,...] )
binding.Require( binding.delegate("attrName") )

Provide and Require would accept mostly identical keyword arguments, the 
same ones as all the current binding APIs take (doc, adaptTo, offerAs, 
suggestParent, etc.).  Also, there will be some new functionality: e.g. 
'function' will now be able to be a no-argument or one-argument function 
(e.g. 'binding.Provide(lambda self: self.something * 2)') without needing 
to always use the three-argument form 'lambda self,d,a:'.  Also, both 
'Require' and 'Provide' will accept sequences, and evaluate to a sequence 
of the results of the supplied items.  That is:

myAttr = binding.Provide( [ lambda: 1, lambda: 2 ] )

will cause 'myAttr' to end up with the value '[1,2]' at runtime.

The new spelling is intended to emphasize the purpose of the binding, and 
make it easier for a component user reading source code to tell the 
difference between what a component requires from other components, and 
what the component provides on its own (but can still be overridden in an 
individual instance or subclass).

I'm not 100% certain of this spelling.  'Provide' seems a little "off" 
somehow, because such attributes are often really just for internal use of 
that component.  For example, if I was writing a 'MicrowaveOven' class, it 
would have many 'Provide' attributes that describe internal components, 
such as its 'powerSupply'.  OTOH, such internal components are still being 
"provided" by the designer of the overall component.  I guess the thing 
that bothers me is that really *most* uses of 'Provide'-equivalent 
functions today are of this internally-directed nature, and Provide seems 
to carry an implication that it's an "output" value somehow.

Anyway...  if someone has a good suggestion for an alternative name to 
Provide, that would be most helpful.  I'd also be interested in feedback on 
this proposal, which I haven't discussed with anyone at this point, since I 
thought of it after everybody else left work for the day.  :)

(Note: if/when this goes in, the existing APIs would remain valid (but 
deprecated) for one release cycle.  Also, there are probably going to be 
some keyword argument name changes; 'suggestParent' and 'isVolatile' in 
particular are almost certain to be renamed in the new API (as soon as I 
figure out better names!), although they might be left backward compatible 
in the old API.  These keywords made their appearance in the a3 release 
cycle, though, so I might just rename 'em throughout, if there are no 
objections raised.) 

More information about the PEAK mailing list