Damian Conway writes:
> Either you give up interface polymorphism (a grievous loss) or you give
> up static type-checking.

Blech, you're right.

> Actually, it's inheritance polymorphism that proliferates pretend classes
> like Pet.

I meant that.  Sorry, you're so in tune with Perl that I'm starting to
think I can write any old crap and you'll make sense of it :-)

> Alternatively, one might imagine an attribute C<:must> that tells a variable
> that anything assigned to it must provide certain methods:
> 
>       my $foo : must(feed water play poop);
>       $foo = Manager->new();          # die "Manager object can't play".
> 
> An interface then becomes an alias for a particular C<must>:
> 
>       use attr_alias Pet => qw(feed water play poop);
>       my $foo : must(Pet)
> 
> Not sure which I like better. :-)

The other style (Pet via pragmata or "implements") is like C++, only
your "virtual base class" isn't part of the inheritance hierarchy.
This :must attribute isn't something I've seen in any other language,
so I don't know what it's drawbacks might be.

Ah.  "implements" makes the class designer do the work of listing
methods by designing interfaces.  :must makes the user of a class do
the work.  But the most common cases of OO in Perl don't use
polymorphism, so making the user do the work would be making something
hard which ought to be easy.

However, :must gives the user of a module flexibility, because only
you the user really knows what wacky polymorphic way you're combining
classes that the creators never envisioned ("it's a dog, it can
fetch().  it's an FTP client, it can fetch()!").

Is there some way to get the best of both worlds?  Instead of :want,
let the user define custom interfaces?

  package Dog implements Pet;
  package NetSnarfer implements FTP;

  # in main program
  use Custom::Interface Fetcher => qw(fetch);

  my Fetcher $x;
  my Dog $spot;
  my NetSnarfer $z;

  $x = $z;      # ok because $z can fetch
  $x = $spot;   # ok because $spot can fetch
  $x->fetch();  # ok
  $x->bark();   # not ok because Fetcher doesn't list bark()

Nat

Reply via email to