Re: RFC 319 (v1) Transparently integrate Ctie
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. 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. 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. @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 ); } } Now, there's a difference between _could_ do this and _must_ do this. The idea here is that you could do this, and users wouldn't see any difference between your custom types and builtin types. 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. Err... Specifying which classes implement an interface in the interface specification is Wrong Wrong Wrong. Yes, you're right, and it's way outside of this scope of this RFC, actually. Your idea: my Pet $spot : isa(any(qw/Dog Cat/)) = new Camel; # oops! is much better for this application. 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? ;-) 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: package Demo; sub TIESCALAR : implicit { ... } sub TIEHASH : implicit { ... } sub TIEARRAY { ... } So in this example, a user can say: my Demo $x; my Demo %x; my Demo @x; # TIEARRAY not called However, after thinking about this, I decided this was not a worthwhile distinction. How often would you want this behavior? So I decided to attach the attribute to the package: package Demo : implicit; But that really didn't connote what was going on. So I changed it to: package Demo : autotie; But then decided the 'auto' was redundant. However, the more
Re: RFC 265 (v1) Interface polymorphism considered lovely
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. No, it couldn't - notice that Doggie does not inherit from Pet. Unless there's something about OO inheritance that I'm really missing... 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. Yes, and I think that's a very worthwhile distinction. It also allows you to mandate that you use multiple interfaces and a different base to boot. This is a stretch but you should get the idea: package Solaris::Devices::Ethernet::GigEther; use base 'Solaris::Devices::Ethernet'; use interface 'Solaris::Kernel::Kmem'; use interface 'Solaris::Devices::Devtree'; But maybe I'm barkings up a different tree from you. But it seems that interfaces don't have to be constrained to just stub base class definitions. Instead, they can serve as specifications for class interaction as well as class implementation. If we keep "use interface" and "use base" separate then this becomes trivial to do (compile-time checks for proper method declarations/etc). -Nate
Re: RFC 200 (v2) Objects: Revamp tie to support extensibility(Massive tie changes)
Damian Conway wrote: I didn't see any mention of my plea that Ctie should pass the original variable being tied as one of its arguments. :-( That's because it's a dumb idea!! **Kidding!** I forgot about this, sorry. I'll add it to the next version ;-) my $x = 10; tie $x, 'ReadOnly'; print $x; # still prints 10 I feel that additional functionality is *very* important. Yes, so do I. -Nate
Re: FYI: Ruby 1.6.0 - An object-oriented language for quick and easy programming
What sets Ruby apart is a clean and consistent language design where everything is an object. I like this part. Assuming I ever finish my last RFC I'd like Perl to have embedded objects as well. The difference being Perl's wouldn't get in the way, unlike Python's. Of particular interest seems to be this link: http://www.ruby-lang.org/en/compar.html Which has a somewhat poignant analysis of Perl's OO: Ruby was a genuine easy-to-use object-oriented language from the beginning; whereas Perl's OOP features were added to non-OO Perl, so that these features are (unlike the rest of Perl) very clumsy and hard to use correctly and effectively. For many people and purposes, Ruby is a better OO Perl than Perl. And then there's the lexical variable issue too: The default variable scope rules for Ruby (default: local) are much better suited for medium-to-large scale programming tasks; no "my, my, my" proliferation is needed for safe Ruby programming Food for though at least. -Nate
Re: RFC 188 (v2) Objects : Private keys and methods
This RFC proposes two new keywords -- Cprivate and Cpublic -- that limit the accessibility of keys in a hash, and of methods. I still think these should be attributes across the board: my $hash{$key} : private = $val; my @hash{qw(_name _rank _snum)} : public; sub dostuff : private { } I'd be interested what others think. -Nate
Re: RFC 188 (v2) Objects : Private keys and methods
Damian Conway wrote: The problem with specifying them as attributes is that I do not believe there is any way (or even any proposed way) of applying attributes to a hash entrie or a hash slice, nor is there any way of *retrospectively* applying an attribute to a hash that has already been declared elsewhere. You're correct. I personally think there should be. My examples have been based on the idea that this could be possible in Perl 6. I'm going to post a Nat-inspired 'IDEA' to perl6-language in a little bit (if my head doesn't explode first) and see how much it's shot at. -Nate
Re: RFC 163 (v2) Objects: Autoaccessors for object data structures
How about also just ":access" to do both? It would seem to be the most common case. I was trying to conserve keywords, but I'm not opposed to this. =head2 Mixing autoaccessors and real subs I really don't see how this is necessary. If you have to write a custom accessor, you might as well write the whole thing. I also don't see that the optimization of one half of the accessor vs the other is worth the trouble. Well, it depends on how much faster the autoaccessor is. If it is much faster, and you need to access a whole bunch of data repeatedly, then this makes sense. But if the autoaccessor is about the same as a sub speed-wise, then screw it, I agree. While in general this might be a good idea, is it really necessary for this proposal? How about this: package Foo; use laccess qw(this); use raccess qw(foo); use access qw(up); I think attributes are a nicer way of handling stuff attached to data, because it's right there by the data looking at you. But this: This also means accessors are defined on a per class basis rather than per object (which is potentially extremely confusing and difficult to implement). Is a good point. I could see something like: use accessor (name = '$SELF-{DATA}-{C_name}', 'lvalue'); But I'll have to think about this a little more. $r-method; 1. Look for a declared autoaccessor for the given context. Context. I hope this means context of the object $r? Yep. Will clarify. 2. readonly rvalue subs http://www.mail-archive.com/perl6-language-objects@perl.org/msg00096.html implies that this isn't needed because of the proposed :constant hash attribute. This isn't enough. Yeah, check out this email: http://www.mail-archive.com/perl6-language-objects@perl.org/msg00099.html The idea I originally had was that :raccess would specify something was an rvalue accessor which only returned a value, and couldn't take arguments. I think this is probably the way to go, otherwise we have to start adding other keywords, properties, etc, which really complicate things too much. I was about to say that :deref wouldn't be a bad idea, but that would just be shifting the problem from pass-by-reference to pass-by-value. Couldn't quite see what you were getting at here - maybe a little clarification. I'm pretty sure I understand ("autoderef bad, but forced copy bad too") but want to make 100% sure. -Nate
Re: RFC 254 (v1) Class Collections: Provide the ability to overload classes
[From DBI-connect()] # XXX this is inelegant but practical in the short term, sigh. if ($installed_rootclass{$class}) { $dbh-{RootClass} = $class; bless $dbh = $class.'::db'; my ($outer, $inner) = DBI::_handles($dbh); bless $inner = $class.'::db'; } It works, but to quote Tim Bunce there... *sigh*. So anyhow, yes, this is a big, icky problem. I wonder if this problem couldn't be solved with a proper combination of @ISA, SUPER::, NEXT::, and use delegation? (calling Damian... :-) http://dev.perl.org/rfc/190.pod (NEXT:: pseudoclass) http://dev.perl.org/rfc/193.pod (use delegation) Or perhaps a @HASA array or a better way of specifying multiple inheritance than a serial @ISA array are needed. Perhaps we need something as flexible as use delegation for inheritance? use inheritance parent = DBI; { use inheritance parent = DBI::db; SUPER-do_stuff; } use inheritance peer = DBI::st That's just braindump, and I'm not sure what it even means, but figured I'd write it down before I forgot. -Nate
Re: RFC 163 (v2) Objects: Autoaccessors for object data structures
All- As the sublist chair, I politely ask you to please table this discussion. Time is running short and this is really a digression. Glenn, if you have a proposal, please put one together in RFC format and post it to -objects. -Nate
Specific RFC comments for -objects
All- In an attempt to nudge things in the right direction (wrap-up), I've gone through and made some specific comments on RFC's. These are my opinions from monitoring the discussions on this list since its inception. I do not claim to be infallible, but feel I have a pretty good idea of what's been said. Below are specific suggestions as to what should be done with specific RFCs. These are my suggestions; you may feel free to disagree with or ignore them. I am basing these suggestions off what I have seen on the list and other RFCs. Please do not take offense if I suggest your RFC be retracted. This email is an attempt to pare down the number of conflicting RFCs based on community consensus and/or reality. Note: Some of the RFCs discussed here are do not have -objects as the Mailing-List because they predate it. However, I will still comment on these where they're relevant to OO. RFCs that should be Retracted --- RFC 95: Object Classes The consensus appeared to be against this, which provided for radical changes to Perl OO and use of . to separate classes. Many of the key points were covered by later RFCs on private methods and class delegation. RFC 171: my Dog $spot should call a constructor implicitly Again, the overwhelming consensus was against this. The later RFC claiming "my Dog $spot is just an assertion" was accepted as the way this should work. RFC 77: Suggested isa() operator Most of these changes are already handled by UNIVERSAL::isa, albeit with a different syntax. If an inline-style assertion is desired, the indirect object syntax can be used. RFC 108: Scope of Polymorphic References and Objects No discussion was recorded on either version of this RFC, and it appears to duplicate features that were more fully explored in subsequent -objects RFCs. If this is incorrect, a clarified version should be reposted by Wed. Otherwise, it should be retracted. RFC 103: Fix C$pkg::$var precedence issues with parsing of C:: This is unrealistic and unimplementable without causing major problems. And that last one's mine, just so you know I don't consider myself above honest evaluation. RFCs that should be Frozen --- RFC 153: Replace $self in @_ with self() builtin (not $ME) Some clarification of usage, syntax, and scope must be added. RFC 161: Everything in Perl becomes an object This is a philosophical document which has garnered no true support nor detraction. Some clarification of *why* this would be good should be added. RFC 128: Cmy Dog $spot is just an assertion Pretty much everyone seems to be in agreement. RFC 223: Objects: Cuse invocant pragma The mailing list should be changed to -objects, but I did not hear any specific clarifications that were needed. The remaining -objects RFCs should be clarified and reposted by Wednesday. Finally, in the only effort towards facism I will take on this issue, if I do not hear otherwise by next Friday, Sep 30th, I will request that the above RFCs be retracted/frozen under the assumption that you implicitly agree with my analyses. This is not an attempt to force my will on others, but rather try to wrap things up and present Larry with a set of at least somewhat cohesive RFCs. Thanks, Nate
Re: RFC - Interpolation of method calls
Tom Christiansen wrote: print "Today's weather will be $weather-temp degrees and sunny."; So, the - operator is supposed to get expanded in dq strings, eh? It already does, or at least appears to to users: print "Today's weather will be $weather-{temp} degrees and sunny."; print "Today's weather will be $weather-[0] degrees and sunny."; Isn't it inconsistent to do this? I think it's far more inconsistent to have the above work but not have methods interpolate. And yes, I realize they're different thingies but they're very close syntactically and cognitively, especially for data access (which is really what we're talking about here). I've always found it quite surprising and cumbersome to have to do this: print "Today's weather will be ", $weather-temp, " degrees and sunny."; When the above two work fine. -Nate
Re: RFC - Interpolation of method calls
This topic is actually covered, albeit far less in-depth and lumped with an unrelated change, by Nathan Wiger's RFC 103, just in case you weren't aware. Yeah, I've got to split those up. I was trying cut down on the flood of RFC's that poor Larry has to sift through :-(, but they are both complex issues. Schwern, if you want to take this one over, it's all yours. There has already been some discussion on this here: http://www.mail-archive.com/perl6-language@perl.org/msg02169.html I would encourage people to read the thread. In particular, to be truly consistent we should interpolate class as well as instance methods, i.e.: "Hello, Class-name"; But there's a lot of problems with this and I'm not sure it's a good idea. print 'Today\'s weather will be '.join($", $weather-temp()). ' degrees and sunny.'; However if temp() calls wantarray(), the result will be FALSE (scalar). Ok, this is very confusing. I think what he's trying to get at is that these should all work the same: print "Here's some @stuff"; print "Here's some $h-{stuff}"; print "Here's some $r-stuff"; print 'There is '.$obj-foo(this = $yar, that = 2 + 2). ' in my head."; Now perl is parsing full statements within strings. This already happens with: print "Here's some $h-{$stuff}"; print "Here's some $a-[$stuff + $MIN]"; So it's not that confusing, and quite consistent. I'd say keep it simple, allow only simple, non-parenthetical method calls. No, this makes it impossible to do this: print "Your name is $cgi-param('name')"; And it's also inconsistent with how hashrefs and arrayrefs work already. -Nate
Re: Draft RFC: new pragma: Cuse namespace
Nathan Wiger wrote: use namespace 'Big::Long::Prefix'; my ::Class $object = ::Class-new; Assuming repairing :: precedence is a reality I don't think this proposal buys us anything. backtracking...That being said, I'm not necessarily against it. I'm just against bloat. I hadn't paid too much attention to the actual patch the first time reading it through, but it looks like a simple thing to add. And the one nice thing it does add is that these: $::stuff $main::stuff don't always mean the same thing, which at least gives some real reason for having the first version around. If this change is made, though, then I think it should work the same way in packages: package Foo; $::bar = "stuff"; # $Foo::bar = "stuff" For consistency. That way the rule is: "If no prefix is found to ::, then the current package namespace is used. You can change the current namespace either via 'package' (if you want to encapsulate a new package), or 'use namespace' (if you simply want a shortcut way of referring to variables)". This might have been discussed, but I didn't see it in the threads (I could have missed it, though). For anyone looking for a direct link to the start of the patch thread: http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2000-07/msg00490.html -Nate
Re: RFC 189 (v2) Objects : Hierarchical calls to initializers and destructors
=head2 The CBUILD method =head3 The CREBUILD method Hey! You left out the alternative names NEW / RENEW and BLESS / REBLESS that we all like! :-( -Nate
Re: Draft RFC: new pragma: Cuse namespace
use namespace 'Big::Long::Prefix'; my ::Class $object = ::Class-new; Anyone mentioned that this: $SHORT = 'Some::Huge::Obnoxious::Ridiculous::Term'; $SHORT-member; $stuff = new $SHORT; Already works? The only problem is that this: $SHORT::stuff(@args); Doesn't, but this is a precedence issue with :: and variable interpolation which I actually submitted RFC 103 on. You could still write this currently: {"${SHORT}::stuff"}(@args); But admittedly this is not pretty to look at. Assuming repairing :: precedence is a reality I don't think this proposal buys us anything. I had actually seen the p5p thread before, and it seems like a neat idea on the surface, but it's a real special case and syntax for something that can be solved with simple variables. -Nate
Re: RFC 101 (v2) Handlers and Pseudo-classes
[added -io cross-post] John Porter wrote: Just MHO, but I don't think this is the kind of thing that should go in the core. Just MHO. I think I agree. Just to clarify, the only reason it's an RFC and not just a Perl 5 module is because RFC 14 (the one on a new open()) relies on a handler concept for dealing with different file types: open file "/etc/motd"; # file handler (default) open dir "/usr/local/bin"; # dir handler open http "http://www.yahoo.com"; # http handler This type of abstraction would allow you to import custom modules and register them as http handlers without having to change your main code. It also prevents bloat in the IO routines which would otherwise have hardwired-in ways of dealing with this. Modularization lets us update modules that do http manipulation via CPAN without having to release a new version of Perl. Nonetheless, this may not be the best way to go. Perhaps by default, an "http.pm" is provided which allows basic http operations, and is automatically imported, allowing you to say: open http "http://www.foobar.com" natively without having a bunch of "use" statements at the top of your code. Then, if you wanted to override this you could: use Class::Handler; handler http = 'LWP::UserAgent'; open http "http://www.foobar.com"; # now uses the http handler # instead of native http.pm Comments welcome. -Nate
Re: RFC 200 (v1) Objects: Revamp tie to support extensibility (Massive tie changes)
Michael Fowler wrote: =head3 Merge CTIESCALAR, CTIEHASH, and CTIEARRAY into CTIE I'm not so sure about this. I'm not either anymore. This will probably be removed from the next version. Instead, this RFC proposes that Ctie's operation become much more fundamental, simply translating functions via the existing indirect object syntax: tie Transaction %trans;# indirect object constructor $trans{$var} = $value ;# $obj-STORE($var, $value); lock $trans{$var}; # $obj-lock($var); Ignoring for a moment the ambiguities inherent in indirect object syntax (which we should all be aware of), what says $trans{$var} is not an object in itself, on which we want to call the lock method? Well, currently indirect objects would not be called in the syntax above. You would have to write: lock {$trans{$var}}; Because an indirect object can only be a scalar, block, or bareword. So I would say keeping a similar idea in place - if you want to use the object method instead of the tied method, use braces - might be the best way to disambiguate these. And remember you can also do this: $trans{$var}-lock If you want to make sure that the call is completely unambiguous. However, one thing RFC 174 tries to accomplish is getting Perl to NOT need the braces in these circumstances, which opens this whole can of worms right back up. My current thinking is precedence rules: 1. tied object 2. indirect object 3. package function 4. CORE function You could then use braces or - if you wanted to force the indirect object, as the above examples show (and how currently Perl 5 works). I think this is actually the behavior you'd want. For example, imagine a tied class whose purpose is to maintain filesystem objects. You'd want the tied calls to take precedence, since you might have a special way of sort'ing or push'ing your objects around. And force-disambiguating them becomes pretty simple and consistent: lock $trans{$var}; # use precedence rules lock {$trans{$var}};# indirect object (like Perl 5) lock ($trans{$var});# package or CORE function This is actually pretty much how Perl 5 works already. The only thing we've added is that the tied check is done in a slightly different way. =head3 Cuntie should take all references out of scope I would argue that this should be handled with weak references, and not enforced by untie(). I don't necessarily want Perl deleting my object behind my back because I untied a variable. Yeah, I agree with you, and I suspect that this problem will be implicitly resolved by not having to mix object and tied calls. This'll get the axe too. -Nate
Re: RFC 200 (v1) Objects: Revamp tie to support extensibility (Massive tie changes)
Michael G Schwern wrote: sub lock { print "Hello!" } $trans = new Lock::Ness; lock $trans; # $trans-lock That's not right. You're correct. Sorry for not double-checking my examples. the same reasons I've already pointed out. You don't want adding a method to a class to suddenly alter the behavior of distant code. Regardless of my huge error above, this doesn't change the fact that this is exactly what tie() does currently in Perl 5. That is: tie @a, 'Matrix'; push @a, $stuff; Now changes the meaning of push() in the current package. So the only real difference in this situation from a user standpoint is that "PUSH" becomes "push" per the RFC, plus they can now do this with any function they please. Yes, it does help solve those problems. The dangling untie() will happen less frequently, and you can customize the hell out of your tied class. But you're trading those problems for a new set of ambiguities! I think your concerns are worthwhile. However, I think the "ambiguities" part can be resolved through precedence rules and similar constructs. I think there are many more potential upsides than downsides Iassuming a careful implementation. By v2 I expect to have a considerably better implementation section, complete with examples, specific code, rules, and so forth that should help alleviate any potential ambiguities. Also, little attention has been paid to operator overloading, which is another huge deal. Per this RFC, we can now integrate operator overloading and higher-order variables like @ and %, meaning we can add custom matrix math classes, special %hashes that do neat stuff in string contexts, and more. -Nate
Re: RFC 193 (v1) Objects : Core support for method delegation
Damian Conway wrote: attr3 = [ALL] It was (and is) a good suggestion. I suspect however that it should be attr3 = [__ALL__] Any consideration given to the :all export-like tag? attr3 = [:all]# could be uppercase too -Nate
Non-inheritable and cascading methods
All- I've been toying with this for a while, and I'm looking for others' input. I'm not RFC'ing it yet because (a) I already have 25 others to maintain and (b) I'm not sure if this might be covered by "my sub" or one of Damian's future RFC's. Currently, there are two big problems in defining subs that override inherited ones: 1. Once you override one, then all classes derived from you get yours by default, and not the parent's. Hence having to have a special dispatch for UNIVERSAL::can and friends if you override them. 2. It is not easy to have them automatically cascaded; you must call SUPER:: (or NEXT::) manually. This becomes a big problem with polymorphic objects, since you might want an ADD routine that just twiddles one thing, but then cascades down (for example, bigint::ADD might override int::ADD, but you might still want int::ADD and UNIVERSAL::ADD automatically called always). The solutions I've been thinking about to these two problems are the following: 1. Make it so a given sub cannot be inherited, for example: sub mymethod : noinherit { } I suspect this may be handled by "my sub", but I couldn't find enough info on p5p to tell for sure. This might also be handled by the "private" keyword Damian proposes, but I couldn't tell for sure. 2. Make it so a sub can automatically cascade and call all subs by the same name in parent classes: sub dostuff : cascade { } I'm pretty sure I haven't seen anything that suggests this yet. Clarification/input/etc is appreciated as always. Thanks, Nate
Re: RFC 188 (v1) Objects : Private keys and methods
private $hash{key}; private $hash{$key}; private $hashref-{key}; or to a hash slice: private @hash{qw(_name _rank _snum)}; or to a complete hash (either directly, or via a reference): private %hash; private { _name = "demo", _rank = "private", _snum = 123 }; private bless { @attrs }, $class; bless private { @attrs }, $class; Will "private" be a true scoping keyword? Or under strict would you have to do this: private my %hash; Note: an alternative would be to make Cprivate a subroutine attribute: sub check : private { ... } Has any consideration been given to consistently applying "private" as an attribute throughout? my %hash : private; $hash{$key} : private = "5"; # I know, I made this up. :-) sub dostuff : private { } my sub dostuff : private { } Personally, it reads better to me. I know that the "$hash{$key} : private" syntax doesn't work (yet, AFAIK), but I'd rather keep the scopes out front: my %STATE; our $DEBUG; And the attributes in back: my %STATE : private; our $DEBUG : public; # "public" implied and default Also, on a related issue, any reason why we shouldn't make this: my $hash{$key} = $val; Automatically scope %hash lexically in Perl 6? -Nate
Re: RFC 189 (v1) Objects : Hierarchical calls to initializers and destructors
Michael G Schwern wrote: Derived classes will never have to override a base's implementation, and all member variables should be private, and everyone will always use an accessor, and the UN will bring about world peace, and as long as I'm wishing for a perfect world, I'd like a pony. ;) I'm still not totally convinced that its so horrid to make the File::LockAndKey DESTROY call $self-SUPER::DESTROY manually... but it does break encapsulation. I'm inclined to agree here. I thought about this overnight, and I'm nervous about it again. It doesn't seem that it's that hard to add a single line to your SETUP or BLESS or whatever method that calls SUPER::SETUP. Remember, for all other methods you'd still have to do this manually. If you wanted to modify ADD or STORE, for example, just tweaking a few things, you'd have to manually call SUPER::STORE. I'm not convinced that this proposal saves enough typing to justify the problems that Michael mentions. Plus, what if you want to call a SUPER::'s DESTROY *not* at the start or end? sub DESTROY { my $self = self; # :-) # do a bunch of stuff here $self-SUPER::DESTROY(@_); # do a bunch more stuff here } It seems like this RFC enforces stuff that makes subclassing unnecessarily hard in some cases. At the very least, there should be a way to turn this off: sub SETUP : nocascade { } But then, if you're going to turn it off, why not just leave as-is and have the person turn it on manually by calling SUPER::? Your other RFC proposes calling NEXT:: manually, so the same philosophy I think should apply here. You could still have hooks for BLESS and REBLESS in bless(), but just make people manuallly call SUPER::BLESS and SUPER::REBLESS if they want. People doing Perl OO understand SUPER:: already. -Nate
Re: RFC 189 (v1) Objects : Hierarchical calls to initializers anddestructors
I haven't commented on RFC 171 because I assumed it would be shot down quickly by the Major Contibutors(tm), but let me just say now that I'm firmly in this camp: Funny, I don't see much difference between RFC 171 and this RFC: 171: constructor called on object creation 189: constructor called on object blessing Both of them suffer from involuntary method calls and no way to prevent them. And I'll further add that I like Damian's RFCs on the topic, having essentially duplicated that functionality "by hand" myself at various times, and found it to be very useful and friendly. (Although I used "init" instead of "SETUP" but I guess there already is an "INIT") I like the *idea* to a lot. But I don't like the hooks being in bless. What if you want to bless something but not call all its cascading SETUPs? I'd much rather the hooks be somewhere else, like new builtin. Maybe 'setup'? sub new { setup {}, @_ } sub SETUP { my ($self, @ctor_data) = @_; # initialization of object referred to by $self occurs here } setup() could do the blessing + call recursive SETUPs. Just calling bless() would retain the Perl 5 behavior. -Nate
Re: RFC 171 (v1) my Dog $spot should call a constructor implicitly
What, then, happens to the following code: my Dog $spot; if ($age 12) { $spot = new Doberman(); } else { $spot = new Corgi(); } This is a tricky case that deserves a lot of attention, but not exactly as written. Imagine this code block: my int ($x, $y, $z) = (4, 5, 6); if ( $x $y ) { $x = $z; } That seems like simple enough code. But what would that = line do? $x = $z; # $x-STORE($z) That doesn't make any sense, because $z is an object of class int, and not a number. I'd propose the following precedence rules for assignment: 1. If it's an object being assigned, then the old object gets overwritten 2. If it's a simple value being assigned, then -STORE is called So for example: my int ($x, $y, $z) = (4, 5, 6); if ( $x $y ) { $x = $z; # $x overwritten $y = "15"; # $y-STORE(15) } That's off the top of my head. Any input? This point should probably be addressed in the RFC in one way or another. -Nate
Re: RFC 161 (v2) OO Integration/Migration Path
"Randal L. Schwartz" wrote: That's my first gut reaction to this proposal. "If you like Python, you know where to find it, but let us have some primitive data types in Perl that act primitive so we can optimize things." Well, we're on a border here. What this RFC is really referring to is embedded objects, which are wholly different from objects stacked on top of simple variables. If everything uses these methods, then these methods *are* the internal representation of data, meaning there's no slow down with builtin data types. If you add your own class that grabs these methods, you pay when you override one, but you don't when you don't. These messages talk about this concept thoroughly: http://www.mail-archive.com/perl6-language-objects%40perl.org/msg00097.html http://www.mail-archive.com/perl6-language-objects%40perl.org/msg00106.html http://www.mail-archive.com/perl6-language-objects%40perl.org/msg00112.html Perl != Python. Perl != Python. Perl != Python... ;-) -Nate
Re: RFC 161 (v2) OO Integration/Migration Path
Nathan Torkington wrote: Are you proposing making even "normal" scalar, hash, and array access go through these methods? Wouldn't that slow everything way down? Glad you brought this up, Nat! I would say "yes and no". The reason I'd say this is because Dan S. and the internals guys are doing a lot of interesting stuff down these lines. I would also note say that if we had *one* single scalar data representation, this could be even FASTER than currently, because everything would be the same. That being said, you are right in that if this was stuck on top of Perl 5, things would be so ridiculously, terribly slow as to be unusable. If that looks like it's still going to be the case with Perl 6, then I'll be the first to drop the idea. It's like you're proposing an extension to the current tie system to deal with more operators, and then saying "no variable can have a value, they all have to be ties to objects". Is that what you're suggesting? Basically, yeah. Sort of. Maybe. I hate putting the word "tie" in there anywhere, because my goal would be to make default Perl flexible enough that tie() could be dropped altogether. In my "vision" (disclaimer: just because it's a vision doesn't mean it's a GOOD one), Perl 6 is a world where objects are embedded at the lowest level. You can define specialized accessors methods, like those defined in RFC 159, to override the default behaviors. If you don't provide these methods, default ones are provided for you out of CORE. So, everything is passed around as an object - albeit most of them are extremely lightweight objects, with only one or two methods and a single, simple value (like "5"). However, with one common data representation, there is an amazing amount of consistency, no more OO-slapped-on-as-an-afterthought, etc. Remember: All this assumes it's feasible internally. If not, it gets dropped. But I'd rather work out the kinks of the idea, give it to Larry and the internals guys, then have them say "What are you, nuts?". Because if we're not nuts, this would be really cool... -Nate
Re: RFC 159 (v1) True Polymorphic Objects
Oh geez! I'm sorry, I forgot to mention David Nicol in the REFERENCES, who also gave great input, especially on the BOOLEAN accessor. Thanks David! I swear I'll put you in v2. :-{ -Nate Perl6 RFC Librarian wrote: This and other RFCs are available on the web at http://dev.perl.org/rfc/ =head1 TITLE True Polymorphic Objects =head1 VERSION Maintainer: Nathan Wiger [EMAIL PROTECTED] Date: 25 Aug 2000 Mailing List: [EMAIL PROTECTED] Version: 1 Number: 159 Status: Developing =head1 ABSTRACT Currently, using objects in numeric and string contexts is not very useful or easy: $r = new CGI; $z = $r + $x; # oops print "$r\n"; # double-oops You can use facilities such as Ctie to help fix this issue, but Ctie is limited and slow. You can also overload operators, but this is not flexible enough for many applications since it applies to a package (and not individual objects). This RFC proposes the concept of Btrue polymorphic objects, which are objects that can morph into numbers, strings, booleans, and much more on-demand. As such, objects can be freely passed around and manipulated without having to care what they contain (or even that they're objects). =head1 DESCRIPTION =head1 Overview The top-level syntax remains the same. As such, transition to Perl 6 is very smooth for most people, and in fact most users don't have to care about any of the following details. To them, this script will "just work": $y = Math-data(7); $x = 3; $name = getname("Nate"); if ( $x 5 ) { $y += $x; if ( ! $name ) { $name = "The math whiz"; } } print "$name got $y"; # "Nate got 10" However, under the hood things might work drastically differently. In fact, C$y and C$name might well be polymorphic objects: $y = Math-data(7); # $y-CREATE, $y-STORE(7) $x = 3; # $x = 3 $name = getname("Nate"); # $name-CREATE, $name-STORE("Nate") if ( $x 5 ) { # $x 5 $y += $x; # $y-STORE($y-NUMBER-PLUS($x)) if ( ! $name ) { # $name || $name-BOOLEAN $name = "The math whiz";# $name-STORE("...") } } print "$name got $y";# $name-STRING , $y-STRING Here, C$y and C$name are objects, but we don't have to care. These objects have a key property: Icontext sensitivity. They have numerous different methods which are each called only in specific instances. So, being called in a numeric context calls CNUMBER, whereas being called in a string context would call CSTRING. Plus, operators are overloadable as well. This means that we might decide to overload C+ to become a Java-like concatenation operator on our objects: $string = $name + "Wiger"; # $name-STRING-PLUS("Wiger") Yuck. :-) But it can be done, and that's pretty cool. =head2 Polymorphic Methods The following are the proposed methods for Perl 6 objects. Note that these methods are completely Ioptional for a class to define. If they are not defined, the object would retain its current behavior. The hooks are in Perl if you want them, otherwise they don't get in the way. Note that CSTRING, CNUMBER, and CBOOLEAN are specialized forms of CFETCH. If you define them, they are used instead of CFETCH in the given context, otherwise CFETCH is used. Also note that the operators, when overloaded, behave similarly to 'use overload', but on an Iobject-by-object basis, rather than package-wide. Data Conversion and Access - STRING Called in a string context NUMBER Called in a numeric context BOOLEAN Called in a boolean context Operator Overloading - PLUS Called in + context MINUSCalled in - context TIMESCalled in * context DIVIDED Called in / context MODULUS Called in % context NUMCMP Called in = context NUMEQCalled in == context NUMNECalled in != context NUMLTCalled in context NUMGTCalled in context NUMLECalled in = context NUMGECalled in = context STRCMP Called in cmp context STREQCalled in eq context STRNECalled in ne context STRLTCalled in lt context STRGTCalled in gt context STRLECalled in le context STRGECalled in ge context BITAND Called in context BITORCalled in | context BITXOR Called in ^ context BITNOT Called in ~ context Assignment and Existenc
PLEASE DISCUSS ON -objects!! (was Re: RFC 161 (v1) OO Integration/Migration Path)
Please discuss this RFC on the -objects sublist. Thanks. Matt, you should probably update the Mailist List to perl6-language-objects for v2. -Nate Perl6 RFC Librarian wrote: This and other RFCs are available on the web at http://dev.perl.org/rfc/ =head1 TITLE OO Integration/Migration Path =head1 VERSION Maintainer: Matt Youell [EMAIL PROTECTED] Date: 25 Aug 2000 Mailing List: [EMAIL PROTECTED] Version: 1 Number: 161 =head1 ABSTRACT Allow Perl 6 to benefit more directly from object orientation and object syntax while leaving a bridge to Perl 5. =head1 DESCRIPTION =head2 Overview Everything in Perl becomes an object, using existing object-syntax. Out of plain sight, there would be essentially three base classes: Scalar, List, and Hash. Stricter typing would be imposed (as needed) at the object level without the need for new keywords. The Scalar base class would know about a fixed number of types, perhaps: ref, int, long, bool, and string. Other types could be added by subclassing Scalar. =head2 Examples For example, rather than: my int $intVal = 0; you would say: my $intVal = 0; $intVal-asInt; Or possibly even: my $invVal-asInt = 0; for simplicity. Unary operations could also be made the Scalar object's responsibility in the same style: $record-chop; Or even possibly controversial things like: $value-undef; Finally, some of the more domain-specific features being requested of the language could be added in a subclass of Scalar. For example, transaction-friendly variables might be subclassed: use Transactions; my $firstName = "Bob"; # ... (transaction happens) ... $firstName-commit; # or -rollback (Of course, transaction vars might be in their own, independent, class ala TMTOWTDI.) =head2 Wrap-up What this gives us is a means for adding functionality while leaving the basic language structure alone. This way we don't interfere with improvements happening elsewhere in the language, and we leave a clean migration path for Perl 5. Also, by allowing lower-level extensibility, many language-feature requests may become moot. =head1 IMPLEMENTATION Most of the tools required to implement this system are already there. - Scalar values already have Perl Doing The Right Thing for type conversion. Providing the user with methods to activate type conversion explicitly shouldn't be a major chore. In fact it could lighten Perl's load in many cases by eliminating guess work about when to convert. - The existing bless-based object system provides most (if not all) of the tools needed to implement this system. For example, if I create my own scalar class in Perl 5, I can say: $myScalar-chop; or chop $myScalar; and Perl automagically knows what I mean, barring namespace considerations. It could work the same way in Perl 6. That would mean that older code could very easily get along with newer code, because all of the same operators would still be there and they would still work as expected. =head1 MISC This approach may also allow for better organization of Perl's internals, specifically if the plan is to move toward a Topaz-style (C++) implementation. Also, by organizing responsibilities into explicit classes, the "mind-reading" load might lighten for the Perl interpreter. At least it looks that way from outside. =head1 REFERENCES RFC 4: "Type Inference" RFC 49: "Objects should have builtin stringifying STRING method" RFC 89: "Controllable Data Typing" RFC 137: "Overview: Perl OO should Inot be fundamentally changed." (specifically the EXECUTIVE SUMMARY) http://www.perl.com/pub/1999/09/topaz.html : "Topaz: Perl for the 22nd Century" - Chip Salzenberg http://www.youell.com/matt/perlstring/ - A C++ string class that emulates Perl's scalar manipulation tools. Bears some similarity to the Scalar object described here.
Re: RFC for $ME class variable (was Re: RFC 124 (v1) Sort order forany hash)
You can have your cake, but not force us to eat it too... Like $AUTOLOAD, $ME would be dynamically scoped: The first time I saw the bareword "self" keyword I almost wet myself in horror, but I would say that $AUTOLOAD is a disaster that should not be repeated. And that's the way that this $ME thing is headed... We seem to cope with $AUTOLOAD okay, without the need to: I hate it, it's miserable. Too much hidden trickery and special cases. I could deluge you with examples but I'd rather not. A sub call would probably be better. We have ref(), want(), and other calls to find out context, why not self() to backtrace package context? -Nate