Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Protocols

7 views
Skip to first unread message

Luke Palmer

unread,
Jul 19, 2003, 7:25:34 AM7/19/03
to perl6-l...@perl.org
I've been looking around Objective-C a bit, and I would like to turn
over an old rock.

Remember when I suggested that (static) type equivalence should be
based on interface equivalence? Objective-C seems to feel the same
way. It calls an interface a I<protocol>, and specifying it is
optional. This maps nicely into Perl's distinction between typed an
untyped variables.

In Objective-C:

id untyped = somefunction();
id<Foo> typed = otherfunction();

If you send a message to C<typed> which isn't in the C<Foo> protocol
definition, you get warnings. Depending on the implementation, that
assignment might be dynamically interface-checked.

Objective-C had one difference from my proposal, which, upon reading
it, I like. There is a distinction between a real object and a
protocol. You can supply the name of a class, and the object has to
(well, as much as anything I<has to>) be a real object of that class.
If you supply the name of a protocol, its interface just has to
conform.

Objective-C makes a lexical distinction on the user side, which I
don't think is so Perlish.

So, here's my new proposal.

my Type $x = func();
$x.meth;

First, C<Type> is allowed to be both an interface (my name for
I<protocol>) and a class, even at the same time. When checking, the
interface takes precedence, but that can be overridden with some
trait.

At compile time, if func() has a visibly declared return value, it is
checked against C<Type>. If C<Type> is an interface, then func()'s
return type is checked to make sure that it supports all methods that
C<Type> declares. If C<Type> is a real class and func() is a real
class, they are checked for family relationship. Finally, if C<Type>
is a real class and func() is an interface, checking is deferred until
runtime (with a warning under some pragmatic setting).

Then, still at compile time, C<Type> is checked to make sure it
provides C<meth>.

At runtime on the first statement, no checking needs to be done if
C<Type> is an interface (unless func() didn't explicate a return
type). If C<Type> is real, a family relationship test is done.

And that's all. It's very lenient, but it catches most of the errors
any Java-like type system[1] would catch, hopefully without getting in
the way.

And to make type checking even less explicit, there might be a feature
which would scan (as much as possible) the body of a function and
generate interfaces for the variables in the signature based on how
you use them. That would be neat.

Luke

[1] It would be totally cool to use a Haskell- or ML-style type
inference system, but those things just don't work in procedural
languages.

Steffen müller

unread,
Jul 19, 2003, 9:00:08 AM7/19/03
to perl6-l...@perl.org
Luke Palmer wrote:
[...]

> [1] It would be totally cool to use a Haskell- or ML-style type
> inference system, but those things just don't work in procedural
> languages.

And they're very slow when not done at compile-time. Try a Haskell
interpreter like hugs vs. a Haskell compiler like ghc.

Steffen
--
@n=([283488072,6076],[2105905181,8583184],[1823729722,9282996],[281232,
1312416],[1823790605,791604],[2104676663,884944]);$b=6;@c=' -/\_|'=~/./g
;for(@n){for$n(@$_){map{$h=int$n/$b**$_;$n-=$b**$_*$h;$c[@c]=$h}reverse
0..11;push@p,map{$c[$_]}@c[reverse$b..$#c];$#c=$b-1}$p[@p]="\n"}print@p;

Sean O'Rourke

unread,
Jul 19, 2003, 12:44:26 PM7/19/03
to Luke Palmer, perl6-l...@perl.org
On 19 Jul 2003, Luke Palmer wrote:
> [1] It would be totally cool to use a Haskell- or ML-style type
> inference system, but those things just don't work in procedural
> languages.

Could you clarify what you mean by "don't work" here? ML has both
assignment and type inference, so it seems like it's at least possible
to do this; O'Caml generates some pretty fast code, too, so it seems
like it can be practical as well. Of course, perl6's being _dynamic_
may sink this, but its being _procedural_ doesn't seem like it would
pose a problem.

/s

Chromatic

unread,
Jul 23, 2003, 8:57:22 PM7/23/03
to Luke Palmer, perl6-l...@perl.org
On Saturday, July 19, 2003, at 04:25 AM, Luke Palmer wrote:

> In Objective-C:
>
> id untyped = somefunction();
> id<Foo> typed = otherfunction();
>
> If you send a message to C<typed> which isn't in the C<Foo> protocol
> definition, you get warnings. Depending on the implementation, that
> assignment might be dynamically interface-checked.

This is even nicer in function signatures, where accidental
polymorphism is an amazingly nice thing. If saying:

# quite possibly broken syntax
method debug ( String $s )
{
print $s.to_string;
};

really means 'String or a derived class', you're missing out on things
that support &to_string.

That's really the fault of whoever wrote this method, but I'd prefer
the language guide people to make better decisions.

Now on to the implementation.

Inheritance feels like the wrong way to mark interface equivalence.
Take, for example, an object that combines a FloorWax and a
DessertTopping. Delegation's the way to go here, but if I have to
inherit from both FloorWax and DessertTopping to signify that the
object (somehow) implements both protocols appropriately, there are
subtler problems remaining. It might inherit behavior from a common
ancestor to both classes and then there's a diamond pattern.

Inheritance answers two questions. First, how does this class relate
to other things I know about? Second, where do instances of this class
get behavior?

The first is a deeper question -- besides inheritance, there's
delegation, aggregation, and reimplementation (think mock objects) that
can make two classes have equivalent interfaces. I'd like some way to
mark this equivalence *without* having to inherit from an abstract base
class and I wish that interface equivalence were checked before
inheritance, as per Luke's idea.

Class::ActsLike does something similar in Perl 5.

-- c

David Wheeler

unread,
Jul 24, 2003, 11:49:15 AM7/24/03
to chromatic, Luke Palmer, perl6-l...@perl.org
On Wednesday, July 23, 2003, at 05:57 PM, chromatic wrote:

> The first is a deeper question -- besides inheritance, there's
> delegation, aggregation, and reimplementation (think mock objects)
> that can make two classes have equivalent interfaces. I'd like some
> way to mark this equivalence *without* having to inherit from an
> abstract base class and I wish that interface equivalence were checked
> before inheritance, as per Luke's idea.

Sounds like you want Java-style "interfaces" to me.

Regards,

David

--
David Wheeler AIM: dwTheory
da...@kineticode.com ICQ: 15726394
http://kineticode.com/ Yahoo!: dew7e
Jabber: The...@jabber.org
Kineticode. Setting knowledge in motion.[sm]

David Wheeler

unread,
Jul 24, 2003, 12:28:27 PM7/24/03
to Kurt Starsinic, chromatic, Luke Palmer, perl6-l...@perl.org
On Thursday, July 24, 2003, at 09:25 AM, Kurt Starsinic wrote:

>> Sounds like you want Java-style "interfaces" to me.
>

> Follow the thread back. Objective-C had them way first, and their
> ur-name is "protocols."

D'oh! Sorry, I had read that, but then forgot.

Chromatic

unread,
Jul 24, 2003, 12:45:33 PM7/24/03
to David Wheeler, perl6-l...@perl.org
On Thursday, July 24, 2003, at 08:49 AM, David Wheeler wrote:

> On Wednesday, July 23, 2003, at 05:57 PM, chromatic wrote:
>
>> The first is a deeper question -- besides inheritance, there's
>> delegation, aggregation, and reimplementation (think mock objects)
>> that can make two classes have equivalent interfaces. I'd like some
>> way to mark this equivalence *without* having to inherit from an
>> abstract base class and I wish that interface equivalence were
>> checked before inheritance, as per Luke's idea.
>
> Sounds like you want Java-style "interfaces" to me.

No, I think Java interfaces are a kluge to get around copying a broken
type system and the lack of multiple inheritance.

I don't want to litter both the caller and the callee with interface
declarations that do nothing but say "this thing here understands the
same methods as that thing there". The caller, fine -- that's the
place it belongs.

If I have to modify the callee to do this, I've insufficient
polymorphism.

Think of it this way. If you write Perl 5 code like this:

sub some_method
{
my $self = shift;
die "Bad object" unless ref $self = 'Some::Class';
# do something useful...
}

someone will have to change or override some_method() if he wants to
subclass it. You could make his life a little easier by writing:

sub some_method
{
my $self = shift;
die "Bad object" unless $self->isa( 'Some::Class' );
# do something useful...
}

I'm suggesting to go the next step and let the code say, "Hey, if it
acts like an instance of Some::Class, I don't care where it gets its
behavior. I'll treat it like an instance of Some::Class." That's what
I do with Class::ActsLike, and that's what I'd like to see here:

sub some_method
{
my $self = shift;
die "Bad object" unless $self->acts_like( 'Some::Class' );
# do something useful...
}

Now it doesn't care whether I've inherited, aggregated, delegated, or
reimplemented. My argument is that it shouldn't have to care. It
should only care that I've somehow promised that what I'm passing in
behaves like it expects it to behave. How it does that is
uninteresting.

-- c

Austin Hastings

unread,
Jul 24, 2003, 2:17:20 PM7/24/03
to chromatic, perl6-l...@perl.org

--- chromatic <chro...@wgz.org> wrote:
> On Thursday, July 24, 2003, at 08:49 AM, David Wheeler wrote:
>
> > On Wednesday, July 23, 2003, at 05:57 PM, chromatic wrote:
> >
> >> The first is a deeper question -- besides inheritance, there's
> >> delegation, aggregation, and reimplementation (think mock objects)
>
> >> that can make two classes have equivalent interfaces. I'd like
> some
> >> way to mark this equivalence *without* having to inherit from an
> >> abstract base class and I wish that interface equivalence were
> >> checked before inheritance, as per Luke's idea.
> >
> > Sounds like you want Java-style "interfaces" to me.
>
> No, I think Java interfaces are a kluge to get around copying a
> broken type system and the lack of multiple inheritance.

Multiple Inheritance != Protocols | Interfaces

How much C++ code have you seen with "unused" stuff in the objects
because "I had to inherit from that class to get the MI behavior I
wanted, but I no longer use those attributes."

Protocols/Interfaces is a way of saying "My structure is none of your
damn business, but I comply with the rules you've set."

MI, on the other hand, can be implemented with a protocol and a has-a
relationship, albeit at a significant cost in coding dispatch methods.

There's an argument for supporting both.

class Foo is all(DessertTopping, FloorWax) {
}

> I don't want to litter both the caller and the callee with interface
> declarations that do nothing but say "this thing here understands the
> same methods as that thing there". The caller, fine -- that's the
> place it belongs.

I disagree, and I hope you've simply swapped terms around.

I think you want to declare "I comply with ruleset X" at the callee
object level. That enables the compiler to (1) check that you're not
lying; and (2) optimize based on (1).

> If I have to modify the callee to do this, I've insufficient
> polymorphism.

At the "caller" side, you want to say "I require something which
complies with ruleset X" and have it be enforced to a user-configurable
extent.

Obviously calling a method which doesn't exist should be an error. But
(especially in large systems) it should be possible to slack off on the
call-side checking, because you know you're doing the checking on the
callee side at compile time.

> Think of it this way. If you write Perl 5 code like this:
>
> sub some_method
> {
> my $self = shift;
> die "Bad object" unless ref $self = 'Some::Class';
> # do something useful...
> }
>
> someone will have to change or override some_method() if he wants to
> subclass it. You could make his life a little easier by writing:
>
> sub some_method
> {
> my $self = shift;
> die "Bad object" unless $self->isa( 'Some::Class' );
> # do something useful...
> }
>
> I'm suggesting to go the next step and let the code say, "Hey, if it
> acts like an instance of Some::Class, I don't care where it gets its
> behavior. I'll treat it like an instance of Some::Class." That's
> what
> I do with Class::ActsLike, and that's what I'd like to see here:
>
> sub some_method
> {
> my $self = shift;
> die "Bad object" unless $self->acts_like( 'Some::Class' );
> # do something useful...
> }
>

I notice all this is on the callee side. I'm hoping you swapped er/ee
above.

> Now it doesn't care whether I've inherited, aggregated, delegated, or
> reimplemented. My argument is that it shouldn't have to care. It
> should only care that I've somehow promised that what I'm passing in
> behaves like it expects it to behave. How it does that is
> uninteresting.

I agree. Luke agrees. The extent to which this is formalized is open
for discussion, but I think Damian doesn't agree (see his example some
time back about class Dog vs. class Tree).

=Austin

Chromatic

unread,
Jul 24, 2003, 3:26:40 PM7/24/03
to Austin_...@yahoo.com, perl6-l...@perl.org
On Thursday, July 24, 2003, at 11:17 AM, Austin Hastings wrote:

>> No, I think Java interfaces are a kluge to get around copying a
>> broken type system and the lack of multiple inheritance.
>
> Multiple Inheritance != Protocols | Interfaces

I quite agree, but I've done enough Java to know that if they could
have "solved" it with MI, they would have.

> Protocols/Interfaces is a way of saying "My structure is none of your
> damn business, but I comply with the rules you've set."

Yes, exactly.

> I disagree, and I hope you've simply swapped terms around.
>
> I think you want to declare "I comply with ruleset X" at the callee
> object level. That enables the compiler to (1) check that you're not
> lying; and (2) optimize based on (1).

At least one of us is using "caller/callee" in the X11 sense. What I
mean and what I think you mean is:

method foo ( Thingie $t ) { ... }

$object->foo( $behaves_like_thingie );

foo() says, "Give me something that I can treat like a Thingie. I
don't care HOW it does it, I just want it to do something sane."

$behaves_like_thingie is an instance of a class that somehow says,
"Hey, I act like Thingie. I'm substitutable for Thingie if you don't
break my encapsulation."

If we're just confused over a bit of terminology, we're in violent
agreement on the idea, which is much more important.

-- c

Austin Hastings

unread,
Jul 24, 2003, 3:57:57 PM7/24/03
to chromatic, perl6-l...@perl.org

--- chromatic <chro...@wgz.org> wrote:
> On Thursday, July 24, 2003, at 11:17 AM, Austin Hastings wrote:
>
> >> No, I think Java interfaces are a kluge to get around copying a
> >> broken type system and the lack of multiple inheritance.
> >
> > Multiple Inheritance != Protocols | Interfaces
>
> I quite agree, but I've done enough Java to know that if they could
> have "solved" it with MI, they would have.
>
> > Protocols/Interfaces is a way of saying "My structure is none of
> your
> > damn business, but I comply with the rules you've set."
>
> Yes, exactly.
>
> > I disagree, and I hope you've simply swapped terms around.
> >
> > I think you want to declare "I comply with ruleset X" at the callee
> > object level. That enables the compiler to (1) check that you're
> not
> > lying; and (2) optimize based on (1).
>
> At least one of us is using "caller/callee" in the X11 sense. What I
> mean and what I think you mean is:
>
> method foo ( Thingie $t ) { ... }
>
> $object->foo( $behaves_like_thingie );
>
> foo() says, "Give me something that I can treat like a Thingie. I
> don't care HOW it does it, I just want it to do something sane."

To me, $object.Class is the callee (includes "method foo"). The code
that contains C<$object->foo($behaves_like_thingie);> is the caller.

> If we're just confused over a bit of terminology, we're in violent
> agreement on the idea, which is much more important.

Yeah.

So what do we get?

# Multiple Inheritance:
class Combo is all(SuperClass1, SuperClass2, ...) {...}
class Comb2 is Super1 is Super2 {...}

# Protocol:
# More than just an interface, because Perl6 is okay with
# loose encapsulation
protocol TCPIP {
has $.variable; # Protocol requires this variable
has $.var2 is Array of Int; # Ditto
method Int m1(Int, Str) {...} # Method required
}

Going one step farther, there's a function called "protocol" and maybe
one called "class" that handle this sort of thing. Also, C<is> means
C<implements> when given a protocol, and C<implements> extracts a
default protocol when given a class.

class Scalar implements Str
implements Int
implements Ref
{...} # All you need to know.

class MyArray is class(Array) # Convert PCL to Class

Perverse behavior:

# Converts protocol "TCPIP", above, to anon class, inherits.
class Perv is class(TCPIP) {...}

# Converts Super2 to Protocol, implements it.
class Perv2 is Super1 implements Super2 {...}
class Perv2 is Super1 is protocol(Super2) {...}

# Alternatively, select any of:
# {private, protected, public}_methods (or "methods" => public)
# {private, protected, public}_data ("data" => public)
# inheritance
class Perv2 is Super1 implements Super2, qw(methods inheritance) {...}
class Perv2 is Super1 is protocol(Super2, qw(methods inheritance))
{...}

=Austin

Kurt Starsinic

unread,
Jul 24, 2003, 12:25:19 PM7/24/03
to David Wheeler, chromatic, Luke Palmer, perl6-l...@perl.org
On Jul 24, David Wheeler wrote:
> On Wednesday, July 23, 2003, at 05:57 PM, chromatic wrote:
>
> >The first is a deeper question -- besides inheritance, there's
> >delegation, aggregation, and reimplementation (think mock objects)
> >that can make two classes have equivalent interfaces. I'd like some
> >way to mark this equivalence *without* having to inherit from an
> >abstract base class and I wish that interface equivalence were checked
> >before inheritance, as per Luke's idea.
>
> Sounds like you want Java-style "interfaces" to me.

Follow the thread back. Objective-C had them way first, and their
ur-name is "protocols."

- Kurt

Benjamin Goldberg

unread,
Jul 24, 2003, 8:28:22 PM7/24/03
to perl6-l...@perl.org
Chromatic wrote:
[snip]

> > I think you want to declare "I comply with ruleset X" at the callee
> > object level. That enables the compiler to (1) check that you're not
> > lying; and (2) optimize based on (1).
>
> At least one of us is using "caller/callee" in the X11 sense. What I
> mean and what I think you mean is:
>
> method foo ( Thingie $t ) { ... }
>
> $object->foo( $behaves_like_thingie );
>
> foo() says, "Give me something that I can treat like a Thingie. I
> don't care HOW it does it, I just want it to do something sane."
>
> $behaves_like_thingie is an instance of a class that somehow says,
> "Hey, I act like Thingie. I'm substitutable for Thingie if you don't
> break my encapsulation."

If this were Java, the way to do this would be to define a Thingie
interface, and then an (archetypical) ThingieObject class... any time
that we want to actually *create* Thingies, we would use "new
ThingieObject", but everywhere else, we would use the typename
"Thingie". This way, when we want a class which "acts like" a Thingie,
but without inheriting any of it's innards, simply implement the Thingie
interface, instead of inheriting the ThingyObject class.

<idea type=wierd>
Here's a possible idea -- have a method of the Class class, which
returns (creates) an anonymous Interface object, which provides all of
the public methods of that class, and which is magically one of the
parents of that class.

This way, when one wants to define a new class X which "acts like" some
other class Y, but which doesn't *really* inherit from Y (none of the
internal data, etc.), we can define X as implementing the Y.interface()
Interface. For our "isa" operator, and (perhaps more importantly) for
multimethod dispatch and/or sub prototype checking, we only check if an
object inherits from a class's magic parent interface, and *don't* check
if it *really* inherits from that class itself.
</idea>

Of course, this by itself wouldn't let us delegate to the ThingyObject's
versions of the methods... that would require another extra layer of
nonsense^Windirection.


> If we're just confused over a bit of terminology, we're in violent
> agreement on the idea, which is much more important.

--
$a=24;split//,240513;s/\B/ => /for@@=qw(ac ab bc ba cb ca
);{push(@b,$a),($a-=6)^=1 for 2..$a/6x--$|;print "$@[$a%6
]\n";((6<=($a-=6))?$a+=$_[$a%6]-$a%6:($a=pop @b))&&redo;}

Chromatic

unread,
Jul 24, 2003, 9:18:35 PM7/24/03
to Benjamin Goldberg, perl6-l...@perl.org
On Thursday, July 24, 2003, at 05:28 PM, Benjamin Goldberg wrote:

> If this were Java, the way to do this would be to define a Thingie
> interface, and then an (archetypical) ThingieObject class... any time
> that we want to actually *create* Thingies, we would use "new
> ThingieObject", but everywhere else, we would use the typename
> "Thingie". This way, when we want a class which "acts like" a Thingie,
> but without inheriting any of it's innards, simply implement the
> Thingie
> interface, instead of inheriting the ThingyObject class.

Yes, that's the Java way to do it. Surely we can do it better in Perl
6.

The problem with Java interfaces is that you have to rely on the
library writer to have expected you to use an interface. Given the
amount of CPAN modules that, for example, expect a glob and preclude me
from passing in an IO::Handle with code like this:

croak "Need a glob" unless ref $thingie eq 'GLOB';

I'm not sure that the Java style is helpful. I'd rather not multiply
entities needlessly.

> For our "isa" operator, and (perhaps more importantly) for
> multimethod dispatch and/or sub prototype checking, we only check if an
> object inherits from a class's magic parent interface, and *don't*
> check
> if it *really* inherits from that class itself.

<heretic>
Why should an implementor inherit from the interface?

If inheritance and polymorphic equivalence are two different things,
they ought to be handled two different ways. If anything, inheritance
is a specific case of the general mechanism of marking polymorphic
equivalence.

Again, the interesting question isn't "Does this thing derive from
something I know about?" It's "Does this thing support the operations I
expect it to support? I don't care how, just that it does."

I don't want to call $mock_foo->isa( 'foo' ) because $mock_foo *isn't*
a foo. I don't want to call $delegates_to_foo->isa( 'foo' ) because
$delegates_to_foo *isn't* a foo. They can both handle foo-methods, but
neither is a foo.
</heretic>

-- c

Kurt Starsinic

unread,
Jul 24, 2003, 9:45:12 PM7/24/03
to chromatic, Benjamin Goldberg, perl6-l...@perl.org

My two cents: the best possible use of an interface/protocol is
to define a set of methods *and their semantics*, and *not* their
implementation. In pseudocode:

protocol Window {
method print;
method close;
method bringToFront;
}

class MyWindow: implements Window;

You're saying that MyWindow has print, close, and bringToFront
methods. You're not saying whether they're inherited, or implemented
from scratch. You *are* saying that close() will erase a graphical
rectangle on a display, not disconnect a filehandle or return "true"
if it's nearby.

So the useful feature of this abstraction is that, given an
anonymous object, you don't ask, "do you implement method called
so-and-so", e.g., "$anon->can('print')"; you ask it, "do you do the
things that a Window does," e.g., "$anon->implements('Window')".

So a class shouldn't inherit from an interface. It should
assert that it implements it.

- Kurt

Gordon Henriksen

unread,
Jul 25, 2003, 8:25:03 AM7/25/03
to perl6-l...@perl.org
On Thursday, July 24, 2003, at 09:45 , Kurt Starsinic wrote:

> On Jul 24, chromatic wrote:
>
>> On Thursday, July 24, 2003, at 05:28 PM, Benjamin Goldberg wrote:
>>
>> The problem with Java interfaces is that you have to rely on the
>> library writer to have expected you to use an interface. Given the
>> amount of CPAN modules that, for example, expect a glob and preclude
>> me from passing in an IO::Handle with code like this:
>>
>> croak "Need a glob" unless ref $thingie eq 'GLOB';
>>
>> I'm not sure that the Java style is helpful. I'd rather not multiply
>> entities needlessly.
>

> My two cents: the best possible use of an interface/protocol is to
> define a set of methods *and their semantics*, and *not* their
> implementation. In pseudocode:
>
> protocol Window {
> method print;
> method close;
> method bringToFront;
> }
>
> class MyWindow: implements Window;
>
> You're saying that MyWindow has print, close, and bringToFront
> methods. You're not saying whether they're inherited, or implemented
> from scratch. You *are* saying that close() will erase a graphical
> rectangle on a display, not disconnect a filehandle or return "true" if
> it's nearby.
>
> So the useful feature of this abstraction is that, given an
> anonymous object, you don't ask, "do you implement method called
> so-and-so", e.g., "$anon->can('print')"; you ask it, "do you do the
> things that a Window does," e.g., "$anon->implements('Window')".
>
> So a class shouldn't inherit from an interface. It should assert
> that it implements it.

Totally on track. I'd like to also rehash what Mr. Goldberg was getting
at:

One of the very useful feature of Objective C's protocols is that they
be used with classes which did not originally declare implementation of
the protocol: Say a library module from CPAN implements half of the
functionality you want. You want to embed the rest in a new class of
your devising, but it doesn't have an isa-relationship to the CPAN
module. You can simply apply a protocol to the problem, and still wind
up with a typesafe solution. Even if you tried to patch your protocol
into the CPAN module, the patch probably wouldn't be applied because
your app and its protocol are meaningless in a broader context. I'm
going to hijack somebody else's meme here: This dynamism enables
accidental polymorphism--it lets implicit method patterns surface into
explicit protocols without requiring changes to existing code, and so
empowers the caller over the tyranny of the library author: An element
of object-oriented design can arise after the implementation of a class.
That has a very Perl 6-ish feel to it, closer to the untyped flexibility
of Perl 5 than the de rigueur rigidity of Java.

Gordon Henriksen
mali...@mac.com

Richard J Cox

unread,
Jul 26, 2003, 5:56:51 AM7/26/03
to perl6-l...@perl.org, David Wheeler, chromatic
On Thursday, July 24, 2003, 5:45:33 PM, you (mailto:perl6-l...@perl.org) wrote:
> On Thursday, July 24, 2003, at 08:49 AM, David Wheeler wrote:

> No, I think Java interfaces are a kluge to get around copying a broken
> type system and the lack of multiple inheritance.

There are other alternatives...

In typeless languages it is a runtime error; or there is the .NET solution, to
use delegates.

See http://www.gotdotnet.com/team/dbox/default.aspx?key=2003-07-21T08:36:33Z

For a blog entry that talks about exactly this point.


--
Richard
mailto:rj...@cix.co.uk

Ray Blaak

unread,
Jul 29, 2003, 12:57:33 AM7/29/03
to
chro...@wgz.org (Chromatic) writes:
> The problem with Java interfaces is that you have to rely on the
> library writer to have expected you to use an interface.

I don't see this as a problem. You use anything that implements the interface.
The library could also be providing conveniently available instances as well.

What would be tedious with Java's approach in Perl-land would be going from
untyped to typed instances, requiring explicit casts.

If one codes using a typed style, this becomes much less of a problem.

> Again, the interesting question isn't "Does this thing derive from
> something I know about?" It's "Does this thing support the operations I
> expect it to support? I don't care how, just that it does."

Note that the saying "o instanceof C" operator in Java doesn't care if C is a
class or an interface. To a caller it simply means "does this thing act like a
C?".

Which is what you want.

--
Cheers, The Rhythm is around me,
The Rhythm has control.
Ray Blaak The Rhythm is inside me,
rAYb...@STRIPCAPStelus.net The Rhythm has my soul.

0 new messages