Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Re^4: OO-style modifiers for 'sub' ?

by adrianh (Chancellor)
on Jan 31, 2003 at 22:38 UTC ( #231748=note: print w/ replies, xml ) Need Help??


in reply to Re: Re^2: OO-style modifiers for 'sub' ?
in thread OO-style modifiers for 'sub' ?

I've coded C++ and grok templates. They solve some problems quite neatly, bearing in mind C++'s design focus on efficiency.

The thing you lose by having templates like the above is an explicit representation of the classes contract. You have the developer saying "<" has the same semantics in all of the classes involved - rather than it being enforced by the type system. Yes, there is no comparable interface - and that's a mistake.

So, to answer you question:

What advantage would be gained by requiring an explicit interface?

The advantage of having an explicit interface is - that you have an explicit interface :-) By saying something belongs to a particular class you are saying that it functions in a certain way, that it forfills a given contract.

I might have a class with a method set_pitch(N). If its a subclass of MusicalInstrument I know N is Hertz. If its a subclass of aircraft I know N is degrees. Statements about an objects class stop me doing the wrong thing to the wrong object.

Templates are handy in C++ but they're not really relevent to perl since it's not statically typed.

They're also not the only solution to genericity with static typing. For example, Eiffel's generic classes allow more sophisticated statements about inheritance to be made so you can say things like:

class SORTED_LIST [G -> COMPARABLE]

(you can only make SORTED_LISTs out of things that are COMPARABLE).


Comment on Re^4: OO-style modifiers for 'sub' ?
Download Code
Re^5: OO-style modifiers for 'sub' ?
by dpuu (Chaplain) on Feb 01, 2003 at 00:37 UTC
    OK, I'll admit that I went of at a bit of a tangent there. But since we're here, let me refute your example: an interface named "PitchControl" would be no less ambiguous than a method named "set_pitch". We can't use the ambiguity argument to support explicitly named interfaces.

    But you are right. The discussion shouldn't be about whether it is valid to infer an interface from the body of the implementation of a client (a la templates): its about whether it is valid to infer an interface from the functions supported by an object. That is: we're talking about the dependency structure:

    interface Foo { method fn (...); } class Bar : isa Foo { method fn (...) {...} }
    Vs
    class Bar { method fn (...) {...} } interface Foo { require method fn (...); }
    The second example states that an object implements the interface if it supports a specific set of methods. It says: "if it looks like a duck, and quacks like a duck, and walks like a duck: then lets assume that it is a duck".

    In both cases, the interface is made explicit. Client code can be written to require an object that implements a specific interface: the interface is explicit from the client's point of view. The binding between the object and the interface is also explicit, but the direction of the dependency is different.

    But your original question still stands: why would we want to break the explicit dependency between the class definition and an interface?

    Imagine you have a blob of 3rd party code that has an overly fat interface. You can't modify this code (e.g. you're not sysadmin). You want to use these blobs in you own code, which uses a much thinner version of the same interface. You want to validate your input (i.e. does the input object implement your thin interface) without modifying the source code of an object that implements the fat interface.

    fanfare: Inferred Interfaces to the rescue! --Dave

      OK, I'll admit that I went of at a bit of a tangent there. But since we're here, let me refute your example: an interface named "PitchControl" would be no less ambiguous than a method named "set_pitch". We can't use the ambiguity argument to support explicitly named interfaces.

      Sorry - obviously wasn't being clear. I wasn't proposing a PitchControl interface. I was just pointing out that the method name isn't enough. The method would be part of the "interfaces" of MusicalInstrument and Aircraft, which are not ambiguous.

      In both cases, the interface is made explicit. Client code can be written to require an object that implements a specific interface: the interface is explicit from the client's point of view. The binding between the object and the interface is also explicit, but the direction of the dependency is different.

      I think we have different definitions of "interface". To me it includes the implied contract of the class, so:

      interface Aircraft { method set_pitch (...); } class Jet : isa Aircraft { method set_pitch (...) {...} }

      is saying a very different thing from:

      class Jet { method set_pitch (...) {...} } interface FlyingThings { require method set_pitch (...); }

      since:

      class Piano { method set_pitch (...) {...} }

      isn't an Aircraft, but is a FlyingThing.

      Imagine you have a blob of 3rd party code that has an overly fat interface. You can't modify this code (e.g. you're not sysadmin). You want to use these blobs in you own code, which uses a much thinner version of the same interface. You want to validate your input (i.e. does the input object implement your thin interface) without modifying the source code of an object that implements the fat interface.

      Dealing with code you can't alter is once case where I can see it being useful (as I briefly mentioned in another thread).

      That's one way of doing it certainly. But the information that ThinInterface is a subset of ThickInterface is lost. All you are saying is that they have the same method names - not that those methods do the same "things" to the same kind of objects.

      While it might be a useful hack - that's what it is. You are deliberately subverting the isa hierarchy because you can't express the relationship that you want to express directly. It's something that should be used very carefully since it subverts (in my opinion) what OO is all about.

      There are also other ways of getting round the problem. For example, if you have multiple inheritance you could declare a subclass ThickThin of ThickInterface that isa ThinInterface, and use the subclass where you would have used ThickInterface objects.

      ThickInterface ThinInterface \ / ThickThin

      With perl you can do even do ghastly things like:

      unshift @ThickInterface::ISA, 'ThinInterface';

      to make ThickInterface a ThinInterface retrospectively :-)

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://231748]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (9)
As of 2014-12-20 21:16 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (99 votes), past polls