Re: RFC 218 (v1) Cmy Dog $spot is just an assertion
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
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
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
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
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
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
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
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
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
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
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
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
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