Movatterモバイル変換
[0]ホーム
PEP 245
Alex Martellialeaxit at yahoo.com
Tue Apr 3 06:23:40 EDT 2001
"Alex Shindich" <shindich at itginc.com> wrote in messagenews:mailman.986255463.27488.python-list at python.org...> >in C++, one normally uses _private_ inheritance for this specific purpose> There is nothing private in Python. There is "__" name mangling of course,> but that is it.Exactly. In particular, '__' name mangling does not apply to inheritance.> But your point is well taken. Code reuse should not be mixed with class's> interfaces. Still, in C++ multiple inheritance is used as the simplest for> of interface implementation, and abstract classes with only virtualmethods> can be treated as interfaces.Yes: C++ sort-of-confuses "I implement an interface" and "I convenientlyuse [some part of] a class in my own implementation" under the singlerubric of 'inheritance' -- pretty bad in itself, and the distinctionbetween public and private inheritance is a helpful band-aid given thisconfusion. Better, of course, not to have the confusion at all. InPython, we also lack the band-aid, so it's _particularly_ important toavoid confusing these two concepts -- both important, but quite distinct.> >COM, per se, has no concept of 'compile time' either. Among thelanguages> >best supporting COM are some (such as Python:-) which do very little, if> >anything, "at compile time".> OK. That is partially true. If a COM component is implemented usingmultiple> inheretence, then C++ compiler will force you to implement all theinterfaceCOM does not mandate that a C++ compiler is used, nor does it haveanything to say regarding HOW such a compiler (or one for anotherlanguage, such as Eiffel) be used to implement COM objects -- aslong as certain binary layouts are obtained, and various semanticsrules are respected, COM couldn't care less about HOW this isbrought about, nor WHEN (COM has *NO* concept of "compile time").> methods. If agregation, composition, or flyweights are used, then there is> no compile time safety.You seem to be labouring under the misconception that "COM" means"some specific COM implementation I have in mind, based on a certainspecific usage of some kind of C++ compiler". This is simply notthe case. You were talking about confusion being engendered byinterfaces bereft of compile-time checks among programmers who are"familiar with COM". I insist that, if such programmers ARE indeedwell-versed in COM itself, lack of compile-time checking is absolutelynothing new for them. People who wrongly _believe_ they understandCOM (perhaps because they have let themselves be guided by 'wizards'to effect one possible COM implementation strategy out of the manyzillions that are feasible [and potentially important]) may possiblyhave one little extra nugget of confusion added to the considerableamount thereof they already labour under, but in any case they arealready sufficiently befuddled that the only viable strategy is tohelp them clear up their original confusion -- there isn't much thatPython, per se, can do about that.> >In Python's case, we don't share the needs and design constraints which> >led to COM's rules (proxying, marshaling...), so there is no need to> >impose identity-constraints and the resulting complications (even today,> >Python allows an object to keep identity BUT change behavior, e.g. by> >changing its __class__). But that has really nothing to do with> >compile-time vs run-time.> I see identity constraints as philosophical issue.There are more things in heaven and earth, Mr Shindich,Than are dreamt of in your philosophy._I_ (and the designers of COM) see identity constraints as highlypragmatical issues that ensure certain proxying and marshalingstrategies (and, more generally, certain client-side choices foraccess and usage) will work -- constraints on object implementersfor the benefit of optimizations in the COM infrastructure (and,to a lesser degree of importance, for the benefit of client-sidecoders; e.g., the "reflexivity" of QI ensures client-code canchoose to hold a single pointer to a certain interface on a givenobject, and will always be able to QI back to other interfaces atneed, rather than needing to use some specific 'privileged itf'for such purposes). Different sets of constraints might also work,enabling different strategies from client-side, implementer-side,and infrastructure, with different performance tradeoffs, but itis important to have SOME set of very precise ground-rules for"object identity", so that client-code, implementation-code, andinfrastructure-code, each written in very diverse languages, canall work together in harmony (I happen to believe that the veryset chosen by the COM designers is the ideal one for the usecases _they_ were considering -- local, in-process, and fast-response-LAN client/server usage -- but, change the use cases,and the tradeoffs shift... and so does the optimal definitionof object-identity rules, cfr. for example the .NET choices).> To me an interface means> a contract by wich both a component and the client code live. All I amThat's quite a different issue -- the COM identity-semanticsconstraints have nothing much to do with programming-as-contracting(you can't even specify pre- and post-conditions in COM's ownterms), nor does p-as-c imply (e.g.) that two calls to QIwith the same parameters must both fail or both succeed (andreturn the same result in the very specific case where theinterface ID being requested is IID_IUnknown, but without thesame constraint in other cases).> saying is that the proposed definition is to vague, and I don'tparticularly> care for it. To me the definition of an interface that only guarantees the> fact that a class will have attributes with particular names of type"bound> function" is handicapped and useles!The extra guarantee that the methods' signatures also matchis not significant added value, though -- and THAT is allthat any language in the world ever buys you at compiletime (if even that -- add any kind of co-variance, which bothEiffel and Java offer in different forms [Java has it forarrays], and you're back to runtime checking _even justfor "type-safety"_...!!!).That may be extremely irking to you on a philosophical plane,but there is really no way to check up "at compile time" onany of the kind of semantical constraints we're truly mostinterested in -- they're not mere syntacticalities (methodnames or signature), but always deeper ones, requiring theuse of existential and universal quantifiers in all cases ofreal interest... which makes them impractical to check at\ANY time in production code/runs.E.g., we have a method which takes two collections, and theconstraint may be that every integer in the former exactlydivides (with no remained) every integer in the latter. Nocompiler known to man or beast will ever check THAT for you,and, even at runtime, the O(M*N) cost of the check makes itimpractical to perform (except in runs specifically devotedto testing purposes, i.e., not "production" runs).Or, take the semantic constraints on a predicate that canbe used for ordering in the C++ Standard Library ('weakpartial ordering'): P is an acceptable parameter iff...: -- for any x, not P(x,x) -- for any x, y, P(x,y) implies not P(y,x) -- for any x, y, z, P(x,y) and P(y,z) imply P(x,z)I doubt anybody even DREAMS of a compiler able to checksuch constraints (or, of really checking them at runtime,exhaustively, even in the most aggressive unit-testingstrategy -- at most, they'll be checked on a few samplevalues of x, y, z).Does this make _every_ language in the world "handicappedand useles"? A philosopher could take such a stance, sure.A _pragmatical_ person, on the other hand, takes into dueaccount these limitations _and still documents these kindsof constraints_ as formally as feasible given whatevertechnology is at hand. (The same goes for _performance_semantics constraints, such as the C++ Standard Librarywidely introduces: no way to enforce them, or have any sortof _guarantee_, but that doesn't mean they don't still playa *crucial* role in determining library usage and design!).> >I see nothing in the interface-adaptation PEP that can be said to> >be borrowed from other languages (even if one counted COM as "a> >language", which of course it isn't -- it's an object-model> To be precise "Component Object Model".> >, which> >can be, and is, implemented by a huge variety of languages), and> >most particularly nothing that somehow depends on 'staticity' vs> >Python's 'dynamism'.> Oh, Lord! Leave the COM alone. Why don't you talk about similarities with> Java?Because YOU mentioned COM -- a very interesting and hugely successfuldesign for a cross-language object-model, which succeeds in good partby doing the very OPPOSITE of what you SAID it was doing [the idea oftaking COM as an EXAMPLE of "compile-time" was particularly hilariousto a COM expert, and I wanted to share the mirth:-)... and possiblyhelp dispell some misconceptions].I'm not particularly interested in Java's object-model in this context,nor does my Java expertise reach anywhere near the extent of that onCOM (I _have_ studied the sources of typical JVM's, of course, but Idon't think I could implement one without substantial refreshing ofsuch studies, for example). The misconceptions regarding Java appearto be less widespread and less pernicious (few know about the specifichole that arrays introduce in its purported compile-time type-safety,but that's a rather specific issue; in practical Java use, a Vectoris used instead of an array, and *THAT* is *OBVIOUSLY* not compile-timetype-safe since ANY object can be stuffed into it -- it doesn't takemuch Java knowlegde to point this out:-).> And in my mind, the notion of the interface is far more valuable for> staticaly types languages, component models, what have you. And couldpleaseThe notions of interface and contract are extremely useful in allkinds of software _design_ -- they are primarily design-tools, andonly secondarily coding-ones. And whoever thinks that a good designis less valuable when a dynamically-typed language, rather than astatically-typed one, is to be used for the coding, needs far morereprogramming than I can supply:-).> somebody explain to me what advantages the proposed PEP give us oversimple> documentation.Formalizing the concept of interfaces avoids the horrid ambiguitiesthat current documentation mentioning informal 'interfaces' brimswith. Any time some docs mention 'a file-like object' you neverknow WHAT the component needs form the object -- just .write, oralso .writelines, or perhaps .read, or .readlines, or...??!?! Andwhenever a 'sequence' is mentioned, you never know whether youneed to supply a __length__ (or just a suitable __getitem__) andwhether that __length__, if it does have to be present, can bepurely indicative or must be exactly correct. Just to mention twoout of many, many such issues.> BTW. Alex, you mentioned that Python supports COM well... As you can see> interface support could be implemented using existing language constructs.If you include C-coded extensions among the "existing languageconstructs" of Python, then, yes, I cannot think of ANYTHINGthat cannot be _implemented_ using them. There may be no clearway of _expressing_ what is going on in Python, when enough ofthe crucial stuff is hidden in a C-coded extension (have you*studied* the current [and excellent] implementation of the COMsupport, on both the C-coded and Python-coded sides...?!-).Alex
More information about the Python-listmailing list
[8]ページ先頭