[TransWarp] Proposed peak.binding API change

Phillip J. Eby pje at telecommunity.com
Wed Sep 3 14:20:41 EDT 2003

At 11:08 AM 9/3/03 -0400, Ty Sarna wrote:

>I'm -1 on Provide/Require...  too much implication of dependancy
>ordering, module dependancies, etc for me,

That's what it's *supposed* to imply!  :)

>  and too much of a "these come
>in pairs" effect as well...  makes me wonder if for each require in one
>class, there should be a corresponding provide in another or something
>like that.

And well you should wonder, because generally speaking, yes, there *should* 
be a corresponding source for something you require.  Of course, you could 
be depending on a name or property name, but those still have to be 
"provided" or "supplied" by something, i.e. a naming context or a config file.

So far, of the general approaches, I like a two-name API best, from the 
teaching and reading perspectives.  Apparently, from your reaction to it, 
it communicates precisely the thing I wanted it to communicate.  :)  I am 
not settled on the best word to use for the supply-side.

In truth, there are many use cases for bindings:

1. An outward-focused dependency
2. An inward-focused dependency
3. A value placeholder for internal use
4. A utility being offered to subcomponents

However, not all of these uses are mutually exclusive.  #4 for example can 
coexist with any of the others, and thus is prime for a keyword argument 
(that already exists: offerAs).

The Require/Provide split doesn't distinguish between use cases 1 and 2, 
though; they'd both be considered 'require' cases.  #3 is considered a 
'provide', even though it's not intended for outward consumption.  I've 
thought about maybe differentiating between 1 and 2, using maybe 'Require' 
and 'Reference', or 'Require' and 'Use', for outward and inward 
dependencies.  The strings they accept could be different, such that it 
isn't possible to create an outward dependency using the inward API, or 
vice versa.  This would be another useful distinction from the 
teaching/reading perspective, though it's of relatively little consequence 
to the person writing the code.

So, another possible approach is to go for a 3-way API that doesn't have so 
strong a require/provide implication: Require, Supply, Use.  A component 
"requires" things of its context, "supplies" things to itself, and may make 
"use" of its components.  Any of the things that are "required", 
"supplied", or "used" may also be "offered" to the component's subcomponents.

Possible terminology:

Require    Supply     Use
Obtain     Make       Reference
Acquire    Build      Refer
Take       Produce    Attach

All in all, I think most of the benefit of a three-way split is for the 
code's reader.  I'm not sure it adds enough over the two-way split to be 
worthwhile.  I do think that the two-way split adds significant value over 
a singleton API.  Ironically, the value I see it adding is the very thing 
that you -1'd.  ;)

I wish there was some ready-made terminology for this (other than the 
status quo!) that we could just steal and be done with it.  :)

>I'm not sure if like it better than Attr (or the status quo, for that
>matter), but one possible replacement name for Provide is Default, or
>maybe defaultTo.  Since after all, that's what they do, serve as
>defaults unless you wire them up explicitly.  Then, you just need to
>change the "default" keyword parameter so it reads better
>binding.Default(lambda: expr)

Hm.  It seems a little too passive to me; it makes me think that 
'aFunction' will be *returned* rather than *called*.

>Jean Jordan wrote:
> > binding.Bind(...)  would be totally neutral, and would work
> > with binding.Require(...) ..
>we talked about making it just "binding" (IOW, make the module
>callable). But that introduces lots of ickyness in the process.

Bind seems a little better to me that Default, as it verbs more.  :)  Of 
course, Default can also be a verb, but it doesn't seem that way by 
default.  :)

More information about the PEAK mailing list