Re: Stupid Newbie Question

2001-11-09 Thread Piers Cawley

Dan Sugalski [EMAIL PROTECTED] writes:

 At 04:21 PM 11/8/2001 -0800, John Rudd wrote:
So, does this mean my other heart's desire of operator overloading might
be coming forth?  (I know, I know, here I am, a smalltalker, asking for
operator overloading ... but, what are the smalltalkers gonna do, take
away my membership card?)
 
 What, you mean being able to override the + function for a variable,
 complete with method dispatch depending on the types of the variables
 on both sides of the +?
 
 Yup ;)

Um, you do realise you don't need multi dispatch to do operator
overloading don't you?

package Foo;

use overload 
'+' = my_add,
...
;
   
sub my_add {
my $self = shift;
my $target = shift;

$target-add_Foo($self);
}

...

And we can do that today. 'cept it's something of a PITA because
'real' numbers don't respond to object methods.

Every so often I find myself thinking 'I should implement something
that automagically turns all numbers and strings into objects', but
there's always something more important to do.

-- 
Piers

   It is a truth universally acknowledged that a language in
possession of a rich syntax must be in need of a rewrite.
 -- Jane Austen?



Re: RFC 319 (v1) Transparently integrate Ctie

2000-09-27 Thread Piers Cawley

Nathan Wiger [EMAIL PROTECTED] writes:

  I'm kind of curious to know what you think would happen with the
  following. I've commented where I'm confident...
  
  interface Number;
  sub TIESCALAR;
  sub STORE;
  sub FETCH;
  
  package integer implements Number; # I really like this notation
 
 Tangentially, yes, it is nice to read, but it prevents multiple
 interface specifications. "use interface" is more consistent.

It does?

   package integer implements qw/Number Countable/;

Et viola.

 
  sub TIESCALAR {...};
  sub STORE {...};
  sub FETCH {...};
  
  my Number $i;   # Number is an interface, so just an assertion
  my integer $n;  # integer-TIESCALAR($n);
  my non_tied $object;# Just an assertion
  defined($n);# Should be false
 
 Yes. The only potential gotcha is if the user decides to do something
 Really Evil and stores a value as part of their TIESCALAR method. Then
 $n-FETCH will return that value and defined($n) will be true.
 
 However, this is not the purpose of tie, and I think an appropriate
 response is: Don't Do That. I agree with both you and Damian that TIE*
 should be called on declaration for consistency. If a person doesn't
 know how to use tie, well, that's not our problem. ;-)
 
  $n = 5;
  $i = $n;
  $n = 10;
  print $i;
  $i = $object;   # Assertion fails
 
 Assuming you've set up your Cuse optimize restrictions appropriately,
 then yes. The key is really what 'non_tied' is setup as. If this is a
 builtin type that optimizes itself to be a string object, then yes it
 will fail. However, if 'non_tied' is just a synonym for 'float' (for
 some odd reason) then the last line will be ok.

I think you're missing the point. What does 'print $i' print? What
happens if you do C$n = $i? Does $i 'remember' that the number that
got assigned to it is an integer? What is the mechanism for that? It
seems that there will need to be some pretty far reaching changes to
Perl if you want this to do the Right Thing. Assuming we know what the
Right Thing is.

 
  my int @b :64bit;   # again, just an assertion
  
  Asserting what? That's not valid syntax at the moment.
 
 But it will be. :-) See RFC 279.

Ah. I'll marshall arguments there then.

  
  @c = @b;# empty list passed still
  @b = (1,2); # int-TIEARRAY(@a, '64bit'); @b-CLEAR(...);
  
  Hmm... I think this is somewhat ugly. Assuming that you want
  Cmy int @b to imply CUNIVERSAL::isa(all(@a), 'int') then tying the
  entire array seems a bit weird.
 
 Not necessarily. The key is: *how* would you implement the assertion
 check? 
 
 If you use tie, then your int class STORE method can do something like
 this:
 
package int;
use base 'var';
# take defaults from var class
STORE {
   if ( self-isa($_[1]) ) {
  SUPER-STORE($_[0], $_[1]);   # internally store
   } else {
  die "Bad data $_[1]" if ( $under_strict_types );
   }
}

Having the programmer implement this assertion check (or not) is a
Very Bad Idea. Assuming we're expecting to get some compiler
optimization from this then things should be enforced rather more
robustly.

  Er... You seem to be implying here that *all* classes should have TIE
  methods. Which is not good.
 
 No, I wasn't trying to imply that, I'll clarify this point. TIE methods
 are still completely optional. 

Okay. It's just that your example that I quoted and you cut out seems
to imply otherwise.

  Err... Specifying which classes implement an interface in the
  interface specification is Wrong Wrong Wrong.
 
 Yes, you're right,

Phew.

  Can I just point out that nobody has yet proposed that you can attach
  attributes to a package?
 
 Didn't Damian propose Cpackage Foo : interface already? ;-)

Not in an RFC, no.

  I'm not entirely sure what you're driving at here. I thought you were
  arguing that *all* packages that created objects would use tie magic,
  in which case the new attribute becomes unnecessary. And if you're not
  proposing that then :tie is too general in the cases where the module
  can only tie to specific variable types. I think you get better
  granularity with interfaces, which are way more general than a special
  new attribute.
 
 No, let me back up a little. The idea is to make it so that tied
 interfaces - which are really different beasts from OO interfaces
 altogether because of their purpose - should be more closely integrated
 into Perl 6. This would allow you to create custom, optimized,
 strongly-typed variables that would function just like builtins:
 
my Matrix @a = ([1,2,3], [4,5,6]);
my NISMap %map :passwd = read_passwd_file();
my Apache::Session %session :transaction;
 
 However, this is not to overshadow OO interfaces, which are needed for
 functional methods, as you note.
 
 The :tie attribute is a poorly chosen name. The original name was
 :implicit, and was going to be attached to the TIE subs:
 

Re: RFC 161 (v4) Everything in Perl becomes an object.

2000-09-27 Thread Piers Cawley

Simon Cozens [EMAIL PROTECTED] writes:

 On Wed, Sep 27, 2000 at 05:25:28AM -, Perl6 RFC Librarian wrote:
  Not an awful lot was said once this RFC was condensed down to "Everything
  becomes an object". I believe some implementation and conceptual hurdles
  exist which have discouraged more serious discussion. At the suggestion of
  others I've opted to freeze rather than withdraw.
 
 How might I persuade you to reconsider?

I was kind of hoping that this one would get withdrawn as well.

-- 
Piers




Re: RFC 319 (v1) Transparently integrate Ctie

2000-09-26 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
 
 Transparently integrate Ctie

On the whole I think I'm liking this. But it needs work.

my packed $a;   # just an assertion, RFC 218
$a = get_binary;# packed-TIESCALAR($a); $a-STORE(..);

I'm not sure there's any reason to delay the tie; It kind of depends
on what happens to stuff like 'defined($a)'. RFC 218 was brought
forward because I didn't want magic to be happening in cases where
Cmy Foo $bar was using a Foo that was a superclass, and there was no
mechanism for knowing that at the time. 

I'm kind of curious to know what you think would happen with the
following. I've commented where I'm confident...

interface Number;
sub TIESCALAR;
sub STORE;
sub FETCH;

package integer implements Number; # I really like this notation
sub TIESCALAR {...};
sub STORE {...};
sub FETCH {...};

my Number $i;   # Number is an interface, so just an assertion
my integer $n;  # integer-TIESCALAR($n);
my non_tied $object;# Just an assertion
defined($n);# Should be false

$n = 5;
$i = $n;
$n = 10;
print $i;   
$i = $object;   # Assertion fails

$a = more_data; # $a-STORE(...);
$a++;   # $a-STORE($a-PLUS(1));
undef $a;   # $a-DESTROY;
 
my int @b :64bit;   # again, just an assertion

Asserting what? That's not valid syntax at the moment.

@c = @b;# empty list passed still
@b = (1,2); # int-TIEARRAY(@a, '64bit'); @b-CLEAR(...);
...

Hmm... I think this is somewhat ugly. Assuming that you want
Cmy int @b to imply CUNIVERSAL::isa(all(@a), 'int') then tying the
entire array seems a bit weird.

 Note that the CTIE* methods will only be called if they exist, just
 like currently. If a given CTIE* method does not exist, then the
 appropriate error should be spit out:
 
my Pet @spot = ("fluffy");
Can't locate method "TIEARRAY" via package "Pet"
 
 In this case, the package CPet has declared that it can't handle
 arrays, which is just fine.

Er... You seem to be implying here that *all* classes should have TIE
methods. Which is not good. It's especially not good in cases where
the class is actually an interface. Hmm... maybe we should have the tie
behaviour only happen if the package is declared as implementing an
appropriate 'Tie::Foo' interface:

package integer implements Tie::Scalar;

Note that this would imply that the Tie::Foo modules in the standard
library become interfaces, but I'm not sure that that would be any
great loss...

 =head2 Optimization and Inheritance
 
 One of the main goals behind doing something like this is being able to
 create custom variable types that can take advantage of optimizations,
 and having these variables walk and talk like builtins.
 
 For this reason, it is further proposed that all variable types be
 handled through basic method inheritance in Perl 6. Essentially,
 everything becomes an object and is fully overrideable and redefineable.
 So, for example:

Whoa, now you're stretching.

 [...]

 =head2 Type checking
 
 Nat's upcoming RFC on type checking will propose a Cuse strict 'types'
 pragma. Type checking would be trivial to implement by combining aspects
 of this RFC with the Cuse optimize concept:
 
package Pet : interface;   # RFC 265
use optimize types = ['Dog', 'Cat'];
 
 With this declaration, Perl is now told that anything of type CPet can
 be either a CDog or a CCat. 

Err... Specifying which classes implement an interface in the
interface specification is Wrong Wrong Wrong.

 This means that in your main code:
 
use strict 'types';
my Pet $spot = new Camel;   # oops!
 
 The second line would raise a syntax error.

If your client code wants to insist that the only pets it's interested
in are Dogs or Cats then you should make that assertion somewhere.
You certainly shouldn't assert it in the interface declaration.
Check out the 

my Pet $spot : isa(any(qw/Dog Cat/)) = new Camel; # oops!

style that I proposed elsewhere.

 =head2 The C:tie attribute
 
 Making Ctie this seamless may scare some people. In this case, we may
 wish to add an C:tie attribute that can be specified on the
 Cpackage:
 
package Pet : tie; # will be auto-tied

Can I just point out that nobody has yet proposed that you can attach
attributes to a package?

 
 Placing this on the package, and not individual subs, makes more sense
 because it dictates how all the package's methods interact.
 
 The idea here is that by fully integrating these concepts, a separate
 Ctie function will no longer be necessary and will instead be replaced
 by a simple C:tie package attribute (or no attribute at all).

I'm not entirely sure what you're driving at here. I thought you were
arguing that *all* packages that created objects would use tie magic,
in 

Re: RFC 265 (v1) Interface polymorphism considered lovely

2000-09-21 Thread Piers Cawley

Nathan Wiger [EMAIL PROTECTED] writes:
  * The new Cinterface keyword would be unnecessary if *package
specifications* could take attributes:
  
  interface Fetcher;
  
would then become:
  
  package Fetcher : interface;
 
 I'm not sure about this - seems like we're squeezing a whole bunch of
 stuff into "package" that's not a package.
 
 If an interface can't have variables, real methods, or do anything, then
 a separate keyword seems in order. Looking at this:
 
interface Fetcher;
 
 Makes it much more obvious "Ok, here's an interface, not a package.
 I can't stick 'real stuff' in here". However, if we are going to
 potentially add many more attributes, like
 
package int : variable;# custom var for "my int $x = 5";
 
 then perhaps attributes are the way to go after all.
 
 It should also be a compile-time error for an interface to contain
 anything except sub definitions (and possibly constant variables). I
 didn't see that mentioned, but I could have missed it.

Good point

 * There's also no need to distinguish Cuse base and Cuse
   interface,
 
 Again, I'm not sure. As the RFC shows, it's quite easy to imagine a
 situation where you have a tangential interface specification that
 does *not* serve as the inheritance point for your class:
 
package TrainedCat;
 
use strict 'implementation';
  
use base 'Cat';
use interface 'Fetcher';
 
 I can see many potential uses for keeping interfaces and classes
 separate.
 
 Finally, maybe that should be "use strict 'interface'" ?

Ah, no. I wanted to draw a distinction between being strict about a
package properly implementing an interface and to use
Cuse strict 'interfaces' in client code to tell the compiler to
throw an error if I try to use a method that isn't declared for that
interface. 




Re: RFC 265 (v1) Interface polymorphism considered lovely

2000-09-21 Thread Piers Cawley

Nathan Wiger [EMAIL PROTECTED] writes:

 By specifying "use interface" explicitly, you can make sure that your
 class follows the interface spec. Otherwise, you rely on other classes
 in the hierarchy above you doing so, and then you indirectly inheriting
 from that interface. So "use interface" is really the only way you can
 make sure somebody else didn't screw up. ;-) On large projects I think
 this would be an essential safety check, just like "use strict".
 
 -Nate
 
package Pet : interface;
 
sub isborn (@);
sub scratches ($\@;@);
sub annoys (\@);
sub costsmoney ();
sub poopsonfurniture ($);

Whoa Nellie. When did we get prototyping for methods. (Not that I'm
objecting, I think strict interfaces might actually make this
possible. The wisdom of it is left as an exercise...)

package Cat;
 
use interface 'Pet';
 
sub isborn {
bless { @_ }, self;   # ;-)
}
sub scratches ($\@;@) {
...
}
sub annoys (\@) {
...
}
sub costsmoney () {
...
}
sub poopsonfurniture ($) {
...
}
 
 
package Doggie;
 
sub isborn {
bless { @_ }, self;   # ;-)
}
sub scratches ($\@;@) {
...
}
 
 
package Doggie::Cute;
 
use base 'Doggie';
use interface 'Pet';
 
# Our base class is 'Doggie', which does not use the 'Pet'
# interface (perhaps unbeknownst to us!). Nonetheless, we use
# the 'Pet' interface to make sure that our class is implemented
# correctly.
 
# code would follow...

This could still be Cuse base 'Pet' and it would work you know. The
reasoning behind seperating Cuse base and Cuse interface (for me)
is simply because of the mnemonic assistance to the programmer.
interface.pm could easily be a duplicate of base.pm with the added
restriction that that the package so included *must* be an interface.
I'm not irrevocably tied to it...

-- 
Piers




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: Draft RFC: new pragma: Cuse namespace

2000-09-14 Thread Piers Cawley

Graham Barr [EMAIL PROTECTED] writes:

 I would suggest that anyone want to contribute to this discussion should
 first read the thread about the addition of this pragma to perl5 in
 the perl5-porters archives
 
 
http://www.xray.mpe.mpg.de/cgi-bin/w3glimpse/perl5-porters?query=use+namespace+pragmaerrors=0case=onmaxfiles=100maxlines=30

Ah. Sorry I didn't post that url with the RFC.

-- 
Piers




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: Draft RFC: my Dog $spot is just an assertion

2000-09-13 Thread Piers Cawley

Damian Conway [EMAIL PROTECTED] writes:

 Piers wrote:
 
 The behaviour of the my Dog $spot syntax should simply be an
 assertion of the invariant: 
 
(!defined($spot) || (ref($spot) $spot-isa('Dog)))
 
 (!defined($spot) || (ref($spot)  $spot-isa('Dog')))
 
 
 Otherwise, AMEN!

Oopsie.




Re: Draft RFC: new pragma: Cuse namespace

2000-09-13 Thread Piers Cawley

Hildo Biersma [EMAIL PROTECTED] writes:

 Piers Cawley wrote:
  =head1 ABSTRACT
  
  Cmy Big::Long::Prefix::Class $object = Big::Long::Prefix::Class-Egtnew
  is a pain in the bum to type. We should replace this with
  
  use namespace 'Big::Long::Prefix';
  my ::Class $object = ::Class-new;
 
 This is a bit dangerous, since we can get into ambiguities again.
 If I have A::B::C::Foo,  A::B::C::Bar, X::Y::Z::Foo and X::Y::Z::Bar,
 I'd like to use shorthands for A::B::C's Foo and X::Y::Z's Bar at the
 same time.

Well you can't. The patch that I pinched this RFC from is a lexically
scoped affair, so if you want to use a different namespace somewhere
else you are free to do so:

use namespace 'A::B::C';
my ::Foo = ::Foo-new;
use namespace 'X::Y::Z';
my ::Foo = ::Foo-new

should work.

-- 
Piers




Draft RFC: my Dog $spot is just an assertion

2000-09-12 Thread Piers Cawley

=head1 TITLE

Cmy Dog $spot is just an assertion

=head1 VERSION

  Maintainer: Piers Cawley [EMAIL PROTECTED]
  Date: 12th September 2000
  Last Modified: 12th September 2000
  Mailing List: [EMAIL PROTECTED]
  Version: 0
  Status: Draft

=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.  

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. 

=head2 Examples

In class methods:

package Dog;
sub speak {
my Dog $self = shift; # Sadly 'my __PACKAGE__ $self' doesn't work
print $self-name, " barks!\n";
}

Admittedly, this makes little sense unless there is some optimization
available, but it can still be useful as a notational convenience.

Or, consider the case where you have an CAnimalShelter object and
you're looking to get a Dog from there.

my AnimalShelter $shelter = RSPCA-find_nearest_shelter;
my Dog $stray;

try {
PET: while (!defined($stray)) {
$stray = $shelter-next_animal;
}
}
catch Exception::WrongClass {
next PET;
}
$stray-bark;

Admittedly this makes some assumptions about the possibility of loops
within try blocks, but I think the point is still valid.

My main concern with this proposal is to make it possible to use the
Cmy Dog $spot syntax along with it's associated (posited)
optimizations and assertions wherever it's appropriate in user code. 

=head1 IMPLEMENTATION

I've not really looked into using source filters, but if 
Cmy Dog $spot can be mapped to
Ctie my $spot, Tie::Invariant, 'Dog' then Tie::Invariant can look
something like:

package Tie::Invariant;
use carp;

sub TIESCALAR {
my $self = bless {value = undef}, shift;
$self-{class} = shift;
return $self;
}

sub FETCH {
my $self = shift;
return $self-value;
}

sub STORE {
my($self,$newval) = @_;

if (!defined($newval) || (ref($newval) 
  UNIVERSAL::isa($newval, "UNIVERSAL") 
  $newval-isa($self-{class}))) {
croak "Value must be 'undef' or be a $self-{class}"
}
$self-{value} = $newval;
}

=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.

=head1 REFERENCES

RFC 171: my Dog $spot should call a constructor implicitly

This RFC is a counter RFC to RFC 171. See my forthcoming
'new pragma: use package' RFC for something that addresses one of the
concerns of RFC 171.

RFC 137: Overview: Perl OO should Inot be fundamentally changed

My guiding principle.

-- 
Piers


 





Re: RFC 193 (v1) Objects : Core support for method delegation

2000-09-05 Thread Piers Cawley

Michael G Schwern [EMAIL PROTECTED] writes:

 On Mon, Sep 04, 2000 at 09:53:39PM -, Perl6 RFC Librarian wrote:
  Objects : Core support for method delegation
 
 I like it!  One gripe (of course)...
 
 
  The proposed delegation mechanism would work via a pragma:
  
  use delegation
  attr1 = [qw( method1 method2 method3 )],
  attr2 = [qw( method4 method5 )],
  attr3 = [],
  attr4 = [],
 
 I will often use a more complicated data structure for my objects,
 often organizing all sub-objects into a hash of hashes...
 
 $obj-{locks}{MacOSX} = $macosx_obj;
 $obj-{locks}{Mac}= $mac_obj;
 $obj-{locks}{BSD}= $bsd_obj;
 
 which is nice when you stuff alot of things into an object.  If I
 wanted to deligate to those objects in $obj-{locks}, how would I
 under your proposal?

Flatten the hierarchy? Make your aggregations into classes themselves
and set up delegation rules there?

 
 In a similar vein, I can see a use for wanting to deligate a set of
 methods to an entire list of objects.  Consider...
 
 $obj-{locks} = [$macosx_obj, $mac_obj, $bsd_obj];
 
 it would be nice to be able to state that "method1" should deligate to
 each object in the $obj-{locks} list until it is found.

package ListOfObjects;

use strict;
use Symbol qw/gensym/;

sub new {
my($class) = shift;
my $self   = bless {}, ref($class) || $class;
$self-push(@_);
}

sub push {
my $self = shift;
while (shift) {
my $attr = gensym;
$self-{$attr} = $_;
use delegate $attr = [];
}
}


 Also, what happens when a deligated attribute does not contain an
 object when Perl checks?  Should it produce a warning?  I'd say no.  I
 can easily see cases where you'd like to be able to deligate to
 objects which may or may not be instanciated at run-time.  If a
 warning was issued, it would be difficult to circumvent.  You'd have
 to place a dummy object in that slot.

You know, this may be a case for Mister Fowler's RFC about auto
instantiated objects. Except CDog $self-{attr} isn't actually valid
syntax is it? There's certainly a case for just using the (singleton)
null object as a placeholder until a real object comes along, and it
can solve a host of other problems.

--
Piers




Re: RFC 193 (v1) Objects : Core support for method delegation

2000-09-05 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
 
 Objects : Core support for method delegation

I *want* this. Delegation is cool. Delegation that gets set up at
compile time and is marked as such and can thus be optimized is
*really* cool.

-- 
Piers




Re: RFC 171 (v2) my Dog $spot should call a constructor implicitly

2000-09-04 Thread Piers Cawley

Michael Fowler [EMAIL PROTECTED] writes:

 On Fri, Sep 01, 2000 at 05:23:27PM +0200, Slaven Rezic wrote:
  Often, there is the case that "my" is used before actually assigning a
  value to it. For example:
  
  my Foo $foo;
  if ($cond1) {
  $foo = new Foo 1, 2, 3;
  } else {
  $foo = new Foo 2, 4, 6;
  }
  
  If we have implicit constructors, will this cause unnecessary
  overhead, that is, calling the implicit constructor and then the real
  one?
 
 Yes, so don't do that.  If you want optimization, I've been suggesting my
 $spot : isa(Dog) (actually, I've been suggesting my $spot isa(Dog), which
 was a typo):


But that's *so* ugly for the (In my code at least) more common case.
If all you want this behaviour for is to save typing, what about
simply *extending* the current syntax so you'd one of:


my new Dog $spot;# Not sure the parser'd like that.
my Dog $spot : from(new); # same as 'my Dog $spot = Dog-new

Actually, I kind of like the second one (though I'm not sure 'from' is
the right name) as it allows you to specify the appropriate
constructor. The advantage of this is that the existing syntax still
works so that those of us who are already using it in anticipation of
the glorious day when we finally get some optimization from it won't
have to rethink the way we do things. Okay, if you want the new
behaviour you have to learn the new syntax, but hey, that's why it's
new. 

-- 
Piers




Re: RFC 188 (v1) Objects : Private keys and methods

2000-09-04 Thread Piers Cawley

"David E. Wheeler" [EMAIL PROTECTED] writes:

 On 1 Sep 2000, Perl6 RFC Librarian wrote:
 
  This and other RFCs are available on the web at
http://dev.perl.org/rfc/
  
  =head1 TITLE
  
  Objects : Private keys and methods
 
 Here, here  amen, Damian! This one gets my instant vote!

And mine.




Re: RFC 171 (v1) my Dog $spot should call a constructor implicitly

2000-08-30 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
 
 my Dog $spot should call a constructor implicitly

Eeeeww. Most of the time I use 'my Dog $spot' is along the lines
of:


package Dog;

sub bark {
my Dog $self = shift;
print $self-name, " barks!\n";
}
 
package Main;

my Dog $spot = Dog::Dalmation-new(name = 'Spot');
$spot-bark;


Or what about:

my Dog $patches = $dog_pound-get_cute_stray;

There's a whole host of occasions when you want 'my Dog $spot' but you
*don't* want $spot to be set to Dog-new.

-- 
Piers




Re: $ME in a method called as a subroutine

2000-08-23 Thread Piers Cawley

Markus Peter [EMAIL PROTECTED] writes:

 --On 22.08.2000 18:24 Uhr + David L. Nicol wrote:
 
 
  Regardless of what its called, in a method called as a subroutine,
  the variable could refer to the last instance of this kind of object
  used by this thread.
 
 Hmm Does that mean if I once all $obj-method() and then afterwards
 somewhere else obj::method() then $ME or whatever it is called still holds
 $obj ? If yes, why? I can imagine _some_ cases where that's useful, 
 especially if someone is sloppily mixing procedural and object oriented 
 programming, but I can also imagine many more cases where it adds 
 confusion.
 
 In my opinion the contents of $ME should allow to determine wether it was 
 called as a procedure or as a method, the easiest way to do that is undef 
 for procedure, object for method and classname for class methods.

Procedure reference for a procedure call please. It makes for some
nice wins with anonymous subroutines...

-- 
Piers




Re: RFC 137 (v1) Overview: Perl OO should Inot be fundamentally changed.

2000-08-22 Thread Piers Cawley

Perl6 RFC Librarian [EMAIL PROTECTED] writes:

 =item *
 
 Changes to the semantics of Cbless so that, after associating an
 object with a class, the class's CINIT methods are automatically
 called on the object. An additional trailing C@ parameter for
 Cbless, to allow arguments to be passed to CINIT methods.

Ooh:

sub INIT {
$ME-_init unless $ME-initialized;
my $tok = $ME-parser-next_token;
my $next_state = $ME-handle($tok);
bless $ME = $next_state;
}

That OO state machine idea I keep toying with gets more and more
scary. Of course, the call stack could get rather deep...

-- 
Piers