Re: Should $.foo attributes without is rw be writable from within the class
Sex, 2008-09-19 às 10:25 -0700, Jon Lang escreveu: Daniel Ruoso wrote: In SMOP, it is handled based on the package of the Class, the private storage inside the object is something like $obj.^!private_storageA::$!bar and $ojb.^!private_storageB::$!bar Note that this ought only be true of class inheritance; with role composition, there should only be one $!bar in the class, no matter how many roles define it. er... what does that mean exactly? role B { has $!a; } role C { has $!a; } class A does B, C { method foo() { say $!a; } } I think in this case $!B::a and $!C::a won't ever be visible, while the reference to $!a in class A will be a compile time error. OTOH... role B { has $.a; } role C { has $.a; } class A does B, C { method foo() { say $.a; } method bar() { say $!a; } } In that case, both B and C declare a *method* a which happens to be visible in class A (and probably a composition error), but $!a in method bar is still a compile time error, because there's no $!a declared in class A. Or does that mean that class A does B, C {...} actually makes the declarations in B and C as if it were declared in the class A? daniel
Re: Should $.foo attributes without is rw be writable from within the class
Qui, 2008-09-18 às 18:11 +0200, TSa escreveu: Shouldn't there be a warning in B that $!B::bar overwrites $!A::bar without an accessor? Actually, $!B::bar doesn't overwrite $!A::bar... the problem is simply that $!A::bar is not visible from inside B, and therefore, there's nothing to be overriden... daniel
Re: Should $.foo attributes without is rw be writable from within the class
HaloO, Daniel Ruoso wrote: Qui, 2008-09-18 às 18:11 +0200, TSa escreveu: Shouldn't there be a warning in B that $!B::bar overwrites $!A::bar without an accessor? Actually, $!B::bar doesn't overwrite $!A::bar... the problem is simply that $!A::bar is not visible from inside B, and therefore, there's nothing to be overriden... May I pose three more questions? 1. I guess that even using $!A::bar in methods of B is an access violation, right? I.e. A needs to trust B for that to be allowed. 2. The object has to carry $!A::bar and $!B::bar separately, right? 3. How are attribute storage locations handled in multiple inheritance? Are all base classes virtual and hence their slots appear only once in the object's storage? Regards, TSa. -- The unavoidable price of reliability is simplicity -- C.A.R. Hoare Simplicity does not precede complexity, but follows it. -- A.J. Perlis 1 + 2 + 3 + 4 + ... = -1/12 -- Srinivasa Ramanujan
Re: Should $.foo attributes without is rw be writable from within the class
Sex, 2008-09-19 às 17:49 +0200, TSa escreveu: Daniel Ruoso wrote: Qui, 2008-09-18 às 18:11 +0200, TSa escreveu: Shouldn't there be a warning in B that $!B::bar overwrites $!A::bar without an accessor? Actually, $!B::bar doesn't overwrite $!A::bar... the problem is simply that $!A::bar is not visible from inside B, and therefore, there's nothing to be overriden... May I pose three more questions? 1. I guess that even using $!A::bar in methods of B is an access violation, right? I.e. A needs to trust B for that to be allowed. Yes 2. The object has to carry $!A::bar and $!B::bar separately, right? Yes 3. How are attribute storage locations handled in multiple inheritance? Are all base classes virtual and hence their slots appear only once in the object's storage? In SMOP, it is handled based on the package of the Class, the private storage inside the object is something like $obj.^!private_storageA::$!bar and $ojb.^!private_storageB::$!bar daniel
Re: {SPAM} Re: Should $.foo attributes without is rw be writable from within the class
Sex, 2008-09-19 às 17:49 +0200, TSa escreveu: Daniel Ruoso wrote: Qui, 2008-09-18 às 18:11 +0200, TSa escreveu: Shouldn't there be a warning in B that $!B::bar overwrites $!A::bar without an accessor? Actually, $!B::bar doesn't overwrite $!A::bar... the problem is simply that $!A::bar is not visible from inside B, and therefore, there's nothing to be overriden... May I pose three more questions? 1. I guess that even using $!A::bar in methods of B is an access violation, right? I.e. A needs to trust B for that to be allowed. Yes 2. The object has to carry $!A::bar and $!B::bar separately, right? Yes 3. How are attribute storage locations handled in multiple inheritance? Are all base classes virtual and hence their slots appear only once in the object's storage? In SMOP, it is handled based on the package of the Class, the private storage inside the object is something like $obj.^!private_storageA::$!bar and $ojb.^!private_storageB::$!bar daniel
Re: Should $.foo attributes without is rw be writable from within the class
Daniel Ruoso wrote: TSa wrote: May I pose three more questions? 1. I guess that even using $!A::bar in methods of B is an access violation, right? I.e. A needs to trust B for that to be allowed. Yes 2. The object has to carry $!A::bar and $!B::bar separately, right? Yes 3. How are attribute storage locations handled in multiple inheritance? Are all base classes virtual and hence their slots appear only once in the object's storage? In SMOP, it is handled based on the package of the Class, the private storage inside the object is something like $obj.^!private_storageA::$!bar and $ojb.^!private_storageB::$!bar Note that this ought only be true of class inheritance; with role composition, there should only be one $!bar in the class, no matter how many roles define it. -- Jonathan Dataweaver Lang
Re: Should $.foo attributes without is rw be writable from within the class
Jon Lang wrote: Daniel Ruoso wrote: TSa wrote: May I pose three more questions? 1. I guess that even using $!A::bar in methods of B is an access violation, right? I.e. A needs to trust B for that to be allowed. Yes 2. The object has to carry $!A::bar and $!B::bar separately, right? Yes 3. How are attribute storage locations handled in multiple inheritance? Are all base classes virtual and hence their slots appear only once in the object's storage? In SMOP, it is handled based on the package of the Class, the private storage inside the object is something like $obj.^!private_storageA::$!bar and $ojb.^!private_storageB::$!bar Note that this ought only be true of class inheritance; with role composition, there should only be one $!bar in the class, no matter how many roles define it. Yes, though note that they will only share a slot if they have the exact same type. Otherwise it's a composition-time error. Jonathan
Re: Should $.foo attributes without is rw be writable from within the class
TSa Thomas.Sandlass-at-vts-systems.de |Perl 6| wrote: class A { has $.foo = A; has $!bar = A; method blahh() { say $.foo ~ $!foo ~ $!bar; } } class B is A { has $.foo = B; has $!bar = B; } my $a = A.new; my $b = B.new; say $a.blahh; # prints AAA say $b.blahh; # prints BAA, right? Shouldn't there be a warning in B that $!B::bar overwrites $!A::bar without an accessor? And of course the example shows that $!foo in blahh is not derivation friendly. Or am I getting things wrong and there can be only one $!foo and $!bar in the namespace of the objects created from A and B? That is the declarations in B are superfluous if not outright wrong? Well, or they only affect the generated constructor and the storage location is shared? The latter would nicely contrast them to non twigil attributes in the form 'has $foo'. A::!foo will be distinct from B::!foo. The accessor in B will override the accessor from A. I would not mind a warning, since the implementation knows what is going on being auto-generated. But in general, if you write methods that are accessors, separate from the backing data, the compiler can't tell what you meant and won't give any warning. --John
Re: Should $.foo attributes without is rw be writable from within the class
TSa Thomas.Sandlass-at-vts-systems.de |Perl 6| wrote: May I pose three more questions? 1. I guess that even using $!A::bar in methods of B is an access violation, right? I.e. A needs to trust B for that to be allowed. Correct. 2. The object has to carry $!A::bar and $!B::bar separately, right? Correct. 3. How are attribute storage locations handled in multiple inheritance? Are all base classes virtual and hence their slots appear only once in the object's storage? The slots are direct in that class. The accessor functions are virtual, though. It is not specified anywhere, nor even discussed that I've found, whether base classes are virtual (merged) in the C++ sense. I have this flagged as an open design question. Since you have roles, perhaps you don't need virtual base classes. I think no snap decision should be made, but the ramifications and use-cases explored in some detail. --John
Re: Should $.foo attributes without is rw be writable from within the class
Daniel Ruoso wrote: Jon Lang wrote: Note that this ought only be true of class inheritance; with role composition, there should only be one $!bar in the class, no matter how many roles define it. er... what does that mean exactly? Unless something has drastically changed since I last checked the docs, roles tend to be even more ethereal than classes are. You can think of a class as being the engine that runs objects; a role, OTOH, should be thought of as a blueprint that is used to construct a class. Taking your example: role B { has $!a; } role C { has $!a; } class A does B, C { method foo() { say $!a; } } I think in this case $!B::a and $!C::a won't ever be visible, while the reference to $!a in class A will be a compile time error. :snip: Or does that mean that class A does B, C {...} actually makes the declarations in B and C as if it were declared in the class A? Correct. Declarations in roles are _always_ treated as if they were declared in the class into which they're composed. And since only classes are used to instantiate objects, the only time that a role actually gets used is when it is composed into a class. -- Jonathan Dataweaver Lang
Re: Should $.foo attributes without is rw be writable from within the class
I really like all the replies I got to this; thank you Moritz, Jonathan, TSa, Larry, John and Damian. From the feedback I received, I will now do the following: 1. Remove is rw from all attributes that aren't supposed to be writable from outside the class. 2. Start using $!foo consistently in methods, for both read and write accesses. It remains to be seen whether the greater understanding you have given me about the inner workings of Perl 6 classes will make this system bearable. :) I hope it will. // Carl
Re: Should $.foo attributes without is rw be writable from within the class
* Damian Conway [EMAIL PROTECTED] [2008-09-18 03:30]: When thinking about this, it's also important to remember that, in Perl 6, not everything with a sigil is automatically writeable. That’s not even new to Perl 6. $ perl -e's/foo/bar/ for foo' Modification of a read-only value attempted at -e line 1. -- *AUTOLOAD=*_;sub _{s/(.*)::(.*)/print$2,(,$\/, )[defined wantarray]/e;$1} Just-another-Perl-hack; #Aristotle Pagaltzis // http://plasmasturm.org/
Re: Should $.foo attributes without is rw be writable from within the class
* Carl Mäsak [EMAIL PROTECTED] [2008-09-18 12:20]: 2. Start using $!foo consistently in methods, for both read and write accesses. Unless, of course, you want the class-internal use of the attribute to go through its accessor! Which you are likely to want for public attributes, and much less likely for class- private ones. So Perl 6 defaults the right thing here, it would seem. Regards, -- Aristotle Pagaltzis // http://plasmasturm.org/
Re: Should $.foo attributes without is rw be writable from within the class
I don't understand why this stuff is confusing; it's not new with Perl 6. There's a long tradition in O-O of distinguishing between the externally visible accessor and the internal storage - Ruby self.foo vs @foo, Java this.foo vs setFoo()/getFoo(), etc. In fact the Ruby case is directly analogous: Perl 6 Ruby has $.foo attr_reader :foo has $.foo is rw attr_accessor :foo $.foo
Re: Should $.foo attributes without is rw be writable from within the class
HaloO, Carl Mäsak wrote: I really like all the replies I got to this; thank you Moritz, Jonathan, TSa, Larry, John and Damian. It was a pleasure to be useful. From the feedback I received, I will now do the following: 1. Remove is rw from all attributes that aren't supposed to be writable from outside the class. 2. Start using $!foo consistently in methods, for both read and write accesses. From a best practice POV consider class A { has $.foo = A; has $!bar = A; method blahh() { say $.foo ~ $!foo ~ $!bar; } } class B is A { has $.foo = B; has $!bar = B; } my $a = A.new; my $b = B.new; say $a.blahh; # prints AAA say $b.blahh; # prints BAA, right? Shouldn't there be a warning in B that $!B::bar overwrites $!A::bar without an accessor? And of course the example shows that $!foo in blahh is not derivation friendly. Or am I getting things wrong and there can be only one $!foo and $!bar in the namespace of the objects created from A and B? That is the declarations in B are superfluous if not outright wrong? Well, or they only affect the generated constructor and the storage location is shared? The latter would nicely contrast them to non twigil attributes in the form 'has $foo'. Regards, TSa. -- The unavoidable price of reliability is simplicity -- C.A.R. Hoare Simplicity does not precede complexity, but follows it. -- A.J. Perlis 1 + 2 + 3 + 4 + ... = -1/12 -- Srinivasa Ramanujan
Re: Should $.foo attributes without is rw be writable from within the class
Just to bring some of the IRC discussion to the list... Carl Mäsak wrote: Rakudo and I have a disagreement over this: I expect to be able to assign to a $.foo attribute in methods within the class, whereas Rakudo demands the is rw attribute in order to do that. We discussed it a bit on #perl6 today. http://irclog.perlgeek.de/perl6/2008-09-17#i_572836 I only have pragmatic arguments to offer for my point of view: somehow, it feels like each and every attribute gets an is rw as things stand now. The modifier somewhat loses its meaning... if it meant _publicly_ readable/writable, it would only be used for some variables. There's also the point that you can initialize attributes with the . twigil: class Stuff { has $.more_stuff = 3 } So at least visually it appears as though you *can* assign to it. Not allowing that in other places feels weird. Yes, I know that $.stuff actually translates to $( self.stuff ), so without 'is rw' there is no rw accessor generated - but couldn't we just fake assignment to '$.foo' to actually affect '$!foo'? Finally, some useless statistics: I count 12 attributes in different classes in November right now. Out of those, 12 (100%) have the is rw attribute. This is mostly probably due to non-working constructors. Simple cases seem to work, though: 12:29 moritz_ rakudo: class A { has $.b }; my A $x .= new(b = 3); say $x.b 12:29 p6eval rakudo 31204: OUTPUT[3] Moritz -- Moritz Lenz http://moritz.faui2k3.org/ | http://perl-6.de/
Re: Should $.foo attributes without is rw be writable from within the class
Moritz Lenz wrote: Yes, I know that $.stuff actually translates to $( self.stuff ), so without 'is rw' there is no rw accessor generated - but couldn't we just fake assignment to '$.foo' to actually affect '$!foo'? Why not just assign to $!foo, which is always read/write (since the rw affects whether you get an accessor that is read/write or not - $!foo refers to the underlying storage location; at least, that's how I understand it and what I think Rakudo is implementing today). Jonathan
Re: Should $.foo attributes without is rw be writable from within the class
Jonathan (): Why not just assign to $!foo, which is always read/write (since the rw affects whether you get an accessor that is read/write or not - $!foo refers to the underlying storage location; at least, that's how I understand it and what I think Rakudo is implementing today). I have come to understand that this is an available possibility, yes. That doesn't mean I like it. :) My complaint could be pithily summarized as those are _my_, attributes, why can't I write to them? // Carl
Re: Should $.foo attributes without is rw be writable from within the class
HaloO, Carl Mäsak wrote: My complaint could be pithily summarized as those are _my_, attributes, why can't I write to them? Perhaps you should change your POV. The correct terminus technicus for the $.foo twigil variables is 'call the method' which nicely embeds attribute access into dispatch and makes base methods future proof with respect to deriving classes. Your 100% rw observation then to me indicates that OO is more about data sharing than method dispatch. Note that rw accessors are particularly difficult to handle in typesafe mode. Regards, TSa. -- The unavoidable price of reliability is simplicity -- C.A.R. Hoare Simplicity does not precede complexity, but follows it. -- A.J. Perlis 1 + 2 + 3 + 4 + ... = -1/12 -- Srinivasa Ramanujan
Re: Should $.foo attributes without is rw be writable from within the class
On Wed, Sep 17, 2008 at 01:00:07PM +0200, Carl Mäsak wrote: : Jonathan (): : Why not just assign to $!foo, which is always read/write (since the rw : affects whether you get an accessor that is read/write or not - $!foo refers : to the underlying storage location; at least, that's how I understand it and : what I think Rakudo is implementing today). : : I have come to understand that this is an available possibility, yes. : That doesn't mean I like it. :) : : My complaint could be pithily summarized as those are _my_, : attributes, why can't I write to them? You have to have a way of talking about your own attributes *as if* they were not your own attributes, and $.foo is that way. We take similar 3rd-person viewpoints in natural language too, especially when talking to kids: Daddy thinks that's okay, but Amy will have to go ask Mommy too. In C++ish OO terms, $.foo is always virtual, and $!foo is never virtual. The has declarator can intuit from a virtual $.foo declaration that you also need private non-virtual $!foo storage, but it can't intuit from a non-virtual declaration that you want to have a public accessor, at least, not without more information than the sigil provides, which would be uglier. So $.foo basically says that you want to talk about the slot from the viewpoint of the actual object, while $!foo says you want to talk about the slot from the viewpoint of your class. This is orthogonal to the actual class boundary, if you ignore the fact that we prohibit $!foo access from outside the class. (And, in fact, we could probably still get at it with a private method from outside the class if there is an appropriate trusts declaration.) Larry
Re: Should $.foo attributes without is rw be writable from within the class
Carl Mäsak cmasak-at-gmail.com |Perl 6| wrote: I have come to understand that this is an available possibility, yes. That doesn't mean I like it. :) My complaint could be pithily summarized as those are _my_, attributes, why can't I write to them? // Carl If the accessor were implemented to do something more interesting than just assign to the private location, then having some code call the accessor and other code access the private location directly with the same syntax would be confusing. For untyped variables, it would be difficult to determine whether something is a method call or an attribute on a type that I'm in the body of. Everything would have to be public methods, with a run-time check on the scope of the caller to see if it were allowed. Having a different syntax for private access simplifies things. I'm wondering if the strange wording concerning has $x; with no twigal is meant to take care of this case. But I don't understand what he meant in the Synopses, though I've asked about it repeatedly on this list and other places, so I largely ignore that case. It says something about making $x available as an alias in the lexical scope. In context of what you are asking, maybe that's what it is for. --John
Re: Should $.foo attributes without is rw be writable from within the class
Larry wrote: You have to have a way of talking about your own attributes *as if* they were not your own attributes, and $.foo is that way. When thinking about this, it's also important to remember that, in Perl 6, not everything with a sigil is automatically writeable. For example: constant $answer = 42; $answer = 99; # Kaboom! sub foo( $bar ) { $bar = 42 # Biff!! } $baz := 86; $baz++;# Zowie!!! Likewise a $.foo attribute defaults to read-only, whereas a $!foo attribute defaults to read-write. Damian