Re: Re(vised): Proposal to make class method non-inheritable
On Wed, Oct 19, 2005 at 04:03:54AM -0700, Larry Wall wrote: > : This one is new to me. I'm not sure I understand what it's used for. Is > : there already some documentation about it? > > It's in my copy of S06, which I haven't checked in yet. Is there an AES commit feed available somewhere? -- Gaal Yahas <[EMAIL PROTECTED]> http://gaal.livejournal.com/
Re: Re(vised): Proposal to make class method non-inheritable
Larry Wall skribis 2005-10-19 4:03 (-0700): > The absence of a dot creates a private attribute. We decided it should > be even easier to declare a private attribute than a public one, so it's > just > has $foo; > and then it is visible only in the lexical scope. This takes away my objections to the dot twigil entirely. Juerd -- http://convolution.nl/maak_juerd_blij.html http://convolution.nl/make_juerd_happy.html http://convolution.nl/gajigu_juerd_n.html
Re: Re(vised): Proposal to make class method non-inheritable
On Wed, Oct 19, 2005 at 12:33:11PM +0200, Juerd wrote: : > : make $:foo equivalent to :foo($foo) (conjectural) : : This one is new to me. I'm not sure I understand what it's used for. Is : there already some documentation about it? It's in my copy of S06, which I haven't checked in yet. By the way, the form is intended to work in either signatures or as an rvalue, and in signatures replaces + to mark named args. + becomes the marker for required attributes (assumed on initial positional args). : And does this mean $:foo is no longer a private $.foo? (which could be a : very good thing, by the way) What replaces that? The absence of a dot creates a private attribute. We decided it should be even easier to declare a private attribute than a public one, so it's just has $foo; and then it is visible only in the lexical scope. Larry
Re: Re(vised): Proposal to make class method non-inheritable
Larry Wall skribis 2005-10-19 1:43 (-0700): > On Tue, Oct 18, 2005 at 04:43:57PM +0200, Juerd wrote: > : dot sigils are not actually special. They are required on has-variables > : and forbidden on all other. Changing them to be optional is trivial, or > : so I hope. > Dot sigils drive accessor generation, which essentially hoists an > ordinary variable into the object's namespace. They are not just > commentary. "has" can do this without the dot, in theory. > : (I believe that sigils or twigils should not indicate scope, duration or > : type. The distinctin between the major variable types is useful, further > : distinction is not.) > Eh? Sigils are for type, twigils are precisely for doing weird things > with scope or duration. This doesn't change how I feel about them, though :) Still, I do like twigils for automatically existing variables, like %*ENV and &?SUB. Here, I do see the need and use for indicating scope and duration, but I mostly read the twigil as: this variable is /special/. Global scope needs a twigil because in most cases, the declaration would be nowhere to be found. Declaring superglobals doesn't necessarily make sense anyway. The ^ twigil is needed for the same reason: declaration is implicit. Object attributes are declared by the Perl coder and initialized by code. I know where they come from, and if not, I can look it up very easily. There is no twigil for "my" and "our" variables, and we don't need any. Same for "has": declaration is explicit. > : make $:foo equivalent to :foo($foo) (conjectural) This one is new to me. I'm not sure I understand what it's used for. Is there already some documentation about it? And does this mean $:foo is no longer a private $.foo? (which could be a very good thing, by the way) What replaces that? Juerd -- http://convolution.nl/maak_juerd_blij.html http://convolution.nl/make_juerd_happy.html http://convolution.nl/gajigu_juerd_n.html
Re: Re(vised): Proposal to make class method non-inheritable
On Tue, Oct 18, 2005 at 04:43:57PM +0200, Juerd wrote: : dot sigils are not actually special. They are required on has-variables : and forbidden on all other. Changing them to be optional is trivial, or : so I hope. Dot sigils drive accessor generation, which essentially hoists an ordinary variable into the object's namespace. They are not just commentary. : (I believe that sigils or twigils should not indicate scope, duration or : type. The distinctin between the major variable types is useful, further : distinction is not.) Eh? Sigils are for type, twigils are precisely for doing weird things with scope or duration. * global scope + currently compiling scope ? currently compiled scope = current file/pod scope < current $/ scope ^ current signature scope : make $:foo equivalent to :foo($foo) (conjectural) Larry
Re: Re(vised): Proposal to make class method non-inheritable
[EMAIL PROTECTED] wrote: U... I'm not sure that allowing $. injection from the nested blocks is a good thing. I don't think it's ambiguous, but to me it looks weird and confusing - if a user put the variable in the nested block like that, it's almost certain he actually meant to write { my $foo; } and the . was put there erroneously. Gack, furthermore, I was thinking 'has' and reading/writing 'my'. Sorry. :( But given that the variable will be accessible to all methods via the closure mechanism, the only thing missing I think is the ability to get at the variable via introspection. Now, as for class methods, I suppose it is possible to just stash then in the classes symbol table like with variables. However, do we then loose the method call syntax? Well, if it belongs to the module part of the class, the syntax would be Bar::method(...), right? Yes, but the . is the method invocation operator, the :: is package symbol table access. I think they really mean different things. Yes. Now to be literal-minded, if Foo is a class... Foo::method() would mean package(Foo)::method() (do package access, call method. No invocant, but you can access the proper child of Foo as $*MODULE) Foo.method() would mean Class::method(Foo:) (forward to metaclass, with class as an invocant) Nicely symetric, and (IMHO) completely unintuitive. So what exactly means to say that a class is a module? This also means that they would not (directly) be inheritable since inheritence moves along superclass lines, and not with @ISA. Well, namespaces should generally be inheritable. I don't think this is true, this is a Perl 5-ism. How else would lexical namespaces inject variables from outer block into the inner? I think you are confusing namespacing with scoping. The scope rules are as such that the inner can access see the outer. Fair enough. I was talking about implementation - this means you need symbol table import and shadowing (with the symbols defined in the inner scope). Same (or similar) policy could be used for class methods and attributes. I guess at the package level declaration that Class1 is Class2 would just inject symbols from one module into the other? (yes, this is kinda handwavy :/ ) I don't think this would be so, unless you explicitly asked for it. I'm not sure I understand, why not? Anyway, this makes me cringe on a certain level, although I'm not sure I can put the reason into words. Strictly speaking, it's bad only if there are cases where multimethod should behave differently for a class and an instance. One case I can think of is class AutoCreation { ... }; multi dwimmy_instance(class AutoCreation $obj) { $obj.new() } multi dwimmy_instance(AutoCreation $obj) { $obj } I think we need some ability to differentiate between the class version of Foo and the instance version of Foo. I think we agree here. :) Miro
Re: Re(vised): Proposal to make class method non-inheritable
On Tue, 2005-10-18 at 10:16 -0400, Stevan Little wrote: > On Oct 18, 2005, at 6:56 AM, Miroslav Silovic wrote: > > Uhm. I'm not sure either. :) The way I read Larry's mail, > > multimethods use .isa operator to detect whether $foo belongs to > > Foo. And for every class, Foo.isa(Foo) is true (this is exceptional > > behaviour of .isa). So > (sidebar: it will probably use .does actually, but this an as yet > unresolved detail) Consider it fairly resolved. (What? Using type as a marker of potential coercion? Yep!) -- c
Re: Re(vised): Proposal to make class method non-inheritable
Stevan Little skribis 2005-10-18 10:16 (-0400): > You are probably right, but are the twigils actually special? or is > it just a naming convention. dot sigils are not actually special. They are required on has-variables and forbidden on all other. Changing them to be optional is trivial, or so I hope. (I believe that sigils or twigils should not indicate scope, duration or type. The distinctin between the major variable types is useful, further distinction is not.) > I don't think this is true, this is a Perl 5-ism. Perl 5 isn't a synonym for "bad". "Perl 5-ism" can be construed as positive or negative. Please do elaborate. Juerd -- http://convolution.nl/maak_juerd_blij.html http://convolution.nl/make_juerd_happy.html http://convolution.nl/gajigu_juerd_n.html
Re: Re(vised): Proposal to make class method non-inheritable
On Oct 18, 2005, at 6:56 AM, Miroslav Silovic wrote: Disclaimer: I don't ~~ @larry :) [EMAIL PROTECTED] wrote: class Bar { our $.bar; { my $.foo; } } I assume that the leading "$." is what makes the difference, however, IIRC the "$." is just part of the name, and no more special than that. Which means that I can choose that name (yes, it is evil, but I assume I can still do it). U... I'm not sure that allowing $. injection from the nested blocks is a good thing. I don't think it's ambiguous, but to me it looks weird and confusing - if a user put the variable in the nested block like that, it's almost certain he actually meant to write { my $foo; } and the . was put there erroneously. You are probably right, but are the twigils actually special? or is it just a naming convention. But given that the variable will be accessible to all methods via the closure mechanism, the only thing missing I think is the ability to get at the variable via introspection. Now, as for class methods, I suppose it is possible to just stash then in the classes symbol table like with variables. However, do we then loose the method call syntax? Well, if it belongs to the module part of the class, the syntax would be Bar::method(...), right? Yes, but the . is the method invocation operator, the :: is package symbol table access. I think they really mean different things. This also means that they would not (directly) be inheritable since inheritence moves along superclass lines, and not with @ISA. Well, namespaces should generally be inheritable. I don't think this is true, this is a Perl 5-ism. How else would lexical namespaces inject variables from outer block into the inner? I think you are confusing namespacing with scoping. The scope rules are as such that the inner can access see the outer. I guess at the package level declaration that Class1 is Class2 would just inject symbols from one module into the other? (yes, this is kinda handwavy :/ ) I don't think this would be so, unless you explicitly asked for it. I am also not sure what you mean about multi-methods either, could you please explain more? Uhm. I'm not sure either. :) The way I read Larry's mail, multimethods use .isa operator to detect whether $foo belongs to Foo. And for every class, Foo.isa(Foo) is true (this is exceptional behaviour of .isa). So (sidebar: it will probably use .does actually, but this an as yet unresolved detail) multi bla (Foo $f); would accept both bla(Foo.new()) and bla(::Foo). (Larry, please correct me on this if I'm misparaphrasing you :) ) I am not 100% sure this is true given basic multi-method behavior, however there is no reason we cannot either special case this, or do some other kind of trickery to make it happen. Anyway, this makes me cringe on a certain level, although I'm not sure I can put the reason into words. Strictly speaking, it's bad only if there are cases where multimethod should behave differently for a class and an instance. One case I can think of is class AutoCreation { ... }; multi dwimmy_instance(class AutoCreation $obj) { $obj.new() } multi dwimmy_instance(AutoCreation $obj) { $obj } I think we need some ability to differentiate between the class version of Foo and the instance version of Foo. Stevan
Re: Re(vised): Proposal to make class method non-inheritable
Disclaimer: I don't ~~ @larry :) [EMAIL PROTECTED] wrote: class Bar { our $.bar; { my $.foo; } } I assume that the leading "$." is what makes the difference, however, IIRC the "$." is just part of the name, and no more special than that. Which means that I can choose that name (yes, it is evil, but I assume I can still do it). U... I'm not sure that allowing $. injection from the nested blocks is a good thing. I don't think it's ambiguous, but to me it looks weird and confusing - if a user put the variable in the nested block like that, it's almost certain he actually meant to write { my $foo; } and the . was put there erroneously. But given that the variable will be accessible to all methods via the closure mechanism, the only thing missing I think is the ability to get at the variable via introspection. Now, as for class methods, I suppose it is possible to just stash then in the classes symbol table like with variables. However, do we then loose the method call syntax? Well, if it belongs to the module part of the class, the syntax would be Bar::method(...), right? This also means that they would not (directly) be inheritable since inheritence moves along superclass lines, and not with @ISA. Well, namespaces should generally be inheritable. How else would lexical namespaces inject variables from outer block into the inner? I guess at the package level declaration that Class1 is Class2 would just inject symbols from one module into the other? (yes, this is kinda handwavy :/ ) I am also not sure what you mean about multi-methods either, could you please explain more? Uhm. I'm not sure either. :) The way I read Larry's mail, multimethods use .isa operator to detect whether $foo belongs to Foo. And for every class, Foo.isa(Foo) is true (this is exceptional behaviour of .isa). So multi bla (Foo $f); would accept both bla(Foo.new()) and bla(::Foo). (Larry, please correct me on this if I'm misparaphrasing you :) ) Anyway, this makes me cringe on a certain level, although I'm not sure I can put the reason into words. Strictly speaking, it's bad only if there are cases where multimethod should behave differently for a class and an instance. One case I can think of is class AutoCreation { ... }; multi dwimmy_instance(class AutoCreation $obj) { $obj.new() } multi dwimmy_instance(AutoCreation $obj) { $obj } (I pulled the syntax out of my nose for this). Anyhow, this looks like a pretty contrieved usage. I'm still trying to think of a non-contrieved, more realistic situation when you might actually want something like this. Miro
Re: Re(vised): Proposal to make class method non-inheritable
On Oct 17, 2005, at 12:32 PM, TSa wrote: This also means that they would not (directly) be inheritable since inheritence moves along superclass lines, and not with @ISA. I am also not sure what you mean about multi-methods either, could you please explain more? Symmetric MMD at least has the meaning that the above mentioned asymmetry doesn't exist for infix ops on the syntactic level: $x foo $y; which neither means ($x foo) $y; # calculated prefix op from postfix foo nor $x (foo $y); # calculated postfix op from prefix foo. I can't speak for metric MMD, though. But IIRC, the metric is 'sum of superclass hops'. -- Okay, I think I understand now. So if all class methods were multis, then we would not need inheritance. The MMD would use the (super|sub) class relationships, and be able to call (super|sub)classes automagically. However, IIRC, the "everything is a multi-method" proposal was not accepted. Could this then be just a restricted case of multi-methods? So all class methods would just use MMD dispatch rules on the invocant parameter, therefore allowing an implicit pseudo-inheritence to take place? Larry, is this what you were thinking? Stevan
Re: Re(vised): Proposal to make class method non-inheritable
HaloO, Stevan Little wrote: Now, as for class methods, I suppose it is possible to just stash then in the classes symbol table like with variables. However, do we then loose the method call syntax? I think not. But the current notion seems to drift closer to my idea of "free methods" versus "slot calls". To express that in therms of your initial equation object == state + behavior would be expressed on the first meta level as class == data(structure) + code(structure) which means that the compiler syntactically splits the class definition into an active and a passive part. Call this symmetry breaking if you like. The same asymmetry exist in the method call syntax $foo .action; because the compiler compiles that into a lookup of 'action' from the method part of the MIR (Meta Information Repository, World in Russian) followed by a dispatch on the actual runtime type referred to by $foo. In other words, the name that connects the compile and runtime is 'action'. If this name shall be retrieved from the instance at runtime without going through the method dispatcher I have proposed to wrap-up the name as $foo :action; Without the $ sigil a bare foo is interpreted as a name lookup in the code part of the MIR which is the union of all subs and methods---subs beeing nullary methods so to speak. That gives foo .action; # dispatch action on retval of foo and foo :action; # bind named param in the call to foo. These two things are on the tightest precedence level, which in my eyes makes . and : meta sigils or some such. We could actually combine these with the idea of the current name beeing a sigilled underscore and '_._' denoting the current method on the current topic, and '_:_' the current key from the current topic :) Hmm, these would make {_} the closure of the current continuation or so. This also means that they would not (directly) be inheritable since inheritence moves along superclass lines, and not with @ISA. I am also not sure what you mean about multi-methods either, could you please explain more? Symmetric MMD at least has the meaning that the above mentioned asymmetry doesn't exist for infix ops on the syntactic level: $x foo $y; which neither means ($x foo) $y; # calculated prefix op from postfix foo nor $x (foo $y); # calculated postfix op from prefix foo. I can't speak for metric MMD, though. But IIRC, the metric is 'sum of superclass hops'. --
Re: 'self' and .foo (was: Re: Re(vised): Proposal to make class method non-inheritable)
On 2005-10-15 15:28, "Ilmari Vacklin" <[EMAIL PROTECTED]> wrote: > On Sat, Oct 15, 2005 at 09:49:30AM -0700, Larry Wall wrote: >> On Sat, Oct 15, 2005 at 07:39:36PM +0300, wolverian wrote: >> : IMHO just call it "self" (by default) and be done with it. :) >> >> Let it be so. > > Somewhat off-tangent: does this mean that .foo is always $_.foo? INCOMING!! . . . Hunh. Who'da thunk - apparently even *flame* wars can trigger post-traumatic stress disorder...
Re: Re(vised): Proposal to make class method non-inheritable
Miroslav On Oct 17, 2005, at 7:35 AM, Miroslav Silovic wrote: [EMAIL PROTECTED] wrote: I think what bothers me most about this is that it seems there is no way to tell the difference between class methods and instance methods. That the distinction is only made when the body of the method does something which is is not supposed to do (method called with a class invocant attempts to access an instance variable, etc). This is one of the major problems that I have always had with Perl 5 OO. That there is a very fuzzy fuzzy line between the responsibilities of a class and an instance. I can see the notion of "a class which is not yet instantiated", this makes sense in many contexts. But I don't think that in order to have this, we need to bring back this element of Perl 5 OO. I think we can still have all the behaviors you have been describing, and still keep classes and their instances as distinct entities. It just recently occured to me that Class is a Package. Actually, to be precise, Class is a Module, and Module is a Package. Modules add the version and authority portions to the name of a Package, and it seems that exporting (as traits?) are Module things, and not Package things. So, on the object model level, class methods/attributes belong to the Package part of a class, while instance methods/attributes belong to the Class part of a class - insofar as they're made distinct by use of my/our. Well, currently in the prototype, class attributes defined with "our" are stored in the Classes symbol table (which is inherited from Package). Discussions with autrijus lead me to not address class attributes defined by "my", since he felt they would be better addressed as "normal" variables within the scope of the class body. This is somewhat of an implementation detail, however, I think it may also play a part in how these things work. For instance, in the following example, is "$.foo" a class attribute? or just a local variable for the inner block? class Bar { our $.bar; { my $.foo; } } I assume that the leading "$." is what makes the difference, however, IIRC the "$." is just part of the name, and no more special than that. Which means that I can choose that name (yes, it is evil, but I assume I can still do it). But given that the variable will be accessible to all methods via the closure mechanism, the only thing missing I think is the ability to get at the variable via introspection. Now, as for class methods, I suppose it is possible to just stash then in the classes symbol table like with variables. However, do we then loose the method call syntax? This also means that they would not (directly) be inheritable since inheritence moves along superclass lines, and not with @ISA. I am also not sure what you mean about multi-methods either, could you please explain more? Thanks, Stevan
Re: Re(vised): Proposal to make class method non-inheritable
[EMAIL PROTECTED] wrote: I think what bothers me most about this is that it seems there is no way to tell the difference between class methods and instance methods. That the distinction is only made when the body of the method does something which is is not supposed to do (method called with a class invocant attempts to access an instance variable, etc). This is one of the major problems that I have always had with Perl 5 OO. That there is a very fuzzy fuzzy line between the responsibilities of a class and an instance. I can see the notion of "a class which is not yet instantiated", this makes sense in many contexts. But I don't think that in order to have this, we need to bring back this element of Perl 5 OO. I think we can still have all the behaviors you have been describing, and still keep classes and their instances as distinct entities. It just recently occured to me that Class is a Package. So, on the object model level, class methods/attributes belong to the Package part of a class, while instance methods/attributes belong to the Class part of a class - insofar as they're made distinct by use of my/our. Larry's proposal is to remove that difference for multimethods. Personally I can't think of a good objection to that idea (except if it may be bad for performance - is there a plan to infer types and auto-inline? I that case, declaring that you don't care about instance part of the object's functionality can really help). Miro
'self' and .foo (was: Re: Re(vised): Proposal to make class method non-inheritable)
On Sat, Oct 15, 2005 at 09:49:30AM -0700, Larry Wall wrote: > On Sat, Oct 15, 2005 at 07:39:36PM +0300, wolverian wrote: > : IMHO just call it "self" (by default) and be done with it. :) > > Let it be so. Somewhat off-tangent: does this mean that .foo is always $_.foo? > Larry -- Ilmari Vacklin
Re: Re(vised): Proposal to make class method non-inheritable
Larry, On Oct 15, 2005, at 11:25 AM, Larry Wall wrote: On Sat, Oct 15, 2005 at 10:34:34AM -0400, Stevan Little wrote: : I think what bothers me most about this is that it seems there is no : way to tell the difference between class methods and instance : methods. That the distinction is only made when the body of the : method does something which is is not supposed to do (method called : with a class invocant attempts to access an instance variable, etc). : : This is one of the major problems that I have always had with Perl 5 : OO. That there is a very fuzzy fuzzy line between the : responsibilities of a class and an instance. But you haven't actually said why this is a problem. If you want to know at compile time that a method must be called with an object that has been instantiated, it seems to me that it's pretty easy to tell 99% of the time whether the method body has made reference to $?SELF in some form or other. And if the compiler can determine that, why should the user have to specify it? I think it is a problem because they are two distinct areas of responsibility. A class creates and manages instances, while an object is the thing which the class creates. The object only manages it's own data. As for whether the compiler can tell the difference, I am not sure you are correct here. Take this for instance: class Foo { method bar { $?CLASS.baz(); } } What is &bar? A class method? or a instance method? Clearly $?CLASS is valid inside instance methods, and surely you can call methods on $?CLASS within instance methods. There is an ambiguity here. One possible solution of course is that this method is both, that it could basically be this (to use the old A12 syntax): class Foo { method bar (Class|Foo $f:) { $?CLASS.baz(); } } I am fine with that personally. My biggest concern is that we are able to fit the syntax into *a* meta-model. As I said before, I don't have a problem scrapping the current version and starting on v3.0, I enjoy writing and thinking about these things, so you will get no resistance from me. However, I want to be sure that I know what it needs to do, then I can determine if I even need to re-write it or not. : I can see the notion of "a class which is not yet instantiated", this : makes sense in many contexts. But I don't think that in order to have : this, we need to bring back this element of Perl 5 OO. I think we can : still have all the behaviors you have been describing, and still keep : classes and their instances as distinct entities. Well sure, they're at least opposite ends of a continuum. But we may usefully smudge the distinction in the middle unless you can show actual damage from this. I don't think there is actually damage, we just have methods which can be called in either context. How to implement this is fairly easy, so I am not worried about that. I am just not comfortable with *all* methods being in this grey area. And as you pointed out in your other message, your notion of class is mostly hidden behind .meta in my scheme of things anyway. And generally the compiler will know by inspection whether the body is referring to the dynamic class through .meta, the static class through $?CLASS, or the dynamic instance through $?SELF. Yes, except in the case I show above, but then we can just use the solution I show above. (And yes, it bothers me that $?CLASS is static while $?SELF is dynamic. The latter is an abuse of the $? sigil, which ought to be reserved for entities known to the compiler. Maybe we should rename $?SELF to something that looks more dynamic. $*SELF is dynamic, but implies global. Hmm, if $.foo() is really a self call, maybe we could make a case for self being $$. Of course, there's never been any controversy here about what to call "self", oh no... :-) I don't even want to get into this debate, I am just the meta-monkey, nothing more :) Thanks, Stevan
Re: Re(vised): Proposal to make class method non-inheritable
Larry, On Oct 15, 2005, at 11:25 AM, Larry Wall wrote: : >But we have to think a bit more about the notion of currying class : >objects into real objects, or something approaching real objects. : : This is an interesting thought, I will have to ponder it some, but it : has a nice smell. Of course I love indian food and functional : programming, so that may be personal bias :) Could turn out that $obj.assuming is just a generalization of &func.assuming. That'd be kinda cool. What would be in the other side of $obj.assuming? Assuming $obj is an instance already, what are we creating with it? Or perhaps you mean Object.assuming()? In which case it would produce some partially instantiated class. Please clarify :) Stevan
Re: Re(vised): Proposal to make class method non-inheritable
On Sat, Oct 15, 2005 at 07:39:36PM +0300, wolverian wrote: : On Sat, Oct 15, 2005 at 08:25:15AM -0700, Larry Wall wrote: : > [snip] : > : > Of course, there's never been any controversy here about what to call : > "self", oh no... :-) : : IMHO just call it "self" (by default) and be done with it. :) Let it be so. Larry
Re: Re(vised): Proposal to make class method non-inheritable
On Sat, Oct 15, 2005 at 08:25:15AM -0700, Larry Wall wrote: > [snip] > > Of course, there's never been any controversy here about what to call > "self", oh no... :-) IMHO just call it "self" (by default) and be done with it. :) -- wolverian, contributing to the general disagreement
Re: Re(vised): Proposal to make class method non-inheritable
On Sat, Oct 15, 2005 at 10:34:34AM -0400, Stevan Little wrote: : I think what bothers me most about this is that it seems there is no : way to tell the difference between class methods and instance : methods. That the distinction is only made when the body of the : method does something which is is not supposed to do (method called : with a class invocant attempts to access an instance variable, etc). : : This is one of the major problems that I have always had with Perl 5 : OO. That there is a very fuzzy fuzzy line between the : responsibilities of a class and an instance. But you haven't actually said why this is a problem. If you want to know at compile time that a method must be called with an object that has been instantiated, it seems to me that it's pretty easy to tell 99% of the time whether the method body has made reference to $?SELF in some form or other. And if the compiler can determine that, why should the user have to specify it? : I can see the notion of "a class which is not yet instantiated", this : makes sense in many contexts. But I don't think that in order to have : this, we need to bring back this element of Perl 5 OO. I think we can : still have all the behaviors you have been describing, and still keep : classes and their instances as distinct entities. Well sure, they're at least opposite ends of a continuum. But we may usefully smudge the distinction in the middle unless you can show actual damage from this. And as you pointed out in your other message, your notion of class is mostly hidden behind .meta in my scheme of things anyway. And generally the compiler will know by inspection whether the body is referring to the dynamic class through .meta, the static class through $?CLASS, or the dynamic instance through $?SELF. (And yes, it bothers me that $?CLASS is static while $?SELF is dynamic. The latter is an abuse of the $? sigil, which ought to be reserved for entities known to the compiler. Maybe we should rename $?SELF to something that looks more dynamic. $*SELF is dynamic, but implies global. Hmm, if $.foo() is really a self call, maybe we could make a case for self being $$. Of course, there's never been any controversy here about what to call "self", oh no... :-) : >But we have to think a bit more about the notion of currying class : >objects into real objects, or something approaching real objects. : : This is an interesting thought, I will have to ponder it some, but it : has a nice smell. Of course I love indian food and functional : programming, so that may be personal bias :) Could turn out that $obj.assuming is just a generalization of &func.assuming. That'd be kinda cool. Larry
Re: Re(vised): Proposal to make class method non-inheritable
Larry, On Oct 14, 2005, at 2:15 PM, Larry Wall wrote: Look guys, I want it to just consistently be method bark (Dog $d) {...} regardless of how instantiated the dog is. Think of partially instantiated subroutines via .assuming. A sub is a sub regardless of how much it's been curried. So who cares if it's a complete Dog or a partial Dog, or a completely generic Dog? Nobody cares until you try to call a specific method that relies on some specific attribute. If you call a sub with an incomplete definition, you should be prepared to handle the exception. If you call a method with an incomplete object, you should be prepared to handle the exception. Of course, by that argument, $d should be considered defined even if it's a completely uninstantiated class object. With subs the final proof of actual well-definedness (not to be confused with .defined()) is whether it can be bound to a particular set of arguments. It's a rather lazy definition of well-definedness. I'm proposing that all objects follow the same model of not caring how well they're defined until you actually try to use them for something. I don't think I care any more about whether classes test as defined or not. It's like reality--there are a lot of complex problems where the simplest way to simulate them is via reality itself, and all other simulations are guaranteed to be slower. I think what bothers me most about this is that it seems there is no way to tell the difference between class methods and instance methods. That the distinction is only made when the body of the method does something which is is not supposed to do (method called with a class invocant attempts to access an instance variable, etc). This is one of the major problems that I have always had with Perl 5 OO. That there is a very fuzzy fuzzy line between the responsibilities of a class and an instance. I can see the notion of "a class which is not yet instantiated", this makes sense in many contexts. But I don't think that in order to have this, we need to bring back this element of Perl 5 OO. I think we can still have all the behaviors you have been describing, and still keep classes and their instances as distinct entities. But we have to think a bit more about the notion of currying class objects into real objects, or something approaching real objects. This is an interesting thought, I will have to ponder it some, but it has a nice smell. Of course I love indian food and functional programming, so that may be personal bias :) Stevan
Re: Re(vised): Proposal to make class method non-inheritable
Larry, I have been giving a lot of thought to the way you have been describing classes lately. I think I understand where you are going with it, but I need to understand some of the details. On Oct 14, 2005, at 2:15 PM, Larry Wall wrote: This only reinforces my view that all the meta stuff for Dog must be via the .meta or the associated package. There is no Class object. It's a false dichotomy. Class is a role that manages partially instantiated objects, just as Routine (or whatever it is these days) is a role that manages partially instantiated sub calls. And they mostly manage by delegation to .meta. If I understand you correctly then, what I have been calling a class object is just really the "thing" on the other end of .meta. When I say "class object", I mean some kind of object instance which contains all the information to describe a class (methods, meta- attributes, superclass list, etc). This can just as easily be called a metaclass instance too, it makes no difference to me. As for the idea that "Class is a role that manages partially instantiated objects", I am not sure i am understanding what you mean here. I am assuming this is along the lines of the "Class's are a special form of undef" idea. In that case I can see where maybe the Class "thing" is simply a parameterized role of some kind which has the following behaviors: 1) it evaluates to undef in an expression my Dog $fido; if ($fido) { # this won't run, $fido is not yet defined } 2) it acts as a proxy if a method is called on it my Dog $fido; $fido .= new(); If this is true, then maybe Class looks something like this: role Class[MetaClassType $T] { # evaluate to false in bool context method prefix:? () { bool::false } # probably need to overload some other # operators here too, but I will leave # that for now # the AUTOMETH checks for an calls # any method you attempt to call on # this particular class # ( I am not sure about the details # of the code here, but you get the # idea I think ) method AUTOMETH { $T.can($_).([EMAIL PROTECTED]) } } Then if this were so, then the following: my Dog $fido; Would be de-sugared into: my $fido = Class[Dog].new(); At least this is how I am seeing it currently in my head. Please let me know if I am way off the mark here, I am trying to understand how this all will work. Ideally it can fit into the current meta-model prototype as designed, if not, I have no problem re-writing it again, but I just need to wrap my head around how this should work. Thanks much, Stevan
Re: Re(vised): Proposal to make class method non-inheritable
On Fri, Oct 14, 2005 at 01:43:39PM +1100, Stuart Cook wrote: : On 14/10/05, Stevan Little <[EMAIL PROTECTED]> wrote: : > So anyway, here are a few ideas, in no particular order: : > : >method bark (::Dog $d:) { ... } : ># not sure if this notation is already taken or not : > : >method bark ($Dog $d:) { ... } : ># not sure I like this one myself, but to me it helps to re- : > enforce the singleton nature of the class instance : > : >method bark (Dog) { ... } : ># this would be similar to functional languages where the : > parameter matches a value, not the type of a value. : ># The user would then be forced to use $?CLASS inside (this one is : > probably too much B&D) : > : >classmethod bark { ... } : ># you can't get more specific than this :) : > : > Okay, thats all for now, however, be on the lookout for some other : > mails on the specifics of class method dispatch. If we are going to : > do it, we need to do it right. : : How about: : : method bark (Dog ::K:) { ... } : : Where ::K must hold a class that is a subclass of Dog. Or 'is a : subtype of', or 'does', or whatever the most correct term is in this : context. Look guys, I want it to just consistently be method bark (Dog $d) {...} regardless of how instantiated the dog is. Think of partially instantiated subroutines via .assuming. A sub is a sub regardless of how much it's been curried. So who cares if it's a complete Dog or a partial Dog, or a completely generic Dog? Nobody cares until you try to call a specific method that relies on some specific attribute. If you call a sub with an incomplete definition, you should be prepared to handle the exception. If you call a method with an incomplete object, you should be prepared to handle the exception. Of course, by that argument, $d should be considered defined even if it's a completely uninstantiated class object. With subs the final proof of actual well-definedness (not to be confused with .defined()) is whether it can be bound to a particular set of arguments. It's a rather lazy definition of well-definedness. I'm proposing that all objects follow the same model of not caring how well they're defined until you actually try to use them for something. I don't think I care any more about whether classes test as defined or not. It's like reality--there are a lot of complex problems where the simplest way to simulate them is via reality itself, and all other simulations are guaranteed to be slower. But we have to think a bit more about the notion of currying class objects into real objects, or something approaching real objects. This only reinforces my view that all the meta stuff for Dog must be via the .meta or the associated package. There is no Class object. It's a false dichotomy. Class is a role that manages partially instantiated objects, just as Routine (or whatever it is these days) is a role that manages partially instantiated sub calls. And they mostly manage by delegation to .meta. Larry
Re: Re(vised): Proposal to make class method non-inheritable
On 14/10/05, Stevan Little <[EMAIL PROTECTED]> wrote: > So anyway, here are a few ideas, in no particular order: > >method bark (::Dog $d:) { ... } ># not sure if this notation is already taken or not > >method bark ($Dog $d:) { ... } ># not sure I like this one myself, but to me it helps to re- > enforce the singleton nature of the class instance > >method bark (Dog) { ... } ># this would be similar to functional languages where the > parameter matches a value, not the type of a value. ># The user would then be forced to use $?CLASS inside (this one is > probably too much B&D) > >classmethod bark { ... } ># you can't get more specific than this :) > > Okay, thats all for now, however, be on the lookout for some other > mails on the specifics of class method dispatch. If we are going to > do it, we need to do it right. How about: method bark (Dog ::K:) { ... } Where ::K must hold a class that is a subclass of Dog. Or 'is a subtype of', or 'does', or whatever the most correct term is in this context. (I seem to recall Damian mentioning something like this on the list somewhere, but I might have misunderstood him and made it up myself.) I do notice, though, that most of these class-method forms don't stand out very well--maybe something like 'classmethod' might be best after all, particularly if class methods aren't heavily used. Stuart
Re(vised): Proposal to make class method non-inheritable
Well, I suspected there would not be much support for my initial proposal on class methods, but I felt I had to try. Not being the type of person who gives up easily, I want to revise the proposal (incorporating some of the ideas in the responses). I propose that class methods are inheritable, but have the following behaviors/attributes: 1) Autogenerated Class attribute accessors will be submethods. This means that this code: class Foo { our $.bar; } will be functionally identical to this code: class Foo { our $.bar; submethod bar (Class $c:) { $.bar } } This will ensure that class methods which are specifically tied to some kind of state within the class will not be inherited. At least not by default, if you want that behavior, then you can do this: class Foo { our $.bar; method bar (Class $c:) { $.bar } } 2) Class methods be defined more specifically I think that "method (Class $c:) { ... }" is kind of ugly, and if we use eigenclasses to implement class methods, is not even correct. Ideally we have some kind of way to represent Larry's "Dog but undef" concept. This could be thought of as being the prototypical instance (for those who like prototype based OO), and it would also be the invocant for all class methods for Dog. So anyway, here are a few ideas, in no particular order: method bark (::Dog $d:) { ... } # not sure if this notation is already taken or not method bark ($Dog $d:) { ... } # not sure I like this one myself, but to me it helps to re- enforce the singleton nature of the class instance method bark (Dog) { ... } # this would be similar to functional languages where the parameter matches a value, not the type of a value. # The user would then be forced to use $?CLASS inside (this one is probably too much B&D) classmethod bark { ... } # you can't get more specific than this :) Okay, thats all for now, however, be on the lookout for some other mails on the specifics of class method dispatch. If we are going to do it, we need to do it right. Thanks, Stevan