Re: Interfaces

2002-10-13 Thread Larry Wall

On Thu, 10 Oct 2002, Larry Wall wrote:
: Anyway, I don't see offhand why composition can't simply be done with
: attributes as it is in C++, especially since attributes manifest as
: methods outside the class.  I don't think $car.cd.eject() is all that
: horrible to contemplate.

By the way, ever since we came up with attr in Zurich, I've been
hating it more and more.  I'm thinking that has reads a lot better:

class Dog is Mammal {
has Nose $.snout;
has Ear  .ears is cut(long);
has Leg  .legs;
has Tail $.tail is cut(short);

method Wag () {...}
}

Or, along the lines of my lists:

class Dog is Mammal {
has (
Nose $.snout,
Ear  .ears is cut(long),
Leg  .legs,
Tail $.tail is cut(short),
);

method Wag () {...}
}

Larry




Re: Interfaces

2002-10-13 Thread Larry Wall

On Fri, 11 Oct 2002, Larry Wall wrote:
: You can certainly drop it within the methods,
: since there's also the accessor methods.

But I should point out that there's a semantic difference between
$.foo and .foo, in that $.foo is guaranteed to get my copy of the
attribute, while .foo might just go haring off after a virtual method
in a subclass, if the subclass puts a wrapper method around this
class's .foo method.

Larry




Re: Interfaces

2002-10-12 Thread Larry Wall

On Fri, 11 Oct 2002, Michael Lazzaro wrote:
: On Friday, October 11, 2002, at 04:11  PM, Larry Wall wrote:
:  has Nose $.snout;
:  has Ear  .ears is cut(long);
:  has Leg  .legs;
:  has Tail $.tail is cut(short);
: 
:  method Wag () {...}
:  }
: 
: What's the rationale again for the dot in $.snout?  Does it imply that 
: it should be
: 
:   method .Wag () {...}
: 
: to match?

Yes, that's part of it, presuming you actually meant:

method .snout () {...}

It also doesn't look like either a lexical or a global when you use
it within the method.  I always hated that about C++.

I suppose it could be argued that the . is redundant within a has,
but I kinda like the consistency.  It could also be argued that
the '$' should be dropped on scalar attributes, but that's another
consistency thing.  You can certainly drop it within the methods,
since there's also the accessor methods.

Larry




Re: Interfaces

2002-10-12 Thread Nicholas Clark

On Tue, Oct 08, 2002 at 05:00:20PM -0400, Michael G Schwern wrote:
 Unfortunately, Java doesn't ship with JUnit nor do Java libraries usually
 ship with tests nor does a simple convention to run them nor an expectation
 that the user will run the tests before installing.  Score one for Perl. :)

I blame that Schwern character, and his partner in crime, Chromatic. They keep
encouraging us to use more 'tests'; Very bad habit - I mean, with more tests
we'll probably be shipping software with less bugs, and where's that going to
lead? I tell you, less bugs mean less jobs for us programmers, and that's not
good. We'll have trouble occupying all the time that will free up. We might
even be forced to do fun stuff. :-)

Nicholas Clark
-- 
Even better than the real thing:http://nms-cgi.sourceforge.net/



Re: Interfaces

2002-10-12 Thread Michael Lazzaro


On Friday, October 11, 2002, at 04:11  PM, Larry Wall wrote:
   has Nose $.snout;
   has Ear  .ears is cut(long);
   has Leg  .legs;
   has Tail $.tail is cut(short);

   method Wag () {...}
 }

What's the rationale again for the dot in $.snout?  Does it imply that 
it should be

method .Wag () {...}

to match?

MikeL




Re: Interface lists (was Re: Interfaces)

2002-10-10 Thread Larry Wall

On Mon, 30 Sep 2002, Michael G Schwern wrote:
: On Tue, Oct 01, 2002 at 01:36:19AM +0100, Simon Cozens wrote:
:  [EMAIL PROTECTED] (Michael G Schwern) writes:
: method _do_internal_init ($num) is private {
:  
:  Just thinking aloud, would 
:  sub foo is method is private is integer is fungible {
:  
:  be better written as
:  sub foo is fungible private integer method {
:  
:  or not?

It's potentially ambiguous.  Here's a bad example, but there are probably
better ones:

my $foo is rw cmp ;

Plus we have to worry about arguments to properties, if we allow
anything other than ().  I'd personally like to see some properties
that can take a closure as their argument, but the parser would have
to know that in advance or the method property above would slurp
up the subroutine block by accident.  Or the sub block itself needs
a keyword.

: How about seperated by commas, like any other list?
: 
: method foo is fungible, private, integer {

Is ambiguous:

my ($foo is foo, bar, $bar is baz) = (1,2);

Also, precedence of comma with respect to assignment causes problems.

We may be able to relax this later somehow, but for now we're saying
that is...is...is... isn't all that onerous.

To which the only correct reply is, but...but...but...  :-)

Larry




Re: Interfaces

2002-10-10 Thread Larry Wall

On Mon, 7 Oct 2002, chromatic wrote:
: On Wed, 02 Oct 2002 04:12:44 -0700, Michael G Schwern wrote:
: 
:  I like the class Vehicle is interface as a shorthand for declaring every
:  method of a class to be an interface.
: 
: Perhaps associating a property with a class can be shorthand for associating
: that property with every method of the class?

Not in general, since the class needs to be able to have properties
apart from from its methods, such as its parent classes.  But a
particular property such as interface could certainly be set up to
be distributive over the methods or attributes.

Larry




Re: Interfaces

2002-10-10 Thread Larry Wall

On Mon, 7 Oct 2002, Andy Wardley wrote:
: Nicholas Clark wrote:
:  I think that the first syntax
:  
:  class Car::Q is Car renames(eject = ejector_seat)
:   is CD_Player renames(drive = cd_drive);
:  
:  makes it more clear that I'd like to pick and choose which methods
:  the composite object gets from which parent.
: 
: But now you've turned composition back into inheritance, and I think it's
: important to be able to distinguish between the two.
: 
: The car is definately not a CD player, it just has one.
: 
: I think we need a more flexible syntax for specifying how interfaces 
: should be constructed in the case of composed objects, rather than 
: turning composition into inheritance to avoid the problem.

Yes, that's important.  If you've got a CD_Player *object*, it doesn't
do anyone any good to pretend it's a car *object*.  We too often
lose sight of the fact that objects should behave like objects.  That's
what OO really means, after all.  OO isn't about inheritance

Anyway, I don't see offhand why composition can't simply be done with
attributes as it is in C++, especially since attributes manifest as
methods outside the class.  I don't think $car.cd.eject() is all that
horrible to contemplate.

Larry




Re: Interfaces

2002-10-08 Thread chromatic

On Wed, 02 Oct 2002 04:12:44 -0700, Michael G Schwern wrote:

 I like the class Vehicle is interface as a shorthand for declaring every
 method of a class to be an interface.

Perhaps associating a property with a class can be shorthand for associating
that property with every method of the class?

-- c



Re: Interfaces

2002-10-08 Thread Michael G Schwern

On Sun, Oct 06, 2002 at 06:17:37PM -0400, Daniel B. Boorstein wrote:
 I think there may be some confusion here. In java, there's no special syntax 
 to declare a method an optional part of the interface. All concrete classes 
 that implement the Collection interface still must define full-bodied 
 Cadd(Object element) methods. It just so happens that by convention some 
 classes simply throw an UnsupportedOperationException, perhaps like so:

A!  No wonder I couldn't find any syntax for it!  Thanks for clearing
that up.

Still, the objections still hold, though now it's a stylistic objection
rather than syntactic.  It's disturbing that they'd put these optional
methods into the core Java API, thereby encouraging their use (Sun did it,
so I can to!).  Cannonizing the idea weakens the whole concept of an
interface and contract.

It really ought to be one of those sure you can do this, but please don't
things.


-- 

Michael G. Schwern   [EMAIL PROTECTED]http://www.pobox.com/~schwern/
Perl Quality Assurance  [EMAIL PROTECTED] Kwalitee Is Job One
You see, in this world there's two kinds of people.  Those with loaded
guns, and those who dig.  Dig.
-- Blondie, The Good, The Bad And The Ugly



Re: Interfaces

2002-10-08 Thread Michael G Schwern

On Sun, Oct 06, 2002 at 11:57:51PM -0400, Noah White wrote:
   I wouldn't call it a dirty little secret as Michael put it :-).  
   This is the right thing to do within the context of a contract. The 
 contract does not guarantee that method functionality implemented by a 
 concrete class does exactly a certain thing a certain way ( I'd like to see 
 the language that does!).

Oddly enough, JUnit (and in the Perl world Test::Class and Test::Unit) can
do it with inherited tests.  Subclasses must pass their parent's tests, so
yes, you can guarantee method implementations, just not with an interface
contract.

Unfortunately, Java doesn't ship with JUnit nor do Java libraries usually
ship with tests nor does a simple convention to run them nor an expectation
that the user will run the tests before installing.  Score one for Perl. :)


-- 

Michael G. Schwern   [EMAIL PROTECTED]http://www.pobox.com/~schwern/
Perl Quality Assurance  [EMAIL PROTECTED] Kwalitee Is Job One
Please Captain, not in front of the Klingons.



Re: Interfaces

2002-10-08 Thread Trey Harris

In a message dated Tue, 8 Oct 2002, Michael G Schwern writes:

 On Sun, Oct 06, 2002 at 06:17:37PM -0400, Daniel B. Boorstein wrote:
  I think there may be some confusion here. In java, there's no special syntax
  to declare a method an optional part of the interface. All concrete classes
  that implement the Collection interface still must define full-bodied
  Cadd(Object element) methods. It just so happens that by convention some
  classes simply throw an UnsupportedOperationException, perhaps like so:

 A!  No wonder I couldn't find any syntax for it!  Thanks for clearing
 that up.

 Still, the objections still hold, though now it's a stylistic objection
 rather than syntactic.  It's disturbing that they'd put these optional
 methods into the core Java API, thereby encouraging their use (Sun did it,
 so I can to!).  Cannonizing the idea weakens the whole concept of an
 interface and contract.

 It really ought to be one of those sure you can do this, but please don't
 things.

It's a RuntimeException.  You can't require that all RuntimeExceptions be
declared if thrown; otherwise, every method would have to declare throws
OutOfMemoryException, CannotLoadClassException,
TheEndTimeIsUponUsException, ...  for every single runtime error.  You
can subclass RuntimeException.  So if Sun hadn't provided an
UnsupportedOperationException, anyone else could easily have done so.

And they'll be able to in Perl, too, whatever you do.  I often code

method foo {
  die Abstract method foo not implemented in concrete class .
 (ref $_[0] || $_[0]) . , died;
}

In my abstract superclasses, which is the very same thing.

Trey




Re: Interfaces

2002-10-08 Thread Michael G Schwern

On Tue, Oct 08, 2002 at 05:03:26PM -0400, Trey Harris wrote:
  It really ought to be one of those sure you can do this, but please don't
  things.
 
 It's a RuntimeException.  You can't require that all RuntimeExceptions be
 declared if thrown;
snip
 You can subclass RuntimeException.  So if Sun hadn't provided an
 UnsupportedOperationException, anyone else could easily have done so.

I'm not objecting to the fact that it's a runtime exception [1] or that it's
possible to do such a thing.  I'm objecting to the fact that it's an
exception at all since it adds uncertainty into what should otherwise be a
guaranteed interface and that this uncertainty is put in the core library of
the language.

Because Sun did it it's now Officially OK, even if that's not what they
ment.  More so in the Java world than in Perl, things you do in the core API
become canonized. Because that's how Sun does it carries a lot of weight.
In Perl it's often that's how (C|Bourne Shell|$popular_module) does it.

Programmers parroting the design of a popular API is common and can be used
for Good or Evil.


[1] It would be less worse [2] as a compile-time exception.
[2] This is different than better. ;)

-- 

Michael G. Schwern   [EMAIL PROTECTED]http://www.pobox.com/~schwern/
Perl Quality Assurance  [EMAIL PROTECTED] Kwalitee Is Job One
I don't get it.  Must be art.



Re: Interfaces

2002-10-07 Thread Andy Wardley

Nicholas Clark wrote:
 I think that the first syntax
 
 class Car::Q is Car renames(eject = ejector_seat)
  is CD_Player renames(drive = cd_drive);
 
 makes it more clear that I'd like to pick and choose which methods
 the composite object gets from which parent.

But now you've turned composition back into inheritance, and I think it's
important to be able to distinguish between the two.

The car is definately not a CD player, it just has one.

I think we need a more flexible syntax for specifying how interfaces 
should be constructed in the case of composed objects, rather than 
turning composition into inheritance to avoid the problem.


A




Re: Interfaces

2002-10-07 Thread Daniel B. Boorstein

On Sunday 06 October 2002 09:57 pm, Michael G Schwern wrote:
 On Sun, Oct 06, 2002 at 01:49:26AM -0400, Noah White wrote:
  OTOH, Java interfaces have a loophole which is considered a design
  mistake.
  An interface can declare some parts of the interface optional and then
  implementors can decide if they want to implement it or not.  The
  upshot
  being that if you use a subclass in Java you can't rely on the optional
  parts being there.
 
  Say what?!? I don't think so. If a JAVA class which implements an
  interface does not declare all of the methods of the interface then
  that class will be abstract and you won't be able to instantiate a
  concrete instance of it. You are guaranteed that any concrete instance
  of a class which implements an interface will contain ALL methods
  defined by the interface.


[snip]


 It is possible in Java to declare methods to be an optional operation.
 This means the subclass may or may not implement that method and if you try
 to use an unimplemented method an UnsupportedOperationException is thrown.

 Effectively, this means that for every optional method you want to use,
 you've got to wrap it in a try block to catch the
 UnsupportedOperationException, recover and try to do something else if it's
 not there.  Makes using an optional operation complicated and error prone.

To be clear, UnsupportedOperationException is a subclass of RuntimeException, 
and therefore one is not required to wrap a try around methods that throw it.


 In effect, an optional interface is declaring this method may or may not
 exist which ain't that useful.

 I can't find the syntax or this or when it was introduced, might be 1.2,
 but I see it mentioned in the Collection API and tutorial docs:

 http://java.sun.com/docs/books/tutorial/collections/interfaces/collection.h
tml

 The Collection interface is shown below:
 public interface Collection {
 // Basic Operations
 int size();
 boolean isEmpty();
 boolean contains(Object element);
 boolean add(Object element);// Optional
 boolean remove(Object element); // Optional
 Iterator iterator();


I think there may be some confusion here. In java, there's no special syntax 
to declare a method an optional part of the interface. All concrete classes 
that implement the Collection interface still must define full-bodied 
Cadd(Object element) methods. It just so happens that by convention some 
classes simply throw an UnsupportedOperationException, perhaps like so:

public class MyStaticCollection implements Collection {
  ...
  public boolean add (Object element) {
throw new UnsupportedOperationException(add not supported);
  }
  ...
}

This is really no different than the following from Tie::Handle:

sub READ {
my $pkg = ref $_[0];
croak $pkg doesn't define a READ method;
}

No special syntax, just convention enforced by the method implementations.

  - Dan Boorstein



Re: Interfaces

2002-10-06 Thread Nicholas Clark

On Tue, Oct 01, 2002 at 04:01:26PM -0700, Michael Lazzaro wrote:
 
 On Tue, Oct 01, 2002 at 03:43:22PM -0400, Trey Harris wrote:
 You want something like
 
   class Car is Vehicle renames(drive = accel)
 is MP3_Player renames(drive = mp3_drive);
 
 I *really* like this, but would the above be better coded as:
 
   class Car is Vehicle renames(drive = accel)
   has MP3_Player renames(drive = mp3_drive);
 
  implying a container relationship with automatic delegation?  
 Among the other considerations is that if you simply said
 
   class Car is Vehicle has MP3_Player;
 
 the inheritance chain could assume that Car.drive === Vehicle.drive, 
 because is-a (inheritance) beats has-a (containment or delegation).  If 
 you needed to, you should still be able to call $mycar.MP3_Player.drive 
 to DWYM, too.

I don't think I like this. Assume that instead of an mp3 player my car
has a 007 CD autochanger.

then $car.drive is as we expect, Vehicle.drive, because inheritance beats
containment or delegation.

But I could get a nasty shock when I want to open the tray on the CD player,
call $car.eject, and the car fires me out through the sunroof.

I think that the first syntax

class Car::Q is Car renames(eject = ejector_seat)
is CD_Player renames(drive = cd_drive);

makes it more clear that I'd like to pick and choose which methods
the composite object gets from which parent.

Nicholas Clark
-- 
Even better than the real thing:http://nms-cgi.sourceforge.net/



Re: Interfaces

2002-10-06 Thread Michael G Schwern

On Sun, Oct 06, 2002 at 01:49:26AM -0400, Noah White wrote:
 OTOH, Java interfaces have a loophole which is considered a design 
 mistake.
 An interface can declare some parts of the interface optional and then
 implementors can decide if they want to implement it or not.  The 
 upshot
 being that if you use a subclass in Java you can't rely on the optional
 parts being there.
 
 Say what?!? I don't think so. If a JAVA class which implements an 
 interface does not declare all of the methods of the interface then 
 that class will be abstract and you won't be able to instantiate a 
 concrete instance of it. You are guaranteed that any concrete instance 
 of a class which implements an interface will contain ALL methods 
 defined by the interface.

This came up durning a talk at JAOO by Kevlin Henny entitled Minimalism: A
Practical Guide to Writing Less Code which is a nice talk, Java or not.
http://www.two-sdg.demon.co.uk/curbralan/papers.html

Slide 7, which is about obeying contracts, says:

Subclassing and implemented interfaces should follow substitutability

Unsupported operations or operations that do a 
little less or expect a little extra add complexity

and he went off on a short tangent during the talk about optional operations
in Java.

It is possible in Java to declare methods to be an optional operation.
This means the subclass may or may not implement that method and if you try
to use an unimplemented method an UnsupportedOperationException is thrown.

Effectively, this means that for every optional method you want to use,
you've got to wrap it in a try block to catch the
UnsupportedOperationException, recover and try to do something else if it's
not there.  Makes using an optional operation complicated and error prone.

In effect, an optional interface is declaring this method may or may not
exist which ain't that useful.

I can't find the syntax or this or when it was introduced, might be 1.2, but
I see it mentioned in the Collection API and tutorial docs:

http://java.sun.com/docs/books/tutorial/collections/interfaces/collection.html

The Collection interface is shown below:
public interface Collection {
// Basic Operations
int size();
boolean isEmpty();
boolean contains(Object element);
boolean add(Object element);// Optional
boolean remove(Object element); // Optional
Iterator iterator();

http://java.sun.com/docs/books/tutorial/collections/interfaces/

To keep the number of core collection interfaces manageable, the JDK
doesn't provide separate interfaces for each variant of each collection
type. (Among the possible variants are immutable, fixed-size, and
append-only.) Instead, the modification operations in each interface are
designated optional: a given implementation may not support some of
these operations.  If an unsupported operation is invoked, a collection
throws an UnsupportedOperationException .  Implementations are
responsible for documenting which of the optional operations they
support.  All of the JDK's general purpose implementations support all
of the optional operations.

http://java.sun.com/j2se/1.4.1/docs/api/java/util/Collection.html

Method Summary

 boolean add(Object o)
  Ensures that this collection contains the specified element 
  (optional operation).

 boolean addAll(Collection c)
  Adds all of the elements in the specified collection to this 
  collection (optional operation).

 void clear()
  Removes all of the elements from this collection (optional 
  operation).

 boolean contains(Object o)
  Returns true if this collection contains the specified element.


I don't know basic Java syntax worth a damn, but I know its dirty little
secrets. ;)


-- 

Michael G. Schwern   [EMAIL PROTECTED]http://www.pobox.com/~schwern/
Perl Quality Assurance  [EMAIL PROTECTED] Kwalitee Is Job One
It's Absinthe time!



Re: Interfaces

2002-10-06 Thread Noah White


On Sunday, October 6, 2002, at 06:17  PM, Daniel B. Boorstein wrote:
[SNIP]

 I think there may be some confusion here. In java, there's no special 
 syntax
 to declare a method an optional part of the interface. All concrete 
 classes
 that implement the Collection interface still must define full-bodied
 Cadd(Object element) methods. It just so happens that by convention 
 some
 classes simply throw an UnsupportedOperationException, perhaps like so:

 public class MyStaticCollection implements Collection {
   ...
   public boolean add (Object element) {
 throw new UnsupportedOperationException(add not supported);
   }
   ...
 }

Yes, this is true and is a common way to stub out methods you may 
choose not to provide functionality for. For example, your code 
implements a JDK 1.2 interface, then you subsequently switch to the 1.4 
VM implementation for which that interface's API has changed and there 
are now 14 more methods to be implemented for which you don't care 
about :-) You still need to provide the method signatures in your 
concrete class, but as in your example above you can throw an 
UnsupportedOperationException within that method.  Or as Michael 
pointed out in the Collections interface, the add() method of a 
read-only Collection implementation will throw an 
UnsupportedOperationException.

I wouldn't call it a dirty little secret as Michael put it :-).  This 
is the right thing to do within the context of a contract. The contract 
does not guarantee that method functionality implemented by a concrete 
class does exactly a certain thing a certain way ( I'd like to see the 
language that does!). It only guarantees return type, optional 
parameters to accept and any CHECKED exceptions that need be thrown 
(and _importantly_, caught by the invoker), not actually what goes on 
in the method. If it did it wouldn't be an interface :-) Now, an 
UnsuppoertedOperationException is an UNCHECKED (subclass of 
RuntimeException) exception.

The weakness if any lies here. It would be nice for the compiler to 
tell me that I've invoked a method which is going to throw that 
exception, so I would know that I used a method that I probably 
shouldn't be using before it actually gets tapped at runtime which is 
too late and goes *boom*.

-Noah





Re: Interfaces

2002-10-05 Thread Noah White


On Monday, September 30, 2002, at 08:23  PM, Michael G Schwern wrote:

 OTOH, Java interfaces have a loophole which is considered a design 
 mistake.
 An interface can declare some parts of the interface optional and then
 implementors can decide if they want to implement it or not.  The 
 upshot
 being that if you use a subclass in Java you can't rely on the optional
 parts being there.


Say what?!? I don't think so. If a JAVA class which implements an 
interface does not declare all of the methods of the interface then 
that class will be abstract and you won't be able to instantiate a 
concrete instance of it. You are guaranteed that any concrete instance 
of a class which implements an interface will contain ALL methods 
defined by the interface.

-Noah




Re: Interfaces

2002-10-02 Thread Michael G Schwern

On Tue, Oct 01, 2002 at 05:04:29PM -0700, Michael Lazzaro wrote:
 On Tuesday, October 1, 2002, at 02:49  PM, Michael Lazzaro wrote:
 Which implies, I assume, that interface is not the default state of 
 a class method, e.g. we do need something like method foo() is 
 interface { ... } to declare any given method
 
 Flippin' hell, never mind.  You're almost certainly talking about a 
 style like:
 
   interface Vehicle {
   method foo () { ... }
   method bar () { ... }
   }

Definately not that.

 - or -
   class Vehicle is interface {
   ...
   }


snip

   class Vehicle {
   method foo () is interface { ... }
   method bar () is interface { ... }
   method zap () is private { ... }
   }

Perhaps both of the above, but only if methods-as-interfaces have to be
explicitly declared.  I like the class Vehicle is interface as a shorthand
for declaring every method of a class to be an interface.

It depends on if method signatures are enforced on subclasses by default, or
if you have to explicitly declare yourself to be an interface.  That's up in
the air in my mind.

Orthoginal to that decision is if a subclass should be able to explicitly
ignore its parent's interface and conditions.  I started by leaning towards
yes, now I'm thinking no.


-- 

Michael G. Schwern   [EMAIL PROTECTED]http://www.pobox.com/~schwern/
Perl Quality Assurance  [EMAIL PROTECTED] Kwalitee Is Job One
Plus I remember being impressed with Ada because you could write an
infinite loop without a faked up condition.  The idea being that in Ada
the typical infinite loop would be normally be terminated by detonation.
-- Larry Wall in [EMAIL PROTECTED]



Re: Interfaces

2002-10-02 Thread Michael G Schwern

On Tue, Oct 01, 2002 at 04:01:26PM -0700, Michael Lazzaro wrote:
 On Tue, Oct 01, 2002 at 03:43:22PM -0400, Trey Harris wrote:
 You want something like
 
   class Car is Vehicle renames(drive = accel)
 is MP3_Player renames(drive = mp3_drive);
 
 I *really* like this, but would the above be better coded as:
 
   class Car is Vehicle renames(drive = accel)
   has MP3_Player renames(drive = mp3_drive);
 
 ... implying a container relationship with automatic delegation?  

That would simply be another way to do it.  One is multiple inheritence, the
other is delegation.  Both should be in the language.


 Among the other considerations is that if you simply said
 
   class Car is Vehicle has MP3_Player;
 
 the inheritance chain could assume that Car.drive === Vehicle.drive, 
 because is-a (inheritance) beats has-a (containment or delegation).  If 
 you needed to, you should still be able to call $mycar.MP3_Player.drive 
 to DWYM, too.

This, too, is another way to do it, but I like Trey's original solution much
better.  When you use your MP3 Car as a Vehicle, the Vehicle methods win.
When you use it like an MP3_Player, the MP3_Player methods win.  No need to
expose the underlying MP3_Player object to the user.  YMMV.


-- 

Michael G. Schwern   [EMAIL PROTECTED]http://www.pobox.com/~schwern/
Perl Quality Assurance  [EMAIL PROTECTED] Kwalitee Is Job One
List context isn't dangerous.  Misquoting Gibson is dangerous.
-- Ziggy



Re: Interfaces

2002-10-02 Thread Michael G Schwern

On Tue, Oct 01, 2002 at 02:49:49PM -0700, Michael Lazzaro wrote:
 My musing is that the behavior of a class in different contexts is
 itself an interface, in the sense of being a contract between a
 class/subclass and it's users
 
 Ah HA!  Contract!  Return values can be enforce via a simple DBC post
 condition, no need to invent a whole new return value signature.
 
 I think I get it, but can you give some pseudocode? If you want a 
 method to return a list of Zoo animals in list context, and a Zoo 
 object in Zoo object context, what would that look like?

The trick is having some way of getting at the return value. Class::Contract
does this by having a magic value() function you can call in a
post-condition.  I can't think of anything better, so...

class Animals;
method zoo {
   ...
   
   # I have no idea what actual post condition syntax will look like
   post {
   given want {
   when 'LIST' { grep { $^thing.isa('Zoo::Animal') } value() }
   default { value().isa('Zoo') }
   }
   }
}

It might be nice if the return value was the topic of the post condition,
but that leads to problems of how you deal with lists as topics which I
don't know if they've been solved.


 (I'm assuming that DBC postconditions on a method would be treated, 
 internally, as part of the overall signature/prototype of the method: 
 i.e. if you override the method in a subclass, all original 
 postconditions would still remain attached to it (though the new method 
 might itself add additional postconditions.))

That's how I understand it works.


-- 

Michael G. Schwern   [EMAIL PROTECTED]http://www.pobox.com/~schwern/
Perl Quality Assurance  [EMAIL PROTECTED] Kwalitee Is Job One
I'm a man, but I can change... if I have to.
-- Red Green



Re: Interfaces

2002-10-01 Thread Michael G Schwern

On Tue, Oct 01, 2002 at 03:43:22PM -0400, Trey Harris wrote:
 You want something like
 
   class Car is Vehicle renames(drive = accel)
 is MP3_Player renames(drive = mp3_drive);
 
 Either of those renamings is, of course, optional, in which case drive()
 refers to the non-renamed one when referring to a Car object.
 
 But later on, if some code does
 
   Vehicle $mover = getNext(); # returns a Car
   $mover.drive(5);
 
 It should call CVehicle::drive() on C$mover, that is,
 C$mover.accel().
 
 See why aliasing doesn't solve this?

Ahh, because Perl has to know that when $mover is used as a Vehicle it
uses Car.accel but when used as an MP3_Player it calls Car.mp3_drive.
Clever!


-- 

Michael G. Schwern   [EMAIL PROTECTED]http://www.pobox.com/~schwern/
Perl Quality Assurance  [EMAIL PROTECTED] Kwalitee Is Job One
If I got something to say, I'll say it with lead.
-- Jon Wayne



Re: Interfaces

2002-10-01 Thread Michael Lazzaro


 On Tue, Oct 01, 2002 at 03:43:22PM -0400, Trey Harris wrote:
 You want something like

   class Car is Vehicle renames(drive = accel)
 is MP3_Player renames(drive = mp3_drive);

I *really* like this, but would the above be better coded as:

class Car is Vehicle renames(drive = accel)
has MP3_Player renames(drive = mp3_drive);

 implying a container relationship with automatic delegation?  
Among the other considerations is that if you simply said

class Car is Vehicle has MP3_Player;

the inheritance chain could assume that Car.drive === Vehicle.drive, 
because is-a (inheritance) beats has-a (containment or delegation).  If 
you needed to, you should still be able to call $mycar.MP3_Player.drive 
to DWYM, too.

Along these lines, I'd love the ability to do something like:

class Bird is Animal
has (LeftWing is Wing)  # a named Wing
has (RightWing is Wing)
has (LeftLeg is Leg)
has (RightLeg is Leg);

$bird.LeftWing.flap;# makes sense
$bird.flap; # but what's this do? left, right, or 
_both_?
$bird^.Wing.flap# perhaps too evil?  :-)

MikeL




Re: Interfaces

2002-10-01 Thread Chris Dutton

On Monday, September 30, 2002, at 11:19  PM, Michael G Schwern wrote:

 On Mon, Sep 30, 2002 at 06:04:28PM -0700, David Whipp wrote:
 On a slightly different note, if we have interfaces then I'd really
 like to follow the Eiffel model: features such as renaming methods
 in the derived class may seem a bit strange; but they can be useful
 if you have have name-conflicts with multiple inheritance.

 I'm not familiar with the Eiffel beyond it's the DBC language and it's
 French, but wouldn't this simply be covered by aliasing?

Eiffel can either rename a feature(method, attribute), which is pretty 
much the same as aliasing as you might see it in Ruby, or you can 
redefine the method entirely.  Again, you also would see this in Ruby, 
which might be more approachable for those familiar with Perl.

class BAR
inherit FOO
rename output as old_output
end
end

or...

class BAR
inherit FOO
redefine output
end
end




Re: Interfaces

2002-10-01 Thread Michael Lazzaro


On Tuesday, October 1, 2002, at 02:49  PM, Michael Lazzaro wrote:
 Which implies, I assume, that interface is not the default state of 
 a class method, e.g. we do need something like method foo() is 
 interface { ... } to declare any given method

Flippin' hell, never mind.  You're almost certainly talking about a 
style like:

interface Vehicle {
method foo () { ... }
method bar () { ... }
}
- or -
class Vehicle is interface {
...
}

 in which case an interface is specified as a type of abstract 
class, not an attribute of a given method... I was thinking of 
something like

class Vehicle {
method foo () is interface { ... }
method bar () is interface { ... }
method zap () is private { ... }
}

 in which a specific base class could define obligatory method 
signatures for any eventual subclasses.  Never mind on that one, I've 
been thinking too much about a different problem.

MikeL




Re: Interfaces

2002-09-30 Thread Michael Lazzaro


On Sunday, September 29, 2002, at 05:11  PM, Michael G Schwern wrote:
 Here's some open problems:

 Would this be the default behavior for overridden methods, or will the
 parent class/methods have to be declared is interface for the 
 signatures
 to be enforced on subclasses?

Heck, I'll jump into this one, since I've been working in _way_ too 
many OO variations lately, some of them inflicted upon myself.  While I 
hope perl6 will allow extendable OO methodologies, the out-of-box one 
needs to be as robust as possible.  Here's a strawman opinion we can 
argue against:

I originally thought I was going to argue that it should be the default 
behavior (to avoid yet more cruft in the method prototype) but thinking 
about it more, I'll make the case that yes, you should have to say is 
interface, if that's what you mean.

The reason being private methods; while the interfaces to an object 
must remain consistent, I don't think we should enforce the same rigor 
on internal methods of a class.  There are cases where you want 
something like:

method do_internal_initialization ($num) { ... }

but you don't care if you stomp on it's name for certain subclasses 
that need similar private methods:

method do_internal_initialization ($hashref) { ... }

(...leading to an additional question, will there be a way to specify 
methods of a class that are *not* inherited by subclasses?)  So I'd say 
we either need is interface, or (worse) is not interface.

 Will interfaces be ignorable?

 and if we _do_ say any of the above, then they are not ignorable, 
on pain o' death.  I'd argue there shouldn't be any way around it, 
period, or we lose the whole point of the implied consistency.  Can 
anyone think of a counterexample?

 What if a subclass adds extra, optional arguments to a method, is that 
 ok?

This is the scariest question, I think...  In theory, yes, there are 
lots of potential interfaces that would benefit from optional 
extensions,  I've made a few.  In strict terms, though, they violate 
the whole idea of common, invariant interface, so I never know if 
what I've done is Acceptable, or a Shameful Hack...  anyone care to 
make a case either way on this one?

 What about the return type?  If you're doing strict OO it would be 
 nice to
 specify the signature of the return value as well, which will get
 interesting to be able to describe totally the various ways in which a
 method can return in different contexts.

While I cannot conceive what monstrosity of syntax we could put in the 
method prototype to say I want to return this type in this context, 
and this type in this context, etc., etc., I would argue that 
specifying it is an absolute necessity; a fundamental part of an 
Interface is the type of information it returns: we have to define it 
as part of the Interface (including all recognized contexts), or we set 
ourselves up such that different subclasses may return their 
information differently.  Better to enforce it?  (Of course, if our 
interface a is returning an object, of a class that flattens itself 
differently in different contexts, then do we say the interface can 
only return object classes derived from that first object class?  And 
do we restrict the possible flattenings of the object class itself, 
using an interface, so subclasses of the returned obj can't muck with 
it and unintentionally violate our first interface (a)?... there's a 
can of worms, boy...)

Mike Lazzaro
Cognitivity (http://www.cognitivity.com/)




Re: Interfaces

2002-09-30 Thread Michael G Schwern

On Mon, Sep 30, 2002 at 10:12:48AM -0700, Michael Lazzaro wrote:
 Heck, I'll jump into this one, since I've been working in _way_ too 
 many OO variations lately, some of them inflicted upon myself.  While I 
 hope perl6 will allow extendable OO methodologies, the out-of-box one 
 needs to be as robust as possible.  Here's a strawman opinion we can 
 argue against:
 
 I originally thought I was going to argue that it should be the default 
 behavior (to avoid yet more cruft in the method prototype) but thinking 
 about it more, I'll make the case that yes, you should have to say is 
 interface, if that's what you mean.
 
 The reason being private methods; while the interfaces to an object 
 must remain consistent, I don't think we should enforce the same rigor 
 on internal methods of a class.

Internal methods would simply be declared private and not be inherited, so
its not a problem.

method _do_internal_init ($num) is private {
   ...
}

Last I heard, Perl 6 will have basic privacy enforcement, something like the
above.


 Will interfaces be ignorable?
 
 ... and if we _do_ say any of the above, then they are not ignorable, 
 on pain o' death.  I'd argue there shouldn't be any way around it, 
 period, or we lose the whole point of the implied consistency.  Can 
 anyone think of a counterexample?

If I inherit from some parent which is well designed except for one really
poorly designed method.

Or maybe the parent class uses a really good name for a really silly
purpose, and I want that name back.

Or maybe I do want to deliberately have a subclass which is different than
the parent.

Or maybe the parent accidentally inherits something, perhaps via multiple
inheritence, and now I'm suck with it.

Not all subclasses are simply functional extensions of the parent.  In these
cases I should have a way to get around the interface restriction, probably
as an attribute to the overriding method.

OTOH, Java interfaces have a loophole which is considered a design mistake.
An interface can declare some parts of the interface optional and then
implementors can decide if they want to implement it or not.  The upshot
being that if you use a subclass in Java you can't rely on the optional
parts being there.

This comes down to an OO philosophy issue.  If Perl 6 wants a strict OO
style, don't put in a loophole.  If they want to leave some room to play,
put in the ability to turn some of the strictness off.


 What if a subclass adds extra, optional arguments to a method, is that 
 ok?
 
 This is the scariest question, I think...  In theory, yes, there are 
 lots of potential interfaces that would benefit from optional 
 extensions,  I've made a few.  In strict terms, though, they violate 
 the whole idea of common, invariant interface, so I never know if 
 what I've done is Acceptable, or a Shameful Hack...  anyone care to 
 make a case either way on this one?

The child's interface still supports the complete interface of the parent,
so I don't see it as a problem.  Sure beats having to write a whole new set
of method names just because you want to add an extra argument on the end.


 What about the return type?  If you're doing strict OO it would be 
 nice to
 specify the signature of the return value as well, which will get
 interesting to be able to describe totally the various ways in which a
 method can return in different contexts.
 
 While I cannot conceive what monstrosity of syntax we could put in the 
 method prototype to say I want to return this type in this context, 
 and this type in this context, etc., etc.

To paraphrase Damian at YAPC::Europe, It's Damian's problem. ;)

 Better to enforce it?  (Of course, if our 
 interface a is returning an object, of a class that flattens itself 
 differently in different contexts, then do we say the interface can 
 only return object classes derived from that first object class?

Yes.  The object class is simply a return type.


 And do we restrict the possible flattenings of the object class itself, 
 using an interface, so subclasses of the returned obj can't muck with 
 it and unintentionally violate our first interface (a)?... there's a 
 can of worms, boy...)

At that point you want to use the Design By Contract features, probably via
a class invariant, to ensure that all your subclasses flatten the same way.


-- 

Michael G. Schwern   [EMAIL PROTECTED]http://www.pobox.com/~schwern/
Perl Quality Assurance  [EMAIL PROTECTED] Kwalitee Is Job One
In my day, we didn't have none of yer new-fangled token-pasting
operators!  We stuck the tokens together with our BARE HANDS and we
LIKED IT.
--  Mark-Jason Dominus fondly remembers perl 1.0
in [EMAIL PROTECTED]



RE: Interfaces

2002-09-30 Thread David Whipp

Michael Lazzaro wrote:
  What if a subclass adds extra, optional arguments to a 
  method, is that ok?
 
 This is the scariest question, I think...  In theory, yes, there are 
 lots of potential interfaces that would benefit from optional 
 extensions,  I've made a few.  In strict terms, though, they violate 
 the whole idea of common, invariant interface, so I never know if 
 what I've done is Acceptable, or a Shameful Hack...  anyone care to 
 make a case either way on this one?

I don't think that the addition of an optional parameter
violates any substitution principle: users of the base-class
interface couldn't use the extra params (because they're not in
the interface); but a user of the derived-class's interface
can use the extra power (because they are in that interface).
A derived class is always allowed to add things (thus, you can
weaken preconditions, stengthen postconditions, add extra
methods, return a more specific result, ...; but you can't
strengthen a precondtion, nor weaken a postcondition, etc.)


On a slightly different note, if we have interfaces then I'd really
like to follow the Eiffel model: features such as renaming methods
in the derived class may seem a bit strange; but they can be useful
if you have have name-conflicts with multiple inheritance. Oh yes,
and we need to make sure DBC stuff is part of the interface, not
the implementation.


Dave.



Interface lists (was Re: Interfaces)

2002-09-30 Thread Michael G Schwern

On Tue, Oct 01, 2002 at 01:36:19AM +0100, Simon Cozens wrote:
 [EMAIL PROTECTED] (Michael G Schwern) writes:
  method _do_internal_init ($num) is private {
 
 Just thinking aloud, would 
 sub foo is method is private is integer is fungible {
 
 be better written as
 sub foo is fungible private integer method {
 
 or not?

How about seperated by commas, like any other list?

  method foo is fungible, private, integer {


-- 

Michael G. Schwern   [EMAIL PROTECTED]http://www.pobox.com/~schwern/
Perl Quality Assurance  [EMAIL PROTECTED] Kwalitee Is Job One
That's what Jagulars always do, said Pooh, much interested.  They call
'Help! Help!' and then when you look up they drop down on you.



Re: Interfaces

2002-09-30 Thread Michael G Schwern

On Mon, Sep 30, 2002 at 06:04:28PM -0700, David Whipp wrote:
 On a slightly different note, if we have interfaces then I'd really
 like to follow the Eiffel model: features such as renaming methods
 in the derived class may seem a bit strange; but they can be useful
 if you have have name-conflicts with multiple inheritance. 

I'm not familiar with the Eiffel beyond it's the DBC language and it's
French, but wouldn't this simply be covered by aliasing?

Which I guess raises the question, is a method's signature and attributes
part of the method itself, or it's name?  In other words, do aliases to the
same method carry the same signature and attributes?


 Oh yes, and we need to make sure DBC stuff is part of the interface, not
 the implementation.

Sensible.


-- 

Michael G. Schwern   [EMAIL PROTECTED]http://www.pobox.com/~schwern/
Perl Quality Assurance  [EMAIL PROTECTED] Kwalitee Is Job One
Playstation?  Of course Perl runs on Playstation.
-- Jarkko Hietaniemi



Re: Interface lists (was Re: Interfaces)

2002-09-30 Thread Frank Wojcik

On Mon, Sep 30, 2002 at 11:16:20PM -0400, Michael G Schwern wrote:
 How about seperated by commas, like any other list?
 
 method foo is fungible, private, integer {

Well, if we're going to use a /list/, how about

  method foo ($param) ^is (fungible, private, integer) {

?

:) 1/2