Re: RFC 218 (v1) Cmy Dog $spot is just an assertion

2000-09-19 Thread Piers Cawley

Michael G Schwern [EMAIL PROTECTED] writes:

 On Mon, Sep 18, 2000 at 09:48:27AM +0100, Piers Cawley wrote:
  Michael G Schwern [EMAIL PROTECTED] writes:
   Nope.  fields::new() basically just does Cbless
   [\%{"$class\::FIELDS"}], $class, but the current pseudohash
   implementation doesn't care if something is an object or not.  It just
   cares about either A) its type or B) what's in $ph-[0].
  
  Hmm... it still feels like undocumented behaviour. I'd definitely be
  inclined to tighten up the base/fields behaviour. My feeling is that
  the proposal makes them closer to the Right Thing.
 
 Its plenty documented.  But if we simply put a bullet into
 pseudo-hashes, as per RFC 241, this all goes away.

Indeedly.

-- 
Piers




Re: RFC 218 (v1) Cmy Dog $spot is just an assertion

2000-09-18 Thread Piers Cawley

Michael G Schwern [EMAIL PROTECTED] writes:

 On Thu, Sep 14, 2000 at 02:19:38PM +0100, Piers Cawley wrote:
  Michael G Schwern [EMAIL PROTECTED] writes:
   package Dog;
   use fields qw(this night up);
   
   my Dog $ph = [];
   $ph-{this} = "that";
  
  That works? I thought you had to do:
  
my Dog $self = fields::new('Dog');
 
 Nope.  fields::new() basically just does Cbless
 [\%{"$class\::FIELDS"}], $class, but the current pseudohash
 implementation doesn't care if something is an object or not.  It just
 cares about either A) its type or B) what's in $ph-[0].  I don't know
 if this is a good thing or a bad thing, but there's nothing on the
 table to change it (yet).
 
 my Dog $ph = [];
 $ph-{this} = "that";
 
 deparses at compile-time to:
 
 my Dog $ph = [];
 $ph-[$Dog::FIELDS{this}] = "that";  # actually the %FIELDS lookup is also
  # done at compile time, but I left
  # it in for illustration.

Hmm... it still feels like undocumented behaviour. I'd definitely be
inclined to tighten up the base/fields behaviour. My feeling is that
the proposal makes them closer to the Right Thing.

-- 
Piers




Re: RFC 218 (v1) Cmy Dog $spot is just an assertion

2000-09-18 Thread Piers Cawley

Damian Conway [EMAIL PROTECTED] writes:

 Piers wrote:
  
 I'm kind of tempted to look at adding another pragma to go with 'use
 base' along the lines of:
 
  use implements 'Interface';
 
 Which is almost entirely like Cuse base 'Interface' but with
 'Interface' consisting of nothing but:
 
 
  package Interface;
 
  sub virtual_method;
  sub virtual_method2 (#prototype);
   
  ...
 
  1;
 
 You and I must have been separated at birth, Piers.
 
 Here's what I wrote to Nat just yesterday:
 
 [ Neat 'interfaces' sketch ]
 
 If you'd like to run with it, be my guest (but check with Nat first, in 
 case he wants it).

I'm not going to have time to produce an RFC on this in time for the
cutoff point. (Which seems painfully soon tbh). It's a shame there's
no way to put down a marker (maybe a title + summary) for an RFC that
one intends to flesh out Real Soon Now, but which won't be ready for
the deadline...

-- 
Piers




Re: RFC 218 (v1) Cmy Dog $spot is just an assertion

2000-09-18 Thread Michael G Schwern

On Mon, Sep 18, 2000 at 09:48:27AM +0100, Piers Cawley wrote:
 Michael G Schwern [EMAIL PROTECTED] writes:
  Nope.  fields::new() basically just does Cbless
  [\%{"$class\::FIELDS"}], $class, but the current pseudohash
  implementation doesn't care if something is an object or not.  It just
  cares about either A) its type or B) what's in $ph-[0].
 
 Hmm... it still feels like undocumented behaviour. I'd definitely be
 inclined to tighten up the base/fields behaviour. My feeling is that
 the proposal makes them closer to the Right Thing.

Its plenty documented.  But if we simply put a bullet into
pseudo-hashes, as per RFC 241, this all goes away.

-- 

Michael G Schwern  http://www.pobox.com/~schwern/  [EMAIL PROTECTED]
Just Another Stupid Consultant  Perl6 Kwalitee Ashuranse
But why?  It's such a well designed cesspool of C++ code.  Why wouldn't
you want to hack mozilla?
-- Ziggy



Re: RFC 218 (v1) Cmy Dog $spot is just an assertion

2000-09-14 Thread Piers Cawley

Perl6 RFC Librarian [EMAIL PROTECTED] writes:

 This and other RFCs are available on the web at
   http://dev.perl.org/rfc/
 
 =head1 TITLE
 
 Cmy Dog $spot is just an assertion
 
 =head1 VERSION
 
   Maintainer: Piers Cawley [EMAIL PROTECTED]
   Date: 13th September 2000
   Mailing List: [EMAIL PROTECTED]
   Number: 218
   Version: 1
   Status: Developing
 
 =head1 ABSTRACT
 
 The behaviour of the my Dog $spot syntax should simply be an
 assertion of the invariant: 
 
(!defined($spot) || (ref($spot)  $spot-isa('Dog)))
 
 =head1 DESCRIPTION
 
 The syntax 
 
 my Dog $spot = Dog-new();
 
 currently carries little weight with Perl, often failing to do what
 one expects:
 
 $ perl -wle 'my Dog::$spot; print "ok"' 
 No such class Dog at -e line 1, near "my Dog"
 Execution of -e aborted due to compilation errors.
 $ perl -wle 'sub Dog::new; my Dog $spot; print "ok"'
 ok
 $ perl -wle 'sub Dog::new; my Dog $spot = 1'
 ok
 
 The first example is obvious, as is the second. The third one is
 Iweird.  

Actually, it's *very* weird given that there's no code to print 'ok'.
Which is bad.

  $ perl -wle 'sub Dog::new; my Dog $spot = 1; print "ok"'

That's better.

-- 
Piers




Re: RFC 218 (v1) Cmy Dog $spot is just an assertion

2000-09-14 Thread Piers Cawley

Nathan Torkington [EMAIL PROTECTED] writes:

 Perl6 RFC Librarian writes:
  I therefore propose that Cmy Dog $spot comes to mean that C$spot
  is restricted to being either undefined or a reference to a CDog
  object (or any subclasses of Dog). Simply having this implicit
  assertion can be useful to the programmer, but I would argue that its
  main advantage is that the compiler knows the object's interface at
  compile time and can potentially use this fact to speed up method
  dispatch. 
 
 Yes!  I mentioned the hypothetical
   use strict 'types';
 which would require all variables assigned to/from an object, and
 all variables upon which method calls are made, to be typed like
 this.  Then the compiler can:
  (a) optimize
  (b) check at compile-time
 
 Your sample implementation is done through a Tie class, which is only
 runtime.  The big win is that if you check types like this (and it's
 a window into C's type-checking hell) then Perl knows types at
 compile-time.  If there's a formal interface specification for classes,
 the compiler can use this to check whether a method call is valid or
 not.  You can build calls to the correct subroutine into optree
 instead of delaying that lookup until runtime.
 
 Every compile-time check comes at the cost of a run-time freedom,
 though.  All bets would be off if you modified @ISA, reblessed, or
 passed objects through non-strict-types-compliant code.  Polymorphic
 types also becomes a problem: how to say that it's okay for a variable
 to hold a Dog *or* a Cat, because we know that both of them have a
 "pet()" method?
 
 I'd love to see these suggestions incorporated into your RFC.  I was
 going to do it myself, but I have a lot of other things to RFC.

TBH, I'm not sure I want to go too far down that road in this RFC. And
tbh they seem more like internals issues to me. The runtime behaviour
this change grants is good enough for me and I don't want to see the
proposal bogged down in flamage about strict types. Of course, given
this RFC it's possible to add other RFCs that deal with specific
dependent language proposals and optimizations.

  =head1 MIGRATION
  
  Migration issues should be minor, the only problem arising when people
  have assigned things that aren't objects of the appropriate type to
  typed variables, but they deserve to lose anyway.
 
 Not if you made the checks and optimizations enabled by a pragma.
 Old programs wouldn't have it, so they could continue to do their
 stupid things and be fine.

Again, I'm not sure that I'd want to encourage such bogosity. After
all, if perl5 could introduce "@array" interpolation which broke stuff
I don't see why this one can't go through as the default.

-- 
Piers




Re: RFC 218 (v1) Cmy Dog $spot is just an assertion

2000-09-14 Thread Piers Cawley

Michael G Schwern [EMAIL PROTECTED] writes:

 On Wed, Sep 13, 2000 at 08:43:43PM -, Perl6 RFC Librarian wrote:
  The behaviour of the my Dog $spot syntax should simply be an
  assertion of the invariant: 
  
 (!defined($spot) || (ref($spot)  $spot-isa('Dog)))
 
 What about the current behavior of typed pseudohashes?
 
 package Dog;
 use fields qw(this night up);
 
 my Dog $ph = [];
 $ph-{this} = "that";

That works? I thought you had to do:

  my Dog $self = fields::new('Dog');

(In which case, as far as I can see, the proposal makes no difference.)

-- 
Piers




Re: RFC 218 (v1) Cmy Dog $spot is just an assertion

2000-09-14 Thread Nathan Torkington

Piers Cawley writes:
 TBH, I'm not sure I want to go too far down that road in this RFC. And
 tbh they seem more like internals issues to me. The runtime behaviour
 this change grants is good enough for me and I don't want to see the
 proposal bogged down in flamage about strict types. Of course, given
 this RFC it's possible to add other RFCs that deal with specific
 dependent language proposals and optimizations.

Ok, I'll work on the RFC for the type-checking.

Nat



Re: RFC 218 (v1) Cmy Dog $spot is just an assertion

2000-09-14 Thread Michael G Schwern

On Thu, Sep 14, 2000 at 02:19:38PM +0100, Piers Cawley wrote:
 Michael G Schwern [EMAIL PROTECTED] writes:
  package Dog;
  use fields qw(this night up);
  
  my Dog $ph = [];
  $ph-{this} = "that";
 
 That works? I thought you had to do:
 
   my Dog $self = fields::new('Dog');

Nope.  fields::new() basically just does Cbless
[\%{"$class\::FIELDS"}], $class, but the current pseudohash
implementation doesn't care if something is an object or not.  It just
cares about either A) its type or B) what's in $ph-[0].  I don't know
if this is a good thing or a bad thing, but there's nothing on the
table to change it (yet).

my Dog $ph = [];
$ph-{this} = "that";

deparses at compile-time to:

my Dog $ph = [];
$ph-[$Dog::FIELDS{this}] = "that";  # actually the %FIELDS lookup is also
 # done at compile time, but I left
 # it in for illustration.

-- 

Michael G Schwern  http://www.pobox.com/~schwern/  [EMAIL PROTECTED]
Just Another Stupid Consultant  Perl6 Kwalitee Ashuranse
Sometimes these hairstyles are exaggerated beyond the laws of physics
  - Unknown narrator speaking about Anime



Re: RFC 218 (v1) Cmy Dog $spot is just an assertion

2000-09-14 Thread Damian Conway

Piers wrote:
 
I'm kind of tempted to look at adding another pragma to go with 'use
base' along the lines of:

 use implements 'Interface';

Which is almost entirely like Cuse base 'Interface' but with
'Interface' consisting of nothing but:


 package Interface;

 sub virtual_method;
 sub virtual_method2 (#prototype);
  
 ...

 1;

You and I must have been separated at birth, Piers.

Here's what I wrote to Nat just yesterday:


There would be an Cinterface pragma or keyword (let's go
with keyword) that creates pseudo-packages with which lexicals
can be typed.

interface Fetcher;

sub fetch;

Interface specifications can only contain subroutine (method)
declarations, which describe what behaviours the interface requires.

Lexicals typed into interfaces (as opposed to packages) only require
that the objects assigned to them can satisfy the interface. I.e.
they don't care about the class of the object, only what is Ccan
do.

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 because Fetcher-can('fetch')
$x-bark(); # not ok because ! Fetcher-can('bark')


Interfaces might also act like pure abstract base classes when
inherited, so that:

package Dog;
use base 'Fetcher';

would cause a compile-time error if Dog failed to actually provide
a Cfetch method.


If you'd like to run with it, be my guest (but check with Nat first, in 
case he wants it).

Damian



Re: RFC 218 (v1) Cmy Dog $spot is just an assertion

2000-09-14 Thread Buddha Buck

At 08:13 AM 9/15/00 +1100, Damian Conway wrote:
Piers wrote:

 I'm kind of tempted to look at adding another pragma to go with 'use
 base' along the lines of:

  use implements 'Interface';

 Which is almost entirely like Cuse base 'Interface' but with
 'Interface' consisting of nothing but:


  package Interface;

  sub virtual_method;
  sub virtual_method2 (#prototype);

  ...

  1;

You and I must have been separated at birth, Piers.

Here's what I wrote to Nat just yesterday:


snip


 Interfaces might also act like pure abstract base classes when
 inherited, so that:

 package Dog;
 use base 'Fetcher';

 would cause a compile-time error if Dog failed to actually provide
 a Cfetch method.

I don't like that at all...

Currently, Object implementations can be changed at will at runtime.  In 
particular, it is possible to create new methods and change the class 
hierarchy at run time.

package TextFilter;
use CryptInterface;
@ISA = qw(CryptInterface);

sub AUTOLOAD {
   my $self = shift;
   ($name = $AUTOLOAD) =~ s/.*://;
   # Cryptography is very hairy and we don't want to load it if we don't
   # have to.
   if ($name = any(qw(setkey setcrypt encode decode)) {
  require Crypt;
  import Crypt;
  push @ISA,"Crypt";
  $self-$name(@_);  # I've not tried this, it may be wrong.
   }
}

I'd hate to have that break because TextFilter isn't derived from Crypt 
unless it needs to be.

I think calling a method declared in an inherited interface but not 
implemented would be a good reason to have a descriptive run-time error, like:

Method getkey in interface Crypt not implemented in TextFilter object at 
line

Well, perhaps written better...

If you'd like to run with it, be my guest (but check with Nat first, in
case he wants it).

Damian




Re: RFC 218 (v1) Cmy Dog $spot is just an assertion

2000-09-13 Thread Damian Conway

I was hoping Damian would be able to suggest a Perlish way of handling
typechecking and polymorphism. 

If you mean static typechecking, then it is the natural enemy of polymorphism.
Either you give up interface polymorphism (a grievous loss) or you give
up static type-checking.
   
Interface polymorphism leads to a proliferation of pointless classes.

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

Perhaps instead of using inheritance for this, just have "implements"
and formal interfaces.  Then associate a variable with an interface
instead of an object type.

  package Cat implements Pet;
  package Dog implements Pet;

  my Pet $foo;
  $foo-feed();


Not bad. Though I'd suggest a pragma:

package Cat;
use interface 'Pet';

my Pet $foo;
$foo-feed();


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 Cmust:

use attr_alias Pet = qw(feed water play poop);

my $foo : must(Pet)


Not sure which I like better. :-)

Damian



Re: RFC 218 (v1) Cmy Dog $spot is just an assertion

2000-09-13 Thread Nathan Torkington

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 Cmust:
 
   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