[Types-sig] QueryProtocol

Clark C. Evans cce@clarkevans.com
Fri, 23 Mar 2001 01:20:05 -0500 (EST)

On 22 Mar 2001, Marcin 'Qrczak' Kowalczyk wrote:
> > this distinction between "declarative, I am a such-and-such" vs
> > "descriptive, It looks like a such-and-such"  
> Actually my view can be declarative too. It is stolen from Haskell
> where it *is* declarative.

By declarative, I am talking about the class "declaring" it's
compliance with an interface, "I am a such-and-such".   

By descriptive, I am talking about an interface figuring
out that a class is compliant by examining it, "It looks like 
a such-and-such".   I suppose you could define a declarative
syntax whereby an interface can specify that a given 
class complies... but this is beside the point.

> It's more about not specifying interfaces at the point of a class
> definition than about the method of their specification and checking.

Exactly, and this is what I was trying to convey:

   declare     -> The class C declares: "I implement interface I".

   descriptive -> The interface describes what it needs 
                  for a class to be compliant.  Then, later
                  a checking mechanism (perhaps using the
                  Interface itself) looks at the description,
                  looks at the class and exclaims:
                  "Upon examination of the methods, attributes,
                   signature and other information available 
                   regarding the class C, it does indeed
                   comply with the interface description."

For give my poor english ability at choosing words....

> It was an opposition to someone suggesting that a class should be
> immediately associated with the interface it implements.

Yes.  I read the entire thread and I quoted you beacuse 
I think the perspective you brought was very very helpful.

> Since in Python everything happens at runtime and everything is
> passed by reference, interface+class associations can be created
> outside interfaces and classes but stored inside them. Either the
> interface or the class may hold them. It depends whom we will ask
> whether a class conforms to an interface and from where we will get
> the implementation of methods specified in the interface.

IMHO, they belong in three places; the class (if it declares it's
complance with an interface), the interface (if the interface
can deduce that the class complies with the interface description),
and perhaps third parties who know better!
> IMHO they belong more to interfaces than to classes. Types and classes
> would be registered in interface objects, not vice versa.

Yes, and the whole point of the contrast that I brought out
is that I assert that neither policy by itself is adeqate
and I belive that they are probably complementary.

> An interface can specify a combined requirement about 
> a tuple of classes. Properties
> can be added to classes but not to types. We already have dispatching
> on the object side, namely plain methods. So it's time for something
> completely different.

Right.  I agree, and if you look at the proposal I'm putting
forth, it allows for your method (with the sole problem that
Interface is not well defined).  

> The decision about the level of checking of the conformance, and
> details of dispatching, are up to the interface object.

No.  The decision about conformance should be up to
the class or the interface (or possibly even the environment).

> An interface can fail when a class was not explicitly registered.
> Another interface will be more liberal and try to deduce the details
> of conformance basing on properties of objects, e.g. whether they have
> attributes of some names.

Right.  And when we have an Interface class (or static methods
which could suffice just fine), these types of choices
can be made using the proposal I put forth without loss
of flexibility.

> It's not very clear for me yet how an interface definition would
> look like. It's hard to apply the Haskell's solution without having
> the rest of the type system. It must somewhat specify patterns of
> types of methods in terms of the classes for which instances are
> declared. Something like this for a sequence with concatenation,
> ignoring the fact that element types are completely unspecified:
>     interface Sequence(S):
>         def getitem(S, Int)
>         def len(S)
>         def concat(S, S) # Arguments are symmetric. The choice of S
>                          # for a particular usage of Sequence.concat
>                          # is deduced from both.

>         #def empty() # This doesn't work: there is no S to dispatch on.
>                      # It works in Haskell where it's enough to dispatch
>                      # on the type of the return value, because it's done
>                      # statically.

Well, if you said that an interface is a type
of module, you can have static methods...

>     # A function which uses the Sequence interface in a generic way:
>     def join(*args):
>         return reduce(Sequence.concat, args)
>         # I would like to say:
>         #     return reduce(Sequence.concat, args, empty())
>         # The empty() case doesn't work. It won't work in current Python
>         # because the empty list of strings is indistinguishable from
>         # the empty list of integer lists.

Lost me here...

Thank you for the feedback.  If I quoted you incorrectly, I 
apologise profusely, although I am pretty sure that I *do*
understand your perspective; even if I don't totally agree.