Re: overloading the variable declaration process
On 2/12/06, Thomas Sandlass <[EMAIL PROTECTED]> wrote: > > > IIRC, you can always create a new method for a class, even outside of > > > its definition, simply by ensuring that the first parameter to be > > > passed in will be an object of that type: > > > > > > method bark (Dog $_) { ... } > > > > I don't think this is true unless it is a multi method, in which case > > it is not actually a method of the of the class, but instead just > > DWIMs because of MMD and the fact we allow an invocant calling style > > freely. > > Yes, the question of ownership of methods is still > somewhat unresolved. I think we need to distinguish > something I've called slots in an object from free > (multi) methods that are defined outside of the class > definition block. BTW, do the outsiders have access > to the private data slots with the $! twigil? I think that multimethods defined outside of the scope of the class should not have access to the classes data slots, it should use the accessors. And those multimethods should live in the package in which they are defined. The class implementation can stash refs to multimethods which apply to it for optimization reasons, but this has nothing to do with the language design itself. As far as method name disambiguation, we should use the calling style (invocant vs. normal function call) to determine which method to call. I am sure there are other edge cases to be uncovered here as well, but I can't think of them at the moment. Stevan
Re: overloading the variable declaration process
Thomas Sandlass wrote: > > > or maybe > > > > > > method Dog.bark () { ... } > > > > Yes that works too. > > Shouldn't that read Dog::bark? Why the dot? Because I'm not 100% with the proper syntax of things. The intent was to add a bark() method to Dog during runtime. -- Jonathan "Dataweaver" Lang
RE: overloading the variable declaration process
Stevan Little wrote: > ^Dog is an instance of the MetaClass, while Dog (no ^ sigil) is the > "class" (actually it's a prototypical instance of the class which the > metaclass ^Dog describes, but you dont really need to know that to use > it). > > ^Dog.can(bark) # false > Dog.can(bark) # true Wasn't the ^ sigil dropped in favor of a 0..^n list creation op? So the first line is spelled ::Dog.can(bark) # false instead? > Of course you have a conceptual circulatiry issue now because well,.. > what is a MetaClass? Well it could be an instance of a MetaMetaClass, > but what is that an instance of? This could go on forever (turtles all > the way down as it is sometimes called). > > But in practice you either just stop and say "this is as far as it > goes", or you bootstrap your class model somehow and "tie the knot". > I prefer the boostrapping as it is much more elegant and tends to > allow for much more flexibility. I agree. Your cicularity is basically an a-priori infinity conceptually one level outside of the meta system. And there will be an orthogonal type/kind system. > > IIRC, you can always create a new method for a class, even outside of > > its definition, simply by ensuring that the first parameter to be > > passed in will be an object of that type: > > > > method bark (Dog $_) { ... } > > I don't think this is true unless it is a multi method, in which case > it is not actually a method of the of the class, but instead just > DWIMs because of MMD and the fact we allow an invocant calling style > freely. Yes, the question of ownership of methods is still somewhat unresolved. I think we need to distinguish something I've called slots in an object from free (multi) methods that are defined outside of the class definition block. BTW, do the outsiders have access to the private data slots with the $! twigil? > > or maybe > > > > method Dog.bark () { ... } > > Yes that works too. Shouldn't that read Dog::bark? Why the dot? -- $TSa.greeting := "HaloO"; # mind the echo!
Re: overloading the variable declaration process
Stevan Little wrote: > Jonathan Lang wrote: > > OK; apparently, what I meant when I asked "what methods and attributes > > does ^Dog have?" is what you're talking about when you speak of which > > methods ^Dog will respond to. To me, an object has whatever methods > > that it responds to. > > I disagree, an object is an instance of a class. A class "has" the > methods that the object will respond too. You would not want to store > all the methods in each instance, it would not make sense. Each > instance needs to share a set of methods, and those methods are stored > in the class. I think that we're talking past each other: you're trying to educate me on how a programmer should think about objects and classes; I'm trying to figure out how a non-programmer thinks of them. To non-programmers (and amateur programmers), objects aren't instances of classes; classes are categories of related objects. Objects have behaviors and characteristics; classes are a convenient shorthand for describing behaviors and characteristics common to a set. Objects come first, while classes are thought of in the context of objects. The same implementation can be used for both perspectives: "dogs can bark; Spot is a dog; therefore, Spot can bark" is a form of reasoning that underlies using the class-and-instance model for the "back-end" implementation of the object-and-category paradigm. "classes have methods; objects respond to them" is part of the classes-and-instances paradigm; but that isn't really how people think. In terms of practical differences: under the classes-and-instances paradigm, if you want to create an object whose behavior differs slightly from a given class, you need to create a subclass that has the desired behavior and to create the object as an instance of that subclass. With the object-and-category paradigm, there's nothing that insists that every object's behavior must conform precisely to the behaviors described by its classes; the latter are "merely" rules of thumb to apply to the former until you learn differently, and behaviors can be added, removed, or tweaked on an individual basis. This is why (last I checked) "but" creates a behind-the-scenes 'singleton' subclass for the new object instead of demanding that a new subclass be explicitly created, and why I suggested the possibility of adding, replacing, or removing methods for individual objects as well as for classes (which, presumably, would also be implemented under the hood by replacing the object's class by a 'singleton' subclass). > > > ^Dog.name # Dog > > > ^Dog.version # 0.0.1 (or something similiar of course) > > > ^Dog.authority # cpan:LWALL or email:[EMAIL PROTECTED] > > > > > > ^Dog.identifier # returns the string Dog-0.0.1-cpan:LWALL > > > > Would it be valid to speak of ^$spot? If so, what would ^$spot.name be? > > There is no such thing as a ^$spot. OK. The only reason I was thinking in those terms was because of the possibility that $spot might be based on one of those behind-the-scenes customized subclasses that I mentioned earlier: if my Dog $brutus but cannot("bark"); How do you access the subclass of Dog that $brutus is the instance of? > > IIRC, you can always create a new method for a class, even outside of > > its definition, simply by ensuring that the first parameter to be > > passed in will be an object of that type: > > > > method bark (Dog $_) { ... } > > I don't think this is true unless it is a multi method, in which case > it is not actually a method of the of the class, but instead just > DWIMs because of MMD and the fact we allow an invocant calling style > freely. I was under the impression that the distinction between a method and a multi-method was how many of the parameters get used to dispatch: methods aren't really "owned" by classes, any more than class definition is a declarative process; it just looks that way on the surface. Am I wrong about this? > > or maybe > > > > method Dog.bark () { ... } > > Yes that works too. But TIMTOWTDI, and each has it's own benefits. I'm aware of that, and was proposing this as Another Way. > Your above approach works fine while you are writing the code, but is > not as useful for dynamically adding a method at runtime (unless you > use eval(), but that gets ugly). I was under the impression that class definition was fundamentally a functional process dressed up as a declarative process. "method Dog.bark () { ... }" would seem to me to be a means of continuing that process "after the fact" - that is, adding a method to a class after you've left the class definition block. It seems to serve exactly the same purpose as using the metaclass API. That is, I see it as being alternate syntax for "^Dog.add_method(bark => method () { ... })". > > To fetch a method, why not have .can() return a reference to the > > method upon success? I might even go so far as to treat can() as an > > lvalue, using the assignment of a coderef as an alternate way
Re: overloading the variable declaration process
On 2/9/06, Jonathan Lang <[EMAIL PROTECTED]> wrote: > Stevan Little wrote: > > Jonathan Lang wrote: > > > OK. To help me get a better idea about what's going on here, what > > > sorts of attributes and methods would ^Dog have? > > > > Well, a metaclass describes the behaviors and attributes of a class, > > and ^Dog is an *instance* of the metaclass. So actually ^Dog would not > > actually have attributes and methods since it is an instance. > > Huh? A dog can bark; so the Dog class should have a method called > 'bark'. Or does 'can' not mean what it seems to mean? ^Dog is an instance of the MetaClass, while Dog (no ^ sigil) is the "class" (actually it's a prototypical instance of the class which the metaclass ^Dog describes, but you dont really need to know that to use it). ^Dog.can(bark) # false Dog.can(bark) # true This is a very important distinction. Saying "Dog class has a method called 'bark'", implies the following statements are true - Dog will respond to the method called "bark". - Given my Dog $spot, $spot will respond to the method called "bark". - ^Dog (the metaclass instance which describes a class called "Dog") does *not* respond to the method called "bark". - ^Dog (since it describes the class called "Dog") manages all of the methods which Dog and $spot will respond too, one of which is called "bark". There is a clear line between the meta-level (where ^Dog lives) and the user-level (where Dog and $spot) live. This is a line which is heavily blurred in Perl 5, and in many OO languages (aside from Smalltalk, CLOS and a few others) the meta-level is just not accessible at all from user-land. > > That said, I think ^Dog would probably respond to methods like > > these (some of which are described in S12): > > OK; apparently, what I meant when I asked "what methods and attributes > does ^Dog have?" is what you're talking about when you speak of which > methods ^Dog will respond to. To me, an object has whatever methods > that it responds to. I disagree, an object is an instance of a class. A class "has" the methods that the object will respond too. You would not want to store all the methods in each instance, it would not make sense. Each instance needs to share a set of methods, and those methods are stored in the class. Well what is a class? In Perl 5 a class is simply a package, and the subs in that package are methods. In Perl 6 however, a class will be an instance of another class, the MetaClass. These two things are really not that different when you think about it. - A Perl 5 package holds methods for you by storing them in the symbol table. You can add, get, remove these methods from the symbol table using the symbol table API. - A Perl 6 class holds methods for you by storing them inside an instance variable in an instance of the MetaClass, and you can add, get, remove these methods by using the methods of MetaClass. Of course you have a conceptual circulatiry issue now because well,.. what is a MetaClass? Well it could be an instance of a MetaMetaClass, but what is that an instance of? This could go on forever (turtles all the way down as it is sometimes called). But in practice you either just stop and say "this is as far as it goes", or you bootstrap your class model somehow and "tie the knot". I prefer the boostrapping as it is much more elegant and tends to allow for much more flexibility. > > ^Dog.name # Dog > > ^Dog.version # 0.0.1 (or something similiar of course) > > ^Dog.authority # cpan:LWALL or email:[EMAIL PROTECTED] > > > > ^Dog.identifier # returns the string Dog-0.0.1-cpan:LWALL > > Would it be valid to speak of ^$spot? If so, what would ^$spot.name be? There is no such thing as a ^$spot. The ^ is the "class" sigil, and will hold metaclass instances only, just as variables with % will only holds hashes, and variables with @ will only holds arrays, etc. > > I would like to see some methods like this: > > > > # dynamically add a method that > > # Dog and $spot would respond to > > ^Dog.add_method(bark => method () { ... }); > > > > Which would be like doing this in Perl 5: > > > > no strict 'refs'; > > *{'Dog::bark'} = sub { ... }; > > IIRC, you can always create a new method for a class, even outside of > its definition, simply by ensuring that the first parameter to be > passed in will be an object of that type: > > method bark (Dog $_) { ... } I don't think this is true unless it is a multi method, in which case it is not actually a method of the of the class, but instead just DWIMs because of MMD and the fact we allow an invocant calling style freely. > or maybe > > method Dog.bark () { ... } Yes that works too. But TIMTOWTDI, and each has it's own benefits. Your above approach works fine while you are writing the code, but is not as useful for dynamically adding a method at runtime (unless you use eval(), but that gets ugly). Using the metaclass API dynamically adding a method to a class at runtime is trivial, ag
Re: overloading the variable declaration process
Stevan Little wrote: > Jonathan Lang wrote: > > OK. To help me get a better idea about what's going on here, what > > sorts of attributes and methods would ^Dog have? > > Well, a metaclass describes the behaviors and attributes of a class, > and ^Dog is an *instance* of the metaclass. So actually ^Dog would not > actually have attributes and methods since it is an instance. Huh? A dog can bark; so the Dog class should have a method called 'bark'. Or does 'can' not mean what it seems to mean? > That said, I think ^Dog would probably respond to methods like > these (some of which are described in S12): OK; apparently, what I meant when I asked "what methods and attributes does ^Dog have?" is what you're talking about when you speak of which methods ^Dog will respond to. To me, an object has whatever methods that it responds to. > ^Dog.name # Dog > ^Dog.version # 0.0.1 (or something similiar of course) > ^Dog.authority # cpan:LWALL or email:[EMAIL PROTECTED] > > ^Dog.identifier # returns the string Dog-0.0.1-cpan:LWALL Would it be valid to speak of ^$spot? If so, what would ^$spot.name be? > I would like to see some methods like this: > > # dynamically add a method that > # Dog and $spot would respond to > ^Dog.add_method(bark => method () { ... }); > > Which would be like doing this in Perl 5: > > no strict 'refs'; > *{'Dog::bark'} = sub { ... }; IIRC, you can always create a new method for a class, even outside of its definition, simply by ensuring that the first parameter to be passed in will be an object of that type: method bark (Dog $_) { ... } or maybe method Dog.bark () { ... } > And of course if you can add a method, you will need to be able to > fetch and delete them as well, so a &get_method and &remove_method > would be in order as well. To fetch a method, why not have .can() return a reference to the method upon success? I might even go so far as to treat can() as an lvalue, using the assignment of a coderef as an alternate way of adding or changing the object's behavior on the fly: method bark (Dog $_:) { ... }; Dog.can("bark") = method () { ... }; # Teach the dog a new trick Dog.can("bark") = true; # inform the dog that it ought to know how to bark, without telling it how, yet; equivalent to a literal "= method { ... }". Dog.can("bark") = false; # tell the dog to forget how to bark. Dog.can("bark") = undef; # Ditto. (Doing this to Dog DWIMs to modifying the behavior of all dogs at once - you're declaring that "dogs can bark" or "this is how dogs bark", whereas doing it to $spot DWIMs to modifying the behavior of $spot only: "$brutus.can('bark') = false": my best friend's pet dog seems to have lost the capacity to bark in its old age; that doesn't mean that dogs in general can't bark.) Similar things might be done with .has (for attributes), .isa (for superclasses), and .does (for roles). -- Jonathan "Dataweaver" Lang
Re: overloading the variable declaration process
On 2/8/06, Jonathan Lang <[EMAIL PROTECTED]> wrote: > Stevan Little wrote: > > Yes, that is correct, because: > > > > Dog.isa(Dog) # true > > $spot.isa(Dog) # true > > ^Dog.isa(Dog) # false > > > > In fact ^Dog isa MetaClass (or Class whatever you want to call it). > > > > At least that is how I see/understand it. > > OK. To help me get a better idea about what's going on here, what > sorts of attributes and methods would ^Dog have? Well, a metaclass describes the behaviors and attributes of a class, and ^Dog is an *instance* of the metaclass. So actually ^Dog would not actually have attributes and methods since it is an instance. That said, I think ^Dog would probably respond to methods like these (some of which are described in S12): ^Dog.name # Dog ^Dog.version # 0.0.1 (or something similiar of course) ^Dog.authority # cpan:LWALL or email:[EMAIL PROTECTED] ^Dog.identifier # returns the string Dog-0.0.1-cpan:LWALL I would like to see some methods like this: # dynamically add a method that # Dog and $spot would respond to ^Dog.add_method(bark => method () { ... }); Which would be like doing this in Perl 5: no strict 'refs'; *{'Dog::bark'} = sub { ... }; And of course if you can add a method, you will need to be able to fetch and delete them as well, so a &get_method and &remove_method would be in order as well. And if you can add methods, surely you can add attributes, so &(add|get|remove)_attribute would be needed. ^Dog.add_attribute(:label<$fur>, :access); Would be equivalent to saying this: class Dog is reopened { has $fur is rw; } And ^Dog would also provide access to infromation about super and subclasses as well. So &superclasses and &subclasses methods would make sense too. We would also need methods to deal with Role relationships as well. So, given the above items, the class MetaClass might look something like this: class MetaClass { has $name is rw; has $version is rw; has $authority is rw; has @superclasses; has @subclasses; has %methods; has %attributes; method identifier { ... } method superclasses { ... } method subclasses { ... } method add_method { ... } method get_method { ... } method remove_method { ... } method add_attribute { ... } method get_attribute { ... } method remove_attribute { ... } } So given this, you could almost look at this code: class Foo-0.0.1-cpan:JRANDOM { has $bar is rw; method baz (Foo $self:) { ... } } As being roughly equivalent to the following code: ^Foo := MetaClass.new(); ^Foo.name('Foo'); ^Foo.version(0.0.1); ^Foo.authority(:cpan); ^Foo.add_attribute(:label<$bar>, :access); ^Foo.add_method(baz => method (Foo $self) { ... }); Of course this is mostly unspecced, and it is still unclear exactly how much of this meta-level API will be accessible in Perl 6 itself. And as far the the Pugs work on this goes, we plan to have something similar to the above available in the next release (6.28.0). Hope this helps. Stevan
Re: overloading the variable declaration process
Stevan Little wrote: > Yes, that is correct, because: > > Dog.isa(Dog) # true > $spot.isa(Dog) # true > ^Dog.isa(Dog) # false > > In fact ^Dog isa MetaClass (or Class whatever you want to call it). > > At least that is how I see/understand it. OK. To help me get a better idea about what's going on here, what sorts of attributes and methods would ^Dog have? -- Jonathan "Dataweaver" Lang
Re: overloading the variable declaration process
On 2/8/06, Jonathan Lang <[EMAIL PROTECTED]> wrote: > Consider "my Dog $spot". From the Perl6-to-English Dictionary: > Dog: a dog. > $spot: the dog that is named Spot. > ^Dog: the concept of a dog. > > Am I understanding things correctly? > > If so, here's what I'd expect: a dog can bark, or Spot can bark; but > the concept of a dog cannot bark: > can Dog "bark"; # answer: yes > can $spot "bark"; # answer: yes > can ^Dog "bark"; # answer: no Yes, that is correct, because: Dog.isa(Dog) # true $spot.isa(Dog) # true ^Dog.isa(Dog) # false In fact ^Dog isa MetaClass (or Class whatever you want to call it). At least that is how I see/understand it. Stevan
Re: overloading the variable declaration process
Consider "my Dog $spot". From the Perl6-to-English Dictionary: Dog: a dog. $spot: the dog that is named Spot. ^Dog: the concept of a dog. Am I understanding things correctly? If so, here's what I'd expect: a dog can bark, or Spot can bark; but the concept of a dog cannot bark: can Dog "bark"; # answer: yes can $spot "bark"; # answer: yes can ^Dog "bark"; # answer: no -- Jonathan "Dataweaver" Lang
Re: overloading the variable declaration process
On Tue, Feb 07, 2006 at 07:32:18PM -0500, Stevan Little wrote: : On 2/7/06, Matt Fowles <[EMAIL PROTECTED]> wrote: : > Stevan~ : > : > I am going to assume that you intended to reply to perl 6 language, : > and thus will include your post in its entirety in my response. : : Yes, sorry... I missed the "reply to all" button on the gmail UI by a : few pixels I guess. Thank you for forwarding. : : > Now that everyone is on the same page, I will go about responding : > : : # snip some code : : > > : > > class Pipe::Stem { : > >has $composed_of; : > >has $color; : > >has $length; : > >has $filter = bool::false; : > > } : > : > so far I am mostly with you, except one question. Does bool::false;> just provide a default? : : Yes, that is a default value. I assume that most Pipe smokers don't : like filters in their pipes, I might be wrong on that one because I am : not a pipe smoker :) : : > > You would then model the different pipes you sell; : > > : > > class MagrittePipe { : > > has $stem = Pipe::Stem.new( : > > :composed_of, : > > :color, : > > :length : > > ); : > > has $bowl = Pipe::Bowl.new( : > > :composed_of, : > > :color, : > > :size : > > ); : > > } : > > : > > Now, you might say, why not make the MagrittePipe an instance of Pipe, : > > and give the Pipe class a few more attributes, like a name. Well, if : > > you did that then you couldn't subclass it of course. : > : > Actually, I was going to ask why not make MagrittePipe inherit from Pipe. : : Ooops, forgot that part it should infact inherit from Pipe. And of : course you can do that dynamically with the metamodel ;) : : > > Well, using introspection, it becomes very simple to discover various : > > qualities about your inventory, enough to probably even autogenerate : > > the HTML pages for your online-web store (powered by Perl 6 of : > > course). And lets not forget the uber-cool Perl 6 Object Database : > > which you are using to store your real-time inventory in (all : > > metamodel powered of course). And of course if you want, you can use : > > the DistributedObjectProxy metaclass which will automatically make : > > your objects distributed so that your door-to-door Pipe saleforce can : > > update your inventory in real time from their cellphones. And your R&D : > > department can use the built-in (but as yet unspeced) logic : > > programming features of Perl 6 to mine your customer information from : > > your (previously mentioend) object database and genetically "grow" : > > new, more desireable Pipe products (which is easy to do since your : > > metaclasses are programatically composable (and no I don't mean eval : > > $code)). : > : > I think you mis-understand me. I do not question the value of a : > powerful meta-model. Quite the contrary I want to see Perl 6 have a : > meta-model more powerful and accessible then CLOS. I see it as a : > necessity for a language that plans to truely scale in the future. : > : > What I do question is the usefullness of having bare class names : > represent these "prototype objects". I just don't really understand : > what they are for or do. : : Well, to be totally honest, I think only Larry truely understands : their usage, but to the best of my understanding they are intented to : serve a number of roles; : : (Larry, please correct me if I am wrong here) : : - to allow for introspection of the class. : : After all ^Foo.can() is really just a series of method calls to the : Foo metaobject. And besides ^Foo.meta.can() is 5 more characters to : type!! : : - provide an invocant for "class" methods. : : Larry does not like the class-method/instance-method distinction (in : fact it seems he doesn't even like the class/instance distinction : either), and has declared that a "class method" is really just a : method of the class which does not access any instance attributes. : Well, this complicates the type signature of the invocant, and we need : an invocant that the type-checker can check. : : In Perl 5, classes were just package names which were just strings. : This will not work in Perl 6 in the presence of a reasonably decent : type checker, the class needs to be *something*. Now Larry has also : declared that he does not like the idea of a "class object", I think : this is because that means that a properly typed method signature for : a class method would look like this: : : class Foo { : method foo (Class $class:) { : say "I am a class method, and proud of it"; : } : } : : According to the signature, this method takes any Class instance as an : invocant. Well : thats just not right because it should only accept the Class instance : which represents the Foo class. But we can't (at least I dont think we : can) be that
Re: overloading the variable declaration process
Stevan~ On 2/7/06, Stevan Little <[EMAIL PROTECTED]> wrote: > > > After all Foo is just a specific instance of the class Class. > > Shhh... class objects don't exist ... I was never here,... I will I > count to three and when I snap my fingers you will awaken and will > have forgotten all about class Class. > > 1 ... 2 ... 3 ... *snap* ... What!?!? Where was I? Oh, yeah. As I was saying, I think we just take C++'s object system exactly. Matt -- "Computer Science is merely the post-Turing Decline of Formal Systems Theory." -Stan Kelly-Bootle, The Devil's DP Dictionary
Re: overloading the variable declaration process
On 2/7/06, Matt Fowles <[EMAIL PROTECTED]> wrote: > Stevan~ > > On 2/7/06, Stevan Little <[EMAIL PROTECTED]> wrote: > > > > Well, to be totally honest, I think only Larry truely understands > > their usage, but to the best of my understanding they are intented to > > serve a number of roles; > > I agree with you about that, which is part of what bothers me. > > > > > (Larry, please correct me if I am wrong here) > > > > - to allow for introspection of the class. > > > > After all ^Foo.can() is really just a series of method calls to the > > Foo metaobject. And besides ^Foo.meta.can() is 5 more characters to > > type!! > > > > - provide an invocant for "class" methods. > > > > Larry does not like the class-method/instance-method distinction (in > > fact it seems he doesn't even like the class/instance distinction > > either), and has declared that a "class method" is really just a > > method of the class which does not access any instance attributes. > > Well, this complicates the type signature of the invocant, and we need > > an invocant that the type-checker can check. > > > > In Perl 5, classes were just package names which were just strings. > > This will not work in Perl 6 in the presence of a reasonably decent > > type checker, the class needs to be *something*. Now Larry has also > > declared that he does not like the idea of a "class object", I think > > this is because that means that a properly typed method signature for > > a class method would look like this: > > > > class Foo { > > method foo (Class $class:) { > > say "I am a class method, and proud of it"; > > } > > } > > > > According to the signature, this method takes any Class instance as an > > invocant. Well > > thats just not right because it should only accept the Class instance > > which represents the Foo class. But we can't (at least I dont think we > > can) be that specific, at least not easily enough to also allow this > > method to be called by an instance of Foo as well. > > > > So, the solution, use "prototype instances" for "class objects". So > > now we can properly type our class method for both Foo and $foo like > > this: > > > > class Foo { > > method foo (Foo $class:) { > > say "I am a class method, and proud of it"; > > } > > } > > > > And whalla, we have a class/instance method ala Perl 5 and it is > > properly type checkable too. > > > > Of course I might be totally wrong here, but this is my best grasp on > > the subject. > > Perl 6 allows dispatch on value (if I am not mistaken). Thus, just as we > have a > > sub fact( Int 0 ) { return 0; } > sub fact( Int $n ) { return $n * fact($n-1); } > > Why not have class methods take the form > > class Foo { > method foo (Class Foo) { > say "I am a class method, and proud of it"; > } > } > > They are still well types (I think), and properly restricts the types > allowed for foo. Larry is going to have to answer the why part of that descision. However, I would venture to guess that dispatch on value is much harder to grok in this case than dispatch on type. Especially since it requires that you understand (at least partially) the metamodel. > After all Foo is just a specific instance of the class Class. Shhh... class objects don't exist ... I was never here,... I will I count to three and when I snap my fingers you will awaken and will have forgotten all about class Class. 1 ... 2 ... 3 ... *snap*
Re: overloading the variable declaration process
Stevan~ On 2/7/06, Stevan Little <[EMAIL PROTECTED]> wrote: > > Well, to be totally honest, I think only Larry truely understands > their usage, but to the best of my understanding they are intented to > serve a number of roles; I agree with you about that, which is part of what bothers me. > > (Larry, please correct me if I am wrong here) > > - to allow for introspection of the class. > > After all ^Foo.can() is really just a series of method calls to the > Foo metaobject. And besides ^Foo.meta.can() is 5 more characters to > type!! > > - provide an invocant for "class" methods. > > Larry does not like the class-method/instance-method distinction (in > fact it seems he doesn't even like the class/instance distinction > either), and has declared that a "class method" is really just a > method of the class which does not access any instance attributes. > Well, this complicates the type signature of the invocant, and we need > an invocant that the type-checker can check. > > In Perl 5, classes were just package names which were just strings. > This will not work in Perl 6 in the presence of a reasonably decent > type checker, the class needs to be *something*. Now Larry has also > declared that he does not like the idea of a "class object", I think > this is because that means that a properly typed method signature for > a class method would look like this: > > class Foo { > method foo (Class $class:) { > say "I am a class method, and proud of it"; > } > } > > According to the signature, this method takes any Class instance as an > invocant. Well > thats just not right because it should only accept the Class instance > which represents the Foo class. But we can't (at least I dont think we > can) be that specific, at least not easily enough to also allow this > method to be called by an instance of Foo as well. > > So, the solution, use "prototype instances" for "class objects". So > now we can properly type our class method for both Foo and $foo like > this: > > class Foo { > method foo (Foo $class:) { > say "I am a class method, and proud of it"; > } > } > > And whalla, we have a class/instance method ala Perl 5 and it is > properly type checkable too. > > Of course I might be totally wrong here, but this is my best grasp on > the subject. Perl 6 allows dispatch on value (if I am not mistaken). Thus, just as we have a sub fact( Int 0 ) { return 0; } sub fact( Int $n ) { return $n * fact($n-1); } Why not have class methods take the form class Foo { method foo (Class Foo) { say "I am a class method, and proud of it"; } } They are still well types (I think), and properly restricts the types allowed for foo. After all Foo is just a specific instance of the class Class. Matt -- "Computer Science is merely the post-Turing Decline of Formal Systems Theory." -Stan Kelly-Bootle, The Devil's DP Dictionary
Re: overloading the variable declaration process
On 2/7/06, Matt Fowles <[EMAIL PROTECTED]> wrote: > Stevan~ > > I am going to assume that you intended to reply to perl 6 language, > and thus will include your post in its entirety in my response. Yes, sorry... I missed the "reply to all" button on the gmail UI by a few pixels I guess. Thank you for forwarding. > Now that everyone is on the same page, I will go about responding > # snip some code > > > > class Pipe::Stem { > >has $composed_of; > >has $color; > >has $length; > >has $filter = bool::false; > > } > > so far I am mostly with you, except one question. Does bool::false;> just provide a default? Yes, that is a default value. I assume that most Pipe smokers don't like filters in their pipes, I might be wrong on that one because I am not a pipe smoker :) > > You would then model the different pipes you sell; > > > > class MagrittePipe { > > has $stem = Pipe::Stem.new( > > :composed_of, > > :color, > > :length > > ); > > has $bowl = Pipe::Bowl.new( > > :composed_of, > > :color, > > :size > > ); > > } > > > > Now, you might say, why not make the MagrittePipe an instance of Pipe, > > and give the Pipe class a few more attributes, like a name. Well, if > > you did that then you couldn't subclass it of course. > > Actually, I was going to ask why not make MagrittePipe inherit from Pipe. Ooops, forgot that part it should infact inherit from Pipe. And of course you can do that dynamically with the metamodel ;) > > Well, using introspection, it becomes very simple to discover various > > qualities about your inventory, enough to probably even autogenerate > > the HTML pages for your online-web store (powered by Perl 6 of > > course). And lets not forget the uber-cool Perl 6 Object Database > > which you are using to store your real-time inventory in (all > > metamodel powered of course). And of course if you want, you can use > > the DistributedObjectProxy metaclass which will automatically make > > your objects distributed so that your door-to-door Pipe saleforce can > > update your inventory in real time from their cellphones. And your R&D > > department can use the built-in (but as yet unspeced) logic > > programming features of Perl 6 to mine your customer information from > > your (previously mentioend) object database and genetically "grow" > > new, more desireable Pipe products (which is easy to do since your > > metaclasses are programatically composable (and no I don't mean eval > > $code)). > > I think you mis-understand me. I do not question the value of a > powerful meta-model. Quite the contrary I want to see Perl 6 have a > meta-model more powerful and accessible then CLOS. I see it as a > necessity for a language that plans to truely scale in the future. > > What I do question is the usefullness of having bare class names > represent these "prototype objects". I just don't really understand > what they are for or do. Well, to be totally honest, I think only Larry truely understands their usage, but to the best of my understanding they are intented to serve a number of roles; (Larry, please correct me if I am wrong here) - to allow for introspection of the class. After all ^Foo.can() is really just a series of method calls to the Foo metaobject. And besides ^Foo.meta.can() is 5 more characters to type!! - provide an invocant for "class" methods. Larry does not like the class-method/instance-method distinction (in fact it seems he doesn't even like the class/instance distinction either), and has declared that a "class method" is really just a method of the class which does not access any instance attributes. Well, this complicates the type signature of the invocant, and we need an invocant that the type-checker can check. In Perl 5, classes were just package names which were just strings. This will not work in Perl 6 in the presence of a reasonably decent type checker, the class needs to be *something*. Now Larry has also declared that he does not like the idea of a "class object", I think this is because that means that a properly typed method signature for a class method would look like this: class Foo { method foo (Class $class:) { say "I am a class method, and proud of it"; } } According to the signature, this method takes any Class instance as an invocant. Well thats just not right because it should only accept the Class instance which represents the Foo class. But we can't (at least I dont think we can) be that specific, at least not easily enough to also allow this method to be called by an instance of Foo as well. So, the solution, use "prototype instances" for "class objects". So now we can properly type our class method for both Foo and $foo like this: class Foo { method foo (Foo $class:)
Re: overloading the variable declaration process
Stevan~ I am going to assume that you intended to reply to perl 6 language, and thus will include your post in its entirety in my response. On 2/7/06, Stevan Little <[EMAIL PROTECTED]> wrote: > On 2/7/06, Matt Fowles <[EMAIL PROTECTED]> wrote: > > Larry~ > > > > On 2/7/06, Larry Wall <[EMAIL PROTECTED]> wrote: > > > > > > Indeed, and the modeling point of view is that $pipe is *also* just > > > a representation of the Pipe. Neither Pipe nor $pipe is the thing > > > itself. Most computer programs are about Something Else, so computer > > > languages should be optimized for talking about other things rather > > > than talking about themselves. The answer to > > > > > > Pipe.can("Smoke") > > > $pipe.can("Smoke") > > > > > > should be the same, not different. On the other hand, > > > > > > ^Pipe.can("Smoke") > > > > > > is a different matter, insofar as you're asking a question about a Class > > > object rather than a Pipe object. And now you get your Platonism back. > > > You just have to be explicit about it. > > > > I see the value of ^Pipe and $pipe as seperate objects which can be > > manipulated programmatically. What I don't really understand is what > > exactly Pipe is and where it would be useful. > > > > They way you have described Pipe feels a little muddy to me and I am > > unsure about its purpose and semantics. Is it just an object I ask > > `.can()` or does it have some deeper usefulness? > > Well since ^Pipe will really just be the same value as Pipe.meta, then > you can do many things with it (if I get my metamodel wishes that is). > Now, in keeping with the "examples of useful things for people other > than programmers and computers" spirit of this discussion, here is one > possible approach to using metaclasses in a constructive way. > > Okay, so lets assume you own a tobacco shop, and you have modeled a > Pipe hierarchy to represent all the pipes you sell. Your base classes > might look something like this: > > class Pipe { > has $stem; > has $bowl; > } > > class Pipe::Bowl { >has $composed_of; >has $color; >has $size; > } > > class Pipe::Stem { >has $composed_of; >has $color; >has $length; >has $filter = bool::false; > } > > You would then model the different pipes you sell; > > class MagrittePipe { > has $stem = Pipe::Stem.new( > :composed_of, > :color, > :length > ); > has $bowl = Pipe::Bowl.new( > :composed_of, > :color, > :size > ); > } > > Now, you might say, why not make the MagrittePipe an instance of Pipe, > and give the Pipe class a few more attributes, like a name. Well, if > you did that then you couldn't subclass it of course. > > class MagrittePipe::SpecialEngravedAnniversayEdition { > is MagrittePipe; > does Engraved[$engraving_text = "Ceci n'est pas une pipe"]; > does SpecialEdition[$type]; > } > > Now, what does all this have to do with metamodel? > > Well, using introspection, it becomes very simple to discover various > qualities about your inventory, enough to probably even autogenerate > the HTML pages for your online-web store (powered by Perl 6 of > course). And lets not forget the uber-cool Perl 6 Object Database > which you are using to store your real-time inventory in (all > metamodel powered of course). And of course if you want, you can use > the DistributedObjectProxy metaclass which will automatically make > your objects distributed so that your door-to-door Pipe saleforce can > update your inventory in real time from their cellphones. And your R&D > department can use the built-in (but as yet unspeced) logic > programming features of Perl 6 to mine your customer information from > your (previously mentioend) object database and genetically "grow" > new, more desireable Pipe products (which is easy to do since your > metaclasses are programatically composable (and no I don't mean eval > $code)). > > Of course, I am just dreaming here, but maybe I am not! Most of > this is already possible using CLOS (see the Franz's AllegroCL 8.0 > it's bad*ss IMO), so why can't we have it? > > Anyway, I hope that doesn't make your head hurt too much Matt ;) Now that everyone is on the same page, I will go about responding > class Pipe { > has $stem; > has $bowl; > } > > class Pipe::Bowl { >has $composed_of; >has $color; >has $size; > } > > class Pipe::Stem { >has $composed_of; >has $color; >has $length; >has $filter = bool::false; > } so far I am mostly with you, except one question. Does just provide a default? > > You would then model the different pipes you sell; > > class MagrittePipe { > has $stem = Pipe::Stem.new( > :composed_of, > :color, >
Re: overloading the variable declaration process
Larry~ On 2/7/06, Larry Wall <[EMAIL PROTECTED]> wrote: > > Indeed, and the modeling point of view is that $pipe is *also* just > a representation of the Pipe. Neither Pipe nor $pipe is the thing > itself. Most computer programs are about Something Else, so computer > languages should be optimized for talking about other things rather > than talking about themselves. The answer to > > Pipe.can("Smoke") > $pipe.can("Smoke") > > should be the same, not different. On the other hand, > > ^Pipe.can("Smoke") > > is a different matter, insofar as you're asking a question about a Class > object rather than a Pipe object. And now you get your Platonism back. > You just have to be explicit about it. I see the value of ^Pipe and $pipe as seperate objects which can be manipulated programmatically. What I don't really understand is what exactly Pipe is and where it would be useful. They way you have described Pipe feels a little muddy to me and I am unsure about its purpose and semantics. Is it just an object I ask `.can()` or does it have some deeper usefulness? Matt -- "Computer Science is merely the post-Turing Decline of Formal Systems Theory." -Stan Kelly-Bootle, The Devil's DP Dictionary
Re: overloading the variable declaration process
On Mon, Feb 06, 2006 at 10:41:02PM -0500, Matt Fowles wrote: : Larry~ : : On 2/6/06, Larry Wall <[EMAIL PROTECTED]> wrote: : > This is mostly motivated by linguistics rather than computer science, : > insofar as types/classes/roles in natural language are normally : > represented by generic objects rather than "meta" objects. When I : > ask in English: : > : > Can a dog bark? : > : > that's equivalent to asking in Perl 6: : > : > Dog.can('bark') : : Or you might think of it more as a question like "Can the ideal of a : dog bark?" the answer to which is of course "No, it doesn't exist.". As soon as you say "the ideal" you've chosen Platonism over Aristotelianism. :-) : Perhaps, I am just too firmly rooted in old paradigms but I think it : is very important not to conflate the representation of a thing with : the thing. : : http://en.wikipedia.org/wiki/Image:MagrittePipe.jpg Indeed, and the modeling point of view is that $pipe is *also* just a representation of the Pipe. Neither Pipe nor $pipe is the thing itself. Most computer programs are about Something Else, so computer languages should be optimized for talking about other things rather than talking about themselves. The answer to Pipe.can("Smoke") $pipe.can("Smoke") should be the same, not different. On the other hand, ^Pipe.can("Smoke") is a different matter, insofar as you're asking a question about a Class object rather than a Pipe object. And now you get your Platonism back. You just have to be explicit about it. Larry
Re: overloading the variable declaration process
On 2/6/06, Larry Wall <[EMAIL PROTECTED]> wrote: > So the basic answer to you question is, I think, yes. If Dog chooses > to always return true for .defined, then (in Haskell terms) it's more > like a Just type than a Maybe type. Perl 6's objects like to be Maybe > types by default, but you can override it. (I'm using the Haskell > terms loosely here, of course.) But the very concept of definedness > is getting mushy in Perl 6. What we need is more concepts of the > form "Is this *sufficiently* defined for what I want to do with it?" > That's why I proposed "defined according to a particular role" as > one way to ask that sort of question. So, if ^Dog describes a Dog which defines a $dog, do we need an undescribed() function? Just kidding... kinda. Ashley Winters
Re: overloading the variable declaration process
Larry~ On 2/6/06, Larry Wall <[EMAIL PROTECTED]> wrote: > This is mostly motivated by linguistics rather than computer science, > insofar as types/classes/roles in natural language are normally > represented by generic objects rather than "meta" objects. When I > ask in English: > > Can a dog bark? > > that's equivalent to asking in Perl 6: > > Dog.can('bark') Or you might think of it more as a question like "Can the ideal of a dog bark?" the answer to which is of course "No, it doesn't exist.". Perhaps, I am just too firmly rooted in old paradigms but I think it is very important not to conflate the representation of a thing with the thing. http://en.wikipedia.org/wiki/Image:MagrittePipe.jpg Matt -- "Computer Science is merely the post-Turing Decline of Formal Systems Theory." -Stan Kelly-Bootle, The Devil's DP Dictionary
Re: overloading the variable declaration process
On 2/6/06, Larry Wall <[EMAIL PROTECTED]> wrote: > This is mostly motivated by linguistics rather than computer science, > insofar as types/classes/roles in natural language are normally > represented by generic objects rather than "meta" objects. When I > ask in English: > > Can a dog bark? > > that's equivalent to asking in Perl 6: > > Dog.can('bark') That sentence is ambiguous. You can interpret it as: Can some dog bark? Or as: Can every dog bark? I think you meant the latter, however the sentence is leaning toward the former. "Can dogs bark?" would be less ambiguous in that respect. And while I'm starting to see the linguistic rationale behind this decision, I still can't find anything concrete that this buys us. Call me an American, but I like instant gratification. Luke
Re: overloading the variable declaration process
At 3:02 PM +0800 2/6/06, Audrey Tang wrote: On 2/6/06, Darren Duncan <[EMAIL PROTECTED]> wrote: Speaking briefly, I would like it if Perl 6 provided a way for a class (or role, or meta-class, etc) to declare that all variables declared to be of that type are automatically/implicitly set to a particular value at declaration time, so that they are not undefined > if the programmer using them doesn't explicitly set a value. If so, your use case can be satisfied by declaring that ::NumType (the class object) numifies to 0, and ::StrType stringifies to "", via the coerce form. That could be fine for some situations, but I was looking for a more generic solution for: my FooType $foo; # acts like we said .= new() $foo.do_action(); Essentially, that $foo is like or is a fully instantiated object on which you can call arbitrary FooType object methods as if someone set it with new(), but where in fact the user never did this. The coercing solution won't work if the types of use are not coersions to simple data types like strings or numbers. Thank you. -- Darren Duncan
Re: overloading the variable declaration process
On Sun, Feb 05, 2006 at 07:26:09PM -0800, Darren Duncan wrote: : Part way through writing this, I had a brief chat on #perl6 with : stevan (and apparently the meta-model is still quite in flux) and he : said my question was related to Larry's "class but undef" idea, and : that Larry should talk more about the subject. Aside from the fact that it's not a class, and not necessarily undef, "class but undef" is a good name for it. :-) I've been calling them prototype objects lately for lack of a better word. To me, the Real Class is the object instance hiding behind .meta. But when you say bare "Foo" you actually naming a generic object of the type ^Foo, which I see currently as shorthand for Foo.meta, and which any object that does Foo can get at if it needs metadata, including the Foo object itself. In short, Foo.does('Foo') This is mostly motivated by linguistics rather than computer science, insofar as types/classes/roles in natural language are normally represented by generic objects rather than "meta" objects. When I ask in English: Can a dog bark? that's equivalent to asking in Perl 6: Dog.can('bark') The "Dog" there is in the same type category as $dog, and specifically is *not* in the same type category as the class that is managing the logic behind the scenes. As a user, I'm thinking about "doggy" objects, not "classy" objects. It's the very same kind of linguistic reasoning that gives us "given" rather than "switch", and "when" rather than "case". People want to think about their problem's objects, not the language implementor's representations of those objects. Now in the case of .can, we do eventually end up asking the metaobject whether this objects supports the .bark method, but the point is that the user doesn't have to keep track of how many metas there are. Or looking at it the other way, any object can stand in for all its meta objects. This is how we think (I think). Psycholinguistially, every "dog" object in your brain is really a kind of partially instantiated object that is slowly being filled in with knowledge about the real world counterpart to your mental model. Your mental model is never perfect. The trend in the world today is away from monolithic computers that either know everything or nothing, and toward programs that have to work with imperfect knowledge that is generated or downloaded on the fly. So I think the modeling view of reality is the sweet spot for the future, and languages that have to know everything before they think they know anything are doomed to fail. Well, not fail, but have restricted ecological niches, such as rocket science. (And maybe not even there, as machines get more autonomous.) So the basic answer to you question is, I think, yes. If Dog chooses to always return true for .defined, then (in Haskell terms) it's more like a Just type than a Maybe type. Perl 6's objects like to be Maybe types by default, but you can override it. (I'm using the Haskell terms loosely here, of course.) But the very concept of definedness is getting mushy in Perl 6. What we need is more concepts of the form "Is this *sufficiently* defined for what I want to do with it?" That's why I proposed "defined according to a particular role" as one way to ask that sort of question. Hope this helps. Larry
Re: overloading the variable declaration process
On 2/6/06, Darren Duncan <[EMAIL PROTECTED]> wrote: > Speaking briefly, I would like it if Perl 6 provided a way for a > class (or role, or meta-class, etc) to declare that all variables > declared to be of that type are automatically/implicitly set to a > particular value at declaration time, so that they are not undefined > if the programmer using them doesn't explicitly set a value. In a somewhat related note, Perl 6 allows this form: my Dog $fido .= new; which may be treated as a special form (as is currently the case with Pugs). However if it's not, it would desugar to: my Dog $fido; $fido = $fido.new; which seem to imply that $fido is set to ::Dog (the dog class) as its initial value. However, that would potentially make this a no-op: my Dog $fido = Dog; which may make sense except that defined($fido) may need to be regulated as true even for the "my Dog $fido" case. If so, your use case can be satisfied by declaring that ::NumType (the class object) numifies to 0, and ::StrType stringifies to "", via the coerce form. Audrey
overloading the variable declaration process
All, Speaking briefly, I would like it if Perl 6 provided a way for a class (or role, or meta-class, etc) to declare that all variables declared to be of that type are automatically/implicitly set to a particular value at declaration time, so that they are not undefined if the programmer using them doesn't explicitly set a value. Here are usage examples: my NumType $foo; # implicitly contains a defined NumType of value 0 my StrType $bar; # implicitly contains a defined StrType of value '' Sure, the user could say ".= new()" or such, but I wanted a fallback if they didn't do that. Then when they come to just use that not explicitly set variable, it contains some type-defined reasonable default value. Presumably, the object meta-model would have an appropriate function defined for use at that time, which returns undef by default, and this function is what individual classes can override. Part way through writing this, I had a brief chat on #perl6 with stevan (and apparently the meta-model is still quite in flux) and he said my question was related to Larry's "class but undef" idea, and that Larry should talk more about the subject. Thank you. -- Darren Duncan