Re: [Zope3-dev] Re: reasonable syntax for multi-adaptation
On Sep 28, 2007, at 11:14 AM, Martijn Faassen wrote: ... On 9/28/07, Jim Fulton <[EMAIL PROTECTED]> wrote: [snip] we could investigate whether we can't come up with something that: * doesn't break the existing notation. The cleanest way to support such non-interference seems to be to do this using an extra .adapt method. This is unfortunate, as I at least consider it prettier if it used the IFoo() syntax (even though I proposed .adapt). I agree. Hm, you agree with my evaluation, but would this mean you'd suggest we use 'adapt' or extend the __call__ syntax? In the short-to-medium term the adapt method is my preference. ... After thinking about it, I think I can avoid the extra hook. Don't worry about the details. :) Cool! The person that tries to implement this will have to worry about them, though, so we'll get back to you on that, I'm sure. Yup. ... Do you suggest we extend zope.component with support for this, or would you suggest we indeed create a new package? You'll need to modify InterfaceClass to add the new adapt method and __call__ semantics. The hook installed by zope.component will need to be updated as well. I see no new package being warrented. Jim -- Jim Fulton Zope Corporation ___ Zope3-dev mailing list Zope3-dev@zope.org Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com
Re: [Zope3-dev] Re: reasonable syntax for multi-adaptation
Hey, First: thanks for listening, Jim. On 9/28/07, Jim Fulton <[EMAIL PROTECTED]> wrote: [snip] > > we could investigate whether we can't come up with something that: > > > > * doesn't break the existing notation. The cleanest way to support > > such non-interference seems to be to do this using an extra .adapt > > method. This is unfortunate, as I at least consider it prettier if > > it used the IFoo() syntax (even though I proposed .adapt). > > I agree. Hm, you agree with my evaluation, but would this mean you'd suggest we use 'adapt' or extend the __call__ syntax? > > * creates a small a new hook inside zope.interface to support this > > After thinking about it, I think I can avoid the extra hook. Don't > worry about the details. :) Cool! The person that tries to implement this will have to worry about them, though, so we'll get back to you on that, I'm sure. > BTW, we *could* use interface __call__ for utility lookup, as there > would be no conflict with current notation *if* we specified a > default using a keyword argument. > I would far prefer using > >IFoo() or IFoo(default=None) > > to look up a utility over: > >IFoo.adapt() or IFoo.adapt(default=None) > > for, I hope, obvious reasons. Agreed. This is good argument for using the __call__ syntax. > I'd also like to support specifying a default for adapter lookup via > a keyword argument. In fact, I'd like to deprecate passing the > default positionally. This would open the door, sometime in the > future, to allowing multi-adaptation via: IFoo(ob1, ob2). +1 > > So, any volunteers to try to implement this? > > I insist on reviewing any change before checking it in. This will > create an unavoidable bottle neck. Understood. Work will be done on a branch. Do you suggest we extend zope.component with support for this, or would you suggest we indeed create a new package? Regards, Martijn ___ Zope3-dev mailing list Zope3-dev@zope.org Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com
Re: [Zope3-dev] Re: reasonable syntax for multi-adaptation
On Sep 28, 2007, at 10:31 AM, Martijn Faassen wrote: Dominik Huber wrote: It would be great, if we could handle other adaption-derivations by the proposed unified, reasonable adaption-api too. [snip interesting proposal] Okay, so there seems to be quite a bit of consensus for *some* form of support for this. I've seen a number of proposals which to me look quite reasonable. Since Jim doesn't like this much but there seems to be a lot of support from others, And am willing, therefore, to compromise we could investigate whether we can't come up with something that: * doesn't break the existing notation. The cleanest way to support such non-interference seems to be to do this using an extra .adapt method. This is unfortunate, as I at least consider it prettier if it used the IFoo() syntax (even though I proposed .adapt). I agree. * creates a small a new hook inside zope.interface to support this After thinking about it, I think I can avoid the extra hook. Don't worry about the details. :) * can be plugged in by an optional extension, like zope.interfacextended See above. * implements the proposed new features. I like the idea of also allowing utility lookup through the same mechanism. I don't, but I'm willing to give in to popular demand. BTW, we *could* use interface __call__ for utility lookup, as there would be no conflict with current notation *if* we specified a default using a keyword argument. I would far prefer using IFoo() or IFoo(default=None) to look up a utility over: IFoo.adapt() or IFoo.adapt(default=None) for, I hope, obvious reasons. I'd also like to support specifying a default for adapter lookup via a keyword argument. In fact, I'd like to deprecate passing the default positionally. This would open the door, sometime in the future, to allowing multi-adaptation via: IFoo(ob1, ob2). So, any volunteers to try to implement this? I insist on reviewing any change before checking it in. This will create an unavoidable bottle neck. Jim -- Jim Fulton Zope Corporation ___ Zope3-dev mailing list Zope3-dev@zope.org Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com
[Zope3-dev] Re: reasonable syntax for multi-adaptation
Dominik Huber wrote: It would be great, if we could handle other adaption-derivations by the proposed unified, reasonable adaption-api too. [snip interesting proposal] Okay, so there seems to be quite a bit of consensus for *some* form of support for this. I've seen a number of proposals which to me look quite reasonable. Since Jim doesn't like this much but there seems to be a lot of support from others, we could investigate whether we can't come up with something that: * doesn't break the existing notation. The cleanest way to support such non-interference seems to be to do this using an extra .adapt method. This is unfortunate, as I at least consider it prettier if it used the IFoo() syntax (even though I proposed .adapt). * creates a small a new hook inside zope.interface to support this * can be plugged in by an optional extension, like zope.interfacextended * implements the proposed new features. I like the idea of also allowing utility lookup through the same mechanism. The goal is to support this notation in applications. Of course, as soon as a library or framework starts to depend on this extension Jim will run into it if he starts to use them, but that happens in all kinds of ways otherwise anyway. So, any volunteers to try to implement this? Regards, Martijn ___ Zope3-dev mailing list Zope3-dev@zope.org Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com
Re: [Zope3-dev] Re: reasonable syntax for multi-adaptation
Marius Gedminas wrote: On Wed, Sep 26, 2007 at 09:09:37PM -0400, Tres Seaver wrote: Why does the caller care? She just wants an object which will provide the 'IFoo' contract on behalf of the passed context. If 'x' is capable of providing 'IFoo' without help, then failing (or worse, returning a less-specific factory result) when calling 'getAdapter' is the Wrong Thing (a "least surprise" violation, if nothing else). FWIW it was a big surprise to me when I discovered that IFoo(x) has different semantics from getAdapter(x, IFoo). That's true. I spent hours debugging errors related to the adaption mechanism. The different api's and its differing lookup mechanism is only one piece in the collection of obscurities. Other pieces are caused by different frameworks that using the underlying adaption mechanism: One problem is that sometimes implemented or adapted objects got treated in different way (ex. form-framework: it's modified event notification). Another problem is that an adapted context might not locatable if its adapter does not implement ILocation or does not get location proxied implicitly (ex. local/global security). All those examples and solutions are based on assumptions about implementations and that is causing the adaption-voodoo. Lookup by interfaces and therefore the adaption asserts a higher logical abstraction layer which should encapsulate such implementation details (like adaption-, localisation- and lookup-mechanism) in a *reasonable* way. If code that relies on this abstraction has to differ the underlying mechanism and the kind of the result, it is *necessary* to provide an api that covers those needs - IOW why should the caller care or make voodoo if he gets what he wants? It would be great, if we could handle other adaption-derivations by the proposed unified, reasonable adaption-api too. Example using the IFoo()-syntax: Single adaptation IFoo(a) ... with default IFoo(a, default=y) ... assert location IFoo(a, default=y, locate=True) ... no conform-call IFoo(a, default=y, coform=False) ... force adaptionIFoo(a, default=y, force_adaption=True) ... explicit context IFoo(a, context=specific_context) Multi adaptation IFoo(multi=(a,b)) ... with default IFoo(multi=(a,b), default=y) Named multi adapter IFoo(multi=(a,b), name='z') ... with default IFoo(multi=(a,b), name='z', default=y) ... assert location IFoo(multi=(a,b), default=y, locate=True) Regards, Dominik ___ Zope3-dev mailing list Zope3-dev@zope.org Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com
Re: [Zope3-dev] Re: reasonable syntax for multi-adaptation
Brandon Craig Rhodes wrote: Tres Seaver <[EMAIL PROTECTED]> writes: Martijn Faassen wrote: IFoo.adapt() for normal adaptation IFoo.multiadapt() for multi adaptation I'd rather have 'adapt' take *args for the contexts, and keywords for extras (like name). And you could make the "default=" another possible extra! In which case our proposals at the moment compare something like this: Brandon Utility? IFoo() Single adaptation IFoo(a) ... with default IFoo(a, default=y) Multi adaptation IFoo(multi=(a,b)) ... with default IFoo(multi=(a,b), default=y) Named multi adapter IFoo(multi=(a,b), name='z') ... with default IFoo(multi=(a,b), name='z', default=y) This syntax is pretty comfortable because you get code completion for free if you are using an ide (ex. eclipse pydev). At the moment IFoo() invokes the factory of an object (if registered). IMO the current implementation is a miss-feature because you can't assign any parameters. I would prefer that IFoo() does look up the default utility and IFoo(name='z') the named one. But this change could break existing code. Martijn/Tres Utility IFoo.adapt() Single adaptation IFoo.adapt(a) ... with default IFoo.adapt(a, default=y) Multi adaptation IFoo.adapt(a,b) ... with default IFoo.adapt(a,b, default=y) Named multi adapter IFoo.adapt(a,b, name='z') ... with default IFoo.adapt(a,b, name='z', default=y) Well, I have to admit, yours are a lot prettier. The word "adapt" takes no more characters than my "multi", and parenthesis disappear! And though I might quibble that "adapt()" would be better spelled "utility()", there is a nice symmetry about your idea. - Both patterns make it explicit to anyone reading the code when a default value is being passed, which should vastly reduce surprise. +1 - Mine feels more natural and Pythonic to people who, like PvW in his book, think of adaptation as being like casting. +1 -- Dominik Huber Perse Engineering GmbH Alte Landstrasse 6 CH-4658 Däniken Telefon +41 56 500 01 40 Direkt +41 56 500 01 41 E-Mail [EMAIL PROTECTED] ___ Zope3-dev mailing list Zope3-dev@zope.org Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com
Re: [Zope3-dev] Re: reasonable syntax for multi-adaptation
On Wed, Sep 26, 2007 at 09:09:37PM -0400, Tres Seaver wrote: > Why does the caller care? She just wants an object which will provide > the 'IFoo' contract on behalf of the passed context. If 'x' is capable > of providing 'IFoo' without help, then failing (or worse, returning a > less-specific factory result) when calling 'getAdapter' is the Wrong > Thing (a "least surprise" violation, if nothing else). FWIW it was a big surprise to me when I discovered that IFoo(x) has different semantics from getAdapter(x, IFoo). Marius Gedminas -- C is for Cookies. Perl is even better for Cookies. signature.asc Description: Digital signature ___ Zope3-dev mailing list Zope3-dev@zope.org Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com
[Zope3-dev] Re: reasonable syntax for multi-adaptation
Tres Seaver <[EMAIL PROTECTED]> writes: > Martijn Faassen wrote: > >> IFoo.adapt() for normal adaptation >> IFoo.multiadapt() for multi adaptation > > I'd rather have 'adapt' take *args for the contexts, and keywords > for extras (like name). And you could make the "default=" another possible extra! In which case our proposals at the moment compare something like this: Brandon Utility? IFoo() Single adaptation IFoo(a) ... with default IFoo(a, default=y) Multi adaptation IFoo(multi=(a,b)) ... with default IFoo(multi=(a,b), default=y) Named multi adapter IFoo(multi=(a,b), name='z') ... with default IFoo(multi=(a,b), name='z', default=y) Martijn/Tres Utility IFoo.adapt() Single adaptation IFoo.adapt(a) ... with default IFoo.adapt(a, default=y) Multi adaptation IFoo.adapt(a,b) ... with default IFoo.adapt(a,b, default=y) Named multi adapter IFoo.adapt(a,b, name='z') ... with default IFoo.adapt(a,b, name='z', default=y) Well, I have to admit, yours are a lot prettier. The word "adapt" takes no more characters than my "multi", and parenthesis disappear! And though I might quibble that "adapt()" would be better spelled "utility()", there is a nice symmetry about your idea. - Both patterns make it explicit to anyone reading the code when a default value is being passed, which should vastly reduce surprise. - Mine feels more natural and Pythonic to people who, like PvW in his book, think of adaptation as being like casting. - On the other hand, adaptation is *not* casting, and having to spell out "adapt" really makes for explicit code! And the very natural handling of single or multiple *args in your scheme is very pretty. - My scheme requires the coder to remember that multi-adaption is "done differently" than normal adaption; yours does not. - My scheme, by requiring the magic keyword "multi=", leaves the user in the same dratted danger as before - that he will call IFoo(a, b) and think that he's multiply adapting! Given those last two points, I must abandon my earlier proposal and respond to that of Martijn and Tres with: +1 -- Brandon Craig Rhodes [EMAIL PROTECTED] http://rhodesmill.org/brandon ___ Zope3-dev mailing list Zope3-dev@zope.org Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com
[Zope3-dev] Re: reasonable syntax for multi-adaptation
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Jim Fulton wrote: > On Sep 26, 2007, at 3:37 PM, Dieter Maurer wrote: > >> Jim Fulton wrote at 2007-9-26 15:10 -0400: >>> ... Jim Fulton wrote at 2007-9-26 11:29 -0400: > ... >> IFoo(x) >> IBar(multi=(x,y)) > Actually, that is not the case. If x already provides IFoo, > then in > the first case, the existing object is retuned. Nothing is > instantiated. OTOH, in: > > getMultiAdapter([x], IFoo) > > or > getAdapter(x, IFoo) > > either there is an error or some factory will be called. x > won't be > returned unless the factory happens to return it. Is this not an irrelevant implementation detail? >>> No, the specified behavior is different. >> Hm. But "getAdapter" and "getMultiAdapter" may return "x" as well >> (when the factory decides to do this). >> >> Thus, why is it relevant? > > Because they don't take into account what x already provides. They > will always call some factory. Also, they never call __conforms__. Why does the caller care? She just wants an object which will provide the 'IFoo' contract on behalf of the passed context. If 'x' is capable of providing 'IFoo' without help, then failing (or worse, returning a less-specific factory result) when calling 'getAdapter' is the Wrong Thing (a "least surprise" violation, if nothing else). Tres. - -- === Tres Seaver +1 540-429-0999 [EMAIL PROTECTED] Palladion Software "Excellence by Design"http://palladion.com -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.6 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFG+wLR+gerLs4ltQ4RAuojAJ90QTKCzaEonLYPTqmJ+5SJpz1eDwCgyy4K w59LMYo7ur+GCfEwAy+w5aM= =Weg9 -END PGP SIGNATURE- ___ Zope3-dev mailing list Zope3-dev@zope.org Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com
[Zope3-dev] Re: reasonable syntax for multi-adaptation
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Martijn Faassen wrote: > Hey, > > My opinions: > > It'd be nice if getMultiAdapter's functionality was in reach without > typing: import zope.component; zope.component.getMultiAdapter. The > IFoo() single adapter lookup shows us a way to make this possible: a > method (in this case __call__ on the interface). It does bother me on > occasion that I need to invoke multi adaptation in such an entirely > different way. I must also note that it's a very common intuition to > want to do something like IFoo((a, b)). > > Even though my intuition is usually like Jim's and prefer to have two > different methods, given different semantics, I consider the differences > in semantics here such a grey area I'm on the fence. > > That the object itself is returned if it already provides the interface > in single adaptation is a difference in semantics, The fact that the object may be returened as its own adapter is logically opaque to the caller, who should properly care only that the returned value implements the interface. For exactly the same reason, I think that calling an iterface with an *empty* context list could reasonablly be construed as a 'getUtility' request: the fact that a factory is called for one, and not the other, is irrelevant *to the caller*. > but since there's > just no possibility of doing so in the case of multi adaptation anyway, > you can argue whether this is a difference in semantics or not, just > some semantics that doesn't apply. __conform__ is a bigger difference, > but given that polymorphism abounds in object oriented code, having > different behavior with different inputs is not *that* surprising either. Exactly. > Anyway, if we want to split methods, I'm fine with a properly named > method for multi-adaptation on the interface. For completeness' sake > you'd also want a properly named method on the interface for > single-adaptation. > > IFoo.adapt() for normal adaptation > IFoo.multiadapt() for multi adaptation I'd rather have 'adapt' take *args for the contexts, and keywords for extras (like name). > sound reasonable to me. We then explain that if you call IFoo directly, > IFoo.adapt is called. These could then also be extended to support named > adapter lookup and such. Tres. - -- === Tres Seaver +1 540-429-0999 [EMAIL PROTECTED] Palladion Software "Excellence by Design"http://palladion.com -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.6 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFG+wHp+gerLs4ltQ4RAkyiAJ0biniCdvVIs5vgVCzSm1ISzbWF5QCfQ7FQ iQsVQ0u8q1ZWg2UEGOx43qY= =HlvT -END PGP SIGNATURE- ___ Zope3-dev mailing list Zope3-dev@zope.org Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com
Re: [Zope3-dev] Re: reasonable syntax for multi-adaptation
On Wednesday 26 September 2007 15:51, Derek Richardson wrote: > As a more experienced Zope developer, I never make this mistake. But I > still yearn for a simple syntax that makes multi-adaption as easy as > adaption. While IFoo.adapt() and IFoo.multiadapt() are nice, neither is as > simple as saying: You don't? I do write IFoo(c1, c2) all the time! Regards, Stephan -- Stephan Richter CBU Physics & Chemistry (B.S.) / Tufts Physics (Ph.D. student) Web2k - Web Software Design, Development and Training ___ Zope3-dev mailing list Zope3-dev@zope.org Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com
[Zope3-dev] Re: reasonable syntax for multi-adaptation
To add a novice's perspective: When I first learned Zope, I tried the syntax: adapter = IFoo(context1, context2) It took me hours and the help of Philipp to determine why context2 was being returned. I saw the symmetry between IFoo(context) and a cast in other languages and figured I'd just cast multiple contexts to an adapter. This makes intuitive sense to the newbie. Returning the second argument as the default adapter was strange to me, a seeming violation fo the explicit comparisons to a cast (see the Summary on page 196 of Philipp's book, fourth bullet point). As a more experienced Zope developer, I never make this mistake. But I still yearn for a simple syntax that makes multi-adaption as easy as adaption. While IFoo.adapt() and IFoo.multiadapt() are nice, neither is as simple as saying: adapter = IFoo((context1, context2), default) So, there seem to be advantages here for both the newbie and the experienced developer. Martijn notes the advantage for the experienced; I am noting the "it just does what I expect" simplicity for the newbie. (of course, I'd prefer the cast syntax didn't have a default option at all, so it was really like a cast, but what's done is done). I don't pretend to understand Jim's objections, as I don't have that mastery of the z3 internals. But, I plead for you all to see this from a user's perspective, not from that of the internals. It is expected, for a user, that adapting (context1, context2) would not return context1 as the adapter, even if it already implements the interface, because one is attempting MULTI-adaption. As for what is called internally, as a user of z3, I'm not sure it matters, as long as I get the adapter back that I expect or a default or error otherwise. At the least, I guess, if z3 isn't going to change, the rhetoric of comparing the adaptation syntax to a cast should change, since, to a neewbie, the exceptions are confusing and, in my course of learning, were not clear. Derek On 9/26/07, Martijn Faassen <[EMAIL PROTECTED]> wrote: > > Hey, > > My opinions: > > It'd be nice if getMultiAdapter's functionality was in reach without > typing: import zope.component; zope.component.getMultiAdapter. The > IFoo() single adapter lookup shows us a way to make this possible: a > method (in this case __call__ on the interface). It does bother me on > occasion that I need to invoke multi adaptation in such an entirely > different way. I must also note that it's a very common intuition to > want to do something like IFoo((a, b)). > > Even though my intuition is usually like Jim's and prefer to have two > different methods, given different semantics, I consider the differences > in semantics here such a grey area I'm on the fence. > > That the object itself is returned if it already provides the interface > in single adaptation is a difference in semantics, but since there's > just no possibility of doing so in the case of multi adaptation anyway, > you can argue whether this is a difference in semantics or not, just > some semantics that doesn't apply. __conform__ is a bigger difference, > but given that polymorphism abounds in object oriented code, having > different behavior with different inputs is not *that* surprising either. > > Anyway, if we want to split methods, I'm fine with a properly named > method for multi-adaptation on the interface. For completeness' sake > you'd also want a properly named method on the interface for > single-adaptation. > > IFoo.adapt() for normal adaptation > IFoo.multiadapt() for multi adaptation > > sound reasonable to me. We then explain that if you call IFoo directly, > IFoo.adapt is called. These could then also be extended to support named > adapter lookup and such. > > Since Jim is -0 on his variation, he's not really against it, if someone > else does the work, right? :) > > Regards, > > Martijn > > ___ > Zope3-dev mailing list > Zope3-dev@zope.org > Unsub: > http://mail.zope.org/mailman/options/zope3-dev/derek.richardson%40gatech.edu > ___ Zope3-dev mailing list Zope3-dev@zope.org Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com
Re: [Zope3-dev] Re: reasonable syntax for multi-adaptation
On Sep 26, 2007, at 3:37 PM, Dieter Maurer wrote: Jim Fulton wrote at 2007-9-26 15:10 -0400: ... Jim Fulton wrote at 2007-9-26 11:29 -0400: ... IFoo(x) IBar(multi=(x,y)) Actually, that is not the case. If x already provides IFoo, then in the first case, the existing object is retuned. Nothing is instantiated. OTOH, in: getMultiAdapter([x], IFoo) or getAdapter(x, IFoo) either there is an error or some factory will be called. x won't be returned unless the factory happens to return it. Is this not an irrelevant implementation detail? No, the specified behavior is different. Hm. But "getAdapter" and "getMultiAdapter" may return "x" as well (when the factory decides to do this). Thus, why is it relevant? Because they don't take into account what x already provides. They will always call some factory. Also, they never call __conforms__. Jim -- Jim Fulton Zope Corporation ___ Zope3-dev mailing list Zope3-dev@zope.org Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com
Re: [Zope3-dev] Re: reasonable syntax for multi-adaptation
Jim Fulton wrote at 2007-9-26 15:10 -0400: > ... >> Jim Fulton wrote at 2007-9-26 11:29 -0400: >>> ... IFoo(x) IBar(multi=(x,y)) >>> >>> Actually, that is not the case. If x already provides IFoo, then in >>> the first case, the existing object is retuned. Nothing is >>> instantiated. OTOH, in: >>> >>> getMultiAdapter([x], IFoo) >>> >>> or >>> getAdapter(x, IFoo) >>> >>> either there is an error or some factory will be called. x won't be >>> returned unless the factory happens to return it. >> >> Is this not an irrelevant implementation detail? > >No, the specified behavior is different. Hm. But "getAdapter" and "getMultiAdapter" may return "x" as well (when the factory decides to do this). Thus, why is it relevant? -- Dieter ___ Zope3-dev mailing list Zope3-dev@zope.org Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com
Re: [Zope3-dev] Re: reasonable syntax for multi-adaptation
On Sep 26, 2007, at 3:00 PM, Dieter Maurer wrote: Jim Fulton wrote at 2007-9-26 11:29 -0400: ... IFoo(x) IBar(multi=(x,y)) Actually, that is not the case. If x already provides IFoo, then in the first case, the existing object is retuned. Nothing is instantiated. OTOH, in: getMultiAdapter([x], IFoo) or getAdapter(x, IFoo) either there is an error or some factory will be called. x won't be returned unless the factory happens to return it. Is this not an irrelevant implementation detail? No, the specified behavior is different. Jim -- Jim Fulton Zope Corporation ___ Zope3-dev mailing list Zope3-dev@zope.org Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com
Re: [Zope3-dev] Re: reasonable syntax for multi-adaptation
Jim Fulton wrote at 2007-9-26 11:29 -0400: > ... >> IFoo(x) >> IBar(multi=(x,y)) > >Actually, that is not the case. If x already provides IFoo, then in >the first case, the existing object is retuned. Nothing is >instantiated. OTOH, in: > > getMultiAdapter([x], IFoo) > >or > getAdapter(x, IFoo) > >either there is an error or some factory will be called. x won't be >returned unless the factory happens to return it. Is this not an irrelevant implementation detail? Should I not concentrate on: I get an object related to "x" implementing "IFoo"? -- Dieter ___ Zope3-dev mailing list Zope3-dev@zope.org Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com
[Zope3-dev] Re: reasonable syntax for multi-adaptation
Hey, My opinions: It'd be nice if getMultiAdapter's functionality was in reach without typing: import zope.component; zope.component.getMultiAdapter. The IFoo() single adapter lookup shows us a way to make this possible: a method (in this case __call__ on the interface). It does bother me on occasion that I need to invoke multi adaptation in such an entirely different way. I must also note that it's a very common intuition to want to do something like IFoo((a, b)). Even though my intuition is usually like Jim's and prefer to have two different methods, given different semantics, I consider the differences in semantics here such a grey area I'm on the fence. That the object itself is returned if it already provides the interface in single adaptation is a difference in semantics, but since there's just no possibility of doing so in the case of multi adaptation anyway, you can argue whether this is a difference in semantics or not, just some semantics that doesn't apply. __conform__ is a bigger difference, but given that polymorphism abounds in object oriented code, having different behavior with different inputs is not *that* surprising either. Anyway, if we want to split methods, I'm fine with a properly named method for multi-adaptation on the interface. For completeness' sake you'd also want a properly named method on the interface for single-adaptation. IFoo.adapt() for normal adaptation IFoo.multiadapt() for multi adaptation sound reasonable to me. We then explain that if you call IFoo directly, IFoo.adapt is called. These could then also be extended to support named adapter lookup and such. Since Jim is -0 on his variation, he's not really against it, if someone else does the work, right? :) Regards, Martijn ___ Zope3-dev mailing list Zope3-dev@zope.org Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com
Re: [Zope3-dev] Re: reasonable syntax for multi-adaptation
On Sep 26, 2007, at 11:08 AM, Brandon Craig Rhodes wrote: Jim Fulton <[EMAIL PROTECTED]> writes: On Sep 26, 2007, at 10:04 AM, Brandon Craig Rhodes wrote: Instead, multi-adaption should look like this: IFoo(multi=(obj1, obj2)) IFoo(multi=(obj1, obj2), name='site_foo') Ah, using keyword arguments to get around limitations (especially backward compatibility issues) with the current API is a neat idea. If we were going to do this though, I think a method syntax would be cleaner. As in: IFoo.adapt([ob1, ob2], 'site_foo', None) -1. Unfortunately the singular verb "adapt" makes it look like normal adaptation is what is being called for - it looks here like you are trying to adapt a list to the IFoo interface. Maybe ".multiadapt()"? Note that IFoo(ob) has some special semantics that don't apply to the multi- or named-adapter case. Agreed! The semantics are different. But mightn't we simply document this difference between single- and multi-adaptation everywhere we need to, rather than letting it force us into splitting the adapter syntax into two unwieldy pieces? I don't consider either unwieldy. ... So, I am not sure that I see yet the problem with "mixing APIs". The semantics of the call would change in fundamental ways based on the arguments passed. I think this is very bad. If you disagree, sorry. :) For me, the essential issue is that in both single- and multi- adaptation you are returned an instance of an adapter that has been instantiated with the objects you are adapting. Both of these syntaxes: IFoo(x) IBar(multi=(x,y)) Actually, that is not the case. If x already provides IFoo, then in the first case, the existing object is retuned. Nothing is instantiated. OTOH, in: getMultiAdapter([x], IFoo) or getAdapter(x, IFoo) either there is an error or some factory will be called. x won't be returned unless the factory happens to return it. ... An added complication is that interfaces don't provide adaption directly, but via a hook. The existing hook api wouldn't work for mult or named adaptation, so a new hook would be needed. I had assumed that IBar(multi=(obj1, obj2)) would simply dispatch to the existing getMultiAdapter() call; how, exactly, would hooks get involved and complicate things? Feel free to just cite a line number and tell me to go read, all I need is a pointer to get started understanding this. zope.interface does *not* depend on zope.component. It only does adaptation the way it does because it provides a hook that zope.component fills. Other people are using zope.interface with different adaptation schemes. Adding multi- or named- adaption support would require a similar hook. I don't really have time to continue this discussion. You made a reasonable proposal, but for various reasons I've tried to explain, I don't support it. Jim -- Jim Fulton Zope Corporation ___ Zope3-dev mailing list Zope3-dev@zope.org Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com
[Zope3-dev] Re: reasonable syntax for multi-adaptation
Jim Fulton <[EMAIL PROTECTED]> writes: > On Sep 26, 2007, at 10:04 AM, Brandon Craig Rhodes wrote: > >> Instead, multi-adaption should look like this: >> >> IFoo(multi=(obj1, obj2)) >> IFoo(multi=(obj1, obj2), name='site_foo') > > Ah, using keyword arguments to get around limitations (especially > backward compatibility issues) with the current API is a neat idea. > If we were going to do this though, I think a method syntax would be > cleaner. As in: > > IFoo.adapt([ob1, ob2], 'site_foo', None) -1. Unfortunately the singular verb "adapt" makes it look like normal adaptation is what is being called for - it looks here like you are trying to adapt a list to the IFoo interface. Maybe ".multiadapt()"? > Note that IFoo(ob) has some special semantics that don't apply to > the multi- or named-adapter case. Agreed! The semantics are different. But mightn't we simply document this difference between single- and multi-adaptation everywhere we need to, rather than letting it force us into splitting the adapter syntax into two unwieldy pieces? I would not imagine that I would be confused encountering documenting that said: Call IFoo(x) to adapt a single object "x" to the IFoo interface, and IBar(multi=(x,y)) to have the adapter registry find and invoke a multi-adapter that adapts the pair of objects "x" and "y" to the IBar interface. When performing single adaptation, the object "x" itself is simply returned if it already offers the IFoo interface; and if the object offers a __conform__ method, then this is called with the IFoo interface as its argument in place of the normal adaptation machinery. So, I am not sure that I see yet the problem with "mixing APIs". For me, the essential issue is that in both single- and multi- adaptation you are returned an instance of an adapter that has been instantiated with the objects you are adapting. Both of these syntaxes: IFoo(x) IBar(multi=(x,y)) suggest this fact, even to the novice Python programmer, because they make it look like something is being instantiated with the arguments given, and returned. Doesn't the benefit of such clarity and symmetry outweigh whatever slight awkwardness might exist in the sort of documentation I suggested above? > An added complication is that interfaces don't provide adaption > directly, but via a hook. The existing hook api wouldn't work for > mult or named adaptation, so a new hook would be needed. I had assumed that IBar(multi=(obj1, obj2)) would simply dispatch to the existing getMultiAdapter() call; how, exactly, would hooks get involved and complicate things? Feel free to just cite a line number and tell me to go read, all I need is a pointer to get started understanding this. -- Brandon Craig Rhodes [EMAIL PROTECTED] http://rhodesmill.org/brandon ___ Zope3-dev mailing list Zope3-dev@zope.org Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com