Re: Where is Manhattan Dispatch discussion?
--- John M. Dlugosz [EMAIL PROTECTED] wrote: I want to review and collect the wisdom of what has been discussed before. Someone mentioned this the other day, as being a significant consensus. But I can't find anything in the forum archives. Can someone point to the discussion, position papers, etc.? This this: http://use.perl.org/~luqui/journal/27362 Luke makes some interesting comments, but you'll want to click the Great Multimethod Debate link (http://tinyurl.com/5hm4ze). Cheers, Ovid -- Buy the book - http://www.oreilly.com/catalog/perlhks/ Perl and CGI - http://users.easystreet.com/ovid/cgi_course/ Personal blog - http://publius-ovidius.livejournal.com/ Tech blog - http://use.perl.org/~Ovid/journal/
my TypeName $x;
Hi, I'm looking for answers/clarification on what (if taken as individual programs) $x is in each case. my Int $x; # $x is Int protoobject say $x; # Int say $x.WHAT; # Int class Foo { } my Foo $x; # $x is Foo protoobject say $x; # Foo say $x.WHAT; # Foo # This means we can only assign to $x something that isa Foo? role Bar { } my Bar $x; # $x is ??? say $x; # ??? say $x.WHAT; # ??? # This means we can only assign to $x something that does Bar? subset EvenInt of Int where { $_ % 2 == 0 }; my EvenInt $x; # $x is ??? say $x; # ??? say $x.WHAT; # Failure? # This means we can only assign to $x something that matches the constraint class Dog { } class Cat { } my Dog|Cat $x; # $x is ??? say $x; # ??? say $x.WHAT; # Failure? # This means we can only assign to $x something that isa Dog or isa Cat Thanks, Jonathan
Re: my TypeName $x;
My thoughts: .HOW returns information concerning the implementation type; .WHAT returns information concerning the value type. .HOW and .WHAT stringify to something resembling the declarations that would be used to create them. Also bear in mind that Perl 6 uses prototype-based object orientation, except where it doesn't. As such, when I say that $x is a Foo below, what I mean is that $x is an object with Foo as its implementation type. Jonathan Worthington wrote: Hi, I'm looking for answers/clarification on what (if taken as individual programs) $x is in each case. my Int $x; # $x is Int protoobject say $x; # Int say $x.WHAT; # Int .WHAT is an Int; stringifies to Int. class Foo { } my Foo $x; # $x is Foo protoobject say $x; # Foo say $x.WHAT; # Foo # This means we can only assign to $x something that isa Foo? .WHAT is a Foo; stringifies to Foo. role Bar { } my Bar $x; # $x is ??? say $x; # ??? say $x.WHAT; # ??? # This means we can only assign to $x something that does Bar? This one's tricky: roles cannot be instantiated, so .WHAT cannot be a Bar. My gut reaction is that it's an anonymous class that does Bar and stringifies to Bar. As long as you don't have both a role and a class named Bar, this should not be a problem, since the value type isn't concerned with the implementation. If it is possible to have both a role and a class with the same name, you might be able to look at .WHAT.HOW (or .^WHAT) to figure out with which you're dealing. That is, the implementation type of the value type ought to provide more elaborate detail as to the nature of the value type. subset EvenInt of Int where { $_ % 2 == 0 }; my EvenInt $x; # $x is ??? say $x; # ??? say $x.WHAT; # Failure? # This means we can only assign to $x something that matches the constraint my guess: .WHAT is an EvenInt that stringifies to EvenInt. If you want to know about the structure of EvenInt (e.g., which class is it based on, and which subset restrictions have been applied to it), you would refer to .WHAT.HOW. class Dog { } class Cat { } my Dog|Cat $x; # $x is ??? say $x; # ??? say $x.WHAT; # Failure? # This means we can only assign to $x something that isa Dog or isa Cat my guess: .WHAT is a Junction that stringifies to Dog|Cat. To access the details as to which classes are in the junction and how they are joined, refer to appropriate methods (I believe that Junction includes a method that returns a Set of its members) or maybe to .WHAT.HOW. As well: class Dog { } role Pet { } my Pet Dog $x; say $x; say $x.WHAT; My guess is that .WHAT would be a (dis)Junction of a Dog and an anonymous class; the anonymous class does Pet and stringifies to Pet, while the Junction stringifies to Pet Dog. -- Jonathan Dataweaver Lang
Re: nested 'our' subs - senseless?
HaloO, David Green wrote: On 2008-May-3, at 5:04 pm, John M. Dlugosz wrote: What does this mean? our sub outer () { ... our sub inner () { ... } } inner; # defined? I don't know why it would be any more illegal than sub foo { our $var... }. The inner sub would be in the package's scope, but the name inner() would be available only in outer's scope. So that use of inner in the last line would be an error. Why that? I would think assuming that inner has a defined body, the our scope is around the outer somewhere. So the call there should succeed. Or is this not like our works? I assume that sub is not an our scope, BTW. Just to ensure that I get the our behavior right, consider sub foo { our $inner = 3; } sub bar { our $inner = 4; # redeclaration error? } say $inner; Does this print 3 even when foo was never called? IOW, is the assignment in foo a real one that only happens when foo is invoked or is it a pseudo-assignment that initializes the variables as if the whole statement where outside of foo? The latter would actually mean that the line in foo behaves different with or without the our. Without the our, the say would print 3, 4 or undef depending on the call sequence of foo and bar, right? Now how does that compare to sub definition? sub foo { our sub inner { 3 } } sub bar { our sub inner { 4 } # redefinition error? } say inner; My favorite is what the spec already seems to say: a symbol can be declared/defined exactly once in a scope. Usage prior to declaration/definition is an error. Usage of undeclared/undefined symbols is parsed provisionally as if defined/declared with our immediately before this use. Take e.g. class definition in a sub sub foo { our class inner { has $.x = 3 } } sub bar { our class inner { has $.x = 4 } # redefinition error? } say inner.new.x; The consequence of a sub not doing Package is that there are no separate foo::inner and bar::inner classes as in class foo { our class inner { has $.x = 3 } } class bar { our class inner { has $.x = 4 } } say inner.new.x; # error: no inner in scope My personal idea is to unify class and sub by allowing sub to do Package. Regards, TSa. -- The unavoidable price of reliability is simplicity -- C.A.R. Hoare Simplicity does not precede complexity, but follows it. -- A.J. Perlis 1 + 2 + 3 + 4 + ... = -1/12 -- Srinivasa Ramanujan
Re: my TypeName $x;
Upon further review: It might be possible that $x.WHAT returns a Signature object, with the value type of $x as the invocant (or return type?), and everything else empty. But that merely begs the question of how to introspect a Signature object. If I tell Perl 6 to say a Signature, what gets displayed? Can I ask Perl 6 to look at a particular parameter in a Signature? If so, what kind of object does the Signature object return if I ask it to give me its invocant? Surely not another Signature object? Whatever it is that Perl 6 returns in that case would probably work better as the return type of the .WHAT method, too. -- Jonathan Dataweaver Lang
Re: my TypeName $x;
On 2008 May 6, at 10:15, Jon Lang wrote: Signature? If so, what kind of object does the Signature object return if I ask it to give me its invocant? Surely not another Signature object? Whatever it is that Perl 6 returns in that case Turtle? :) -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] [EMAIL PROTECTED] system administrator [openafs,heimdal,too many hats] [EMAIL PROTECTED] electrical and computer engineering, carnegie mellon universityKF8NH
Re: Where is Manhattan Dispatch discussion?
I'm still in the dark... I find an positions for manhattan distance but no definition of what that is. I did find the alternative pod page earlier. --John Ovid publiustemp-perl6language2-at-yahoo.com |Perl 6| wrote: --- John M. Dlugosz [EMAIL PROTECTED] wrote: I want to review and collect the wisdom of what has been discussed before. Someone mentioned this the other day, as being a significant consensus. But I can't find anything in the forum archives. Can someone point to the discussion, position papers, etc.? This this: http://use.perl.org/~luqui/journal/27362 Luke makes some interesting comments, but you'll want to click the Great Multimethod Debate link (http://tinyurl.com/5hm4ze). Cheers, Ovid -- Buy the book - http://www.oreilly.com/catalog/perlhks/ Perl and CGI - http://users.easystreet.com/ovid/cgi_course/ Personal blog - http://publius-ovidius.livejournal.com/ Tech blog - http://use.perl.org/~Ovid/journal/
Re: Where is Manhattan Dispatch discussion?
John (): I'm still in the dark... I find an positions for manhattan distance but no definition of what that is. I did find the alternative pod page earlier. I don't have a whole answer for you, but a part that may help. What is generally meant by Manhattan distance is so-called L1 distance, i.e. Pythagoras' distance summation formula but without all the squaring and surding. http://en.wikipedia.org/wiki/Taxicab_geometry I imagine the concept is applied to parameter types in the discussion in question. // Carl
Re: Where is Manhattan Dispatch discussion?
Carl Mäsak wrote: John (): I'm still in the dark... I find an positions for manhattan distance but no definition of what that is. I did find the alternative pod page earlier. I don't have a whole answer for you, but a part that may help. What is generally meant by Manhattan distance is so-called L1 distance, i.e. Pythagoras' distance summation formula but without all the squaring and surding. http://en.wikipedia.org/wiki/Taxicab_geometry I imagine the concept is applied to parameter types in the discussion in question. To do multi method dispatch, you want to select the method that best matches the parameters in the call. One way to do that is to define a measure for distances between types and they use the method that's at the minimum distance. One simple measure is that a type is distance 0 from itself and distance 1 from it's immediate super-types, distance 2 from the immediate super-types of it's immediate super-types, etc. When dispatching over a single parameter picking the method at the minimum distance is the usual most specific type match. But when you want to do multi-method dispatch, you need some rule to combine the various distances of the individual parameters into a single measure value, then pick the method at the minimum distance by that combined measure. Manhattan Distance or Taxicab Distance is the rule that the combined distance is just the simple unweighted sum of the individual parameter distances. The is named after the fact that a taxi must follow the streets and to go 3 block north and 4 blocks west it must travel 7 blocks not the 5 blocks of the euclidean distance. BTW, if you want to do euclidean distance comparisons you don't need to do any square roots. Square root is monotonic, so order relations between the sums of squares values is the the same whether you take square roots or not. -- [EMAIL PROTECTED] [EMAIL PROTECTED]
Re: my TypeName $x;
HaloO, Jon Lang wrote: My thoughts: .HOW returns information concerning the implementation type; .WHAT returns information concerning the value type. My addition to these thoughts is that the WHAT and HOW are cascaded. Let's say we start at level 0 with the objects, thingies or however we want to name the atoms of our discourse. At the zero level HOW, WHAT etc. are vacuously identical with the object. They fall apart on level 1 from each other and among them selfs but they are all sets of level-0 objects. In general a level n concept contains level 0..^n objects and is the name for a something they share. .HOW and .WHAT stringify to something resembling the declarations that would be used to create them. Yeah. Stringification is relatively easy. class Foo { } my Foo $x; # $x is Foo protoobject say $x; # Foo say $x.WHAT; # Foo # This means we can only assign to $x something that isa Foo? .WHAT is a Foo; stringifies to Foo. Note that $x is not initialized. This means the say has to give something like undef of Foo. role Bar { } my Bar $x; # $x is ??? say $x; # ??? say $x.WHAT; # ??? # This means we can only assign to $x something that does Bar? This one's tricky: roles cannot be instantiated, so .WHAT cannot be a Bar. What? I would say it is a level 1 WHAT. The next level concept $x.WHAT.WHAT is role. BTW, there are not very many levels up. My gut reaction is that it's an anonymous class that does Bar and stringifies to Bar. As long as you don't have both a role and a class named Bar, this should not be a problem, since the value type isn't concerned with the implementation. If it is possible to have both a role and a class with the same name, you might be able to look at .WHAT.HOW (or .^WHAT) to figure out with which you're dealing. That is, the implementation type of the value type ought to provide more elaborate detail as to the nature of the value type. Hmm, are these meta accessors commutative? I.e. are $x.WHAT.HOW and $x.HOW.WHAT the identical level 2 entities? I would rather opt for $x.HOW of a role .WHAT.WHAT to be the level 1 undef which is a set of interesting level 0 values of undef. subset EvenInt of Int where { $_ % 2 == 0 }; my EvenInt $x; # $x is ??? say $x; # ??? say $x.WHAT; # Failure? # This means we can only assign to $x something that matches the constraint my guess: .WHAT is an EvenInt that stringifies to EvenInt. If you want to know about the structure of EvenInt (e.g., which class is it based on, and which subset restrictions have been applied to it), you would refer to .WHAT.HOW. I would argue that $x.WHAT.WHAT is subset. I think the idea of introspection is to have $x.WHAT.of return Int as a level 1 WHAT and $x.WHAT.where return the constraint closure. That said I would expect $x.HOW to be the identical level 1 HOW object that $x.WHAT.of.HOW returns. When Int.WHAT.WHAT is a role then this is undef of Int. class Dog { } class Cat { } my Dog|Cat $x; # $x is ??? say $x; # ??? say $x.WHAT; # Failure? # This means we can only assign to $x something that isa Dog or isa Cat my guess: .WHAT is a Junction that stringifies to Dog|Cat. To access the details as to which classes are in the junction and how they are joined, refer to appropriate methods (I believe that Junction includes a method that returns a Set of its members) or maybe to .WHAT.HOW. On level 1 the WHATs of Dog and Cat are distinct. Dog|Cat is a level 2 WHAT. The level 2 $x.WHAT.HOW is a union. $x.WHAT.WHAT is class. As well: class Dog { } role Pet { } my Pet Dog $x; say $x; say $x.WHAT; My guess is that .WHAT would be a (dis)Junction of a Dog and an anonymous class; the anonymous class does Pet and stringifies to Pet, while the Junction stringifies to Pet Dog. Again the say $x should print undef of Pet Dog. Similar to above $x.WHAT.HOW is an intersection. But $x.WHAT.WHAT is role|class and the question is what their common abstraction is. Though, whatever it is, you get it with $x.WHAT.WHAT.WHAT. But you can't call .new on it. The $x.HOW might be Dog but $x can't store an object created by its .new method because Dog.new.WHAT is in the part of the level 1 Dog that is not part of the level 2 WHAT Pet Dog. So to initialize you need my Pet Dog $x = .new does Pet; After this $x.HOW.HOW is Dog. Since the anonymous class created by does is not of interest the $x.WHAT remains the level 2 WHAT Pet Dog. I know that this sounds like turtles all the way down but the levels of abstraction are all derived from the source code. So, as long as your source is finite so is the WHAT structure over the objects. The worst that can happen is that there is a 1:1 mapping between a lower level at the one above it. -- The unavoidable price of reliability is simplicity -- C.A.R. Hoare Simplicity does not precede complexity, but follows it. -- A.J. Perlis 1 + 2 + 3 + 4 + ... = -1/12 -- Srinivasa Ramanujan
Re: Where is Manhattan Dispatch discussion?
HaloO, Mark A. Biggar wrote: To do multi method dispatch, you want to select the method that best matches the parameters in the call. The fundamental flaw of metric mmd is that it trades degrees of specificity. Consider the subtype chain E : D : C : B : A where the rule is that having an E it is better handled by a method dealing with a D than one dealing with an A. The same is the case for having a D being better handled by a C than an A method. Now consider a multi with the two signatures :(A,C,C) and :(D,A,A) and a call with (E,D,D) that goes to :(D,A,A) since 7 8. But note that it handles the two Ds as As instead of Cs as in single dispatch. Dispatch has to go to the single most capable implementation *not* to the least misfit! The call above has to be brought to the attention of a programmer. Regards, TSa. -- The unavoidable price of reliability is simplicity -- C.A.R. Hoare Simplicity does not precede complexity, but follows it. -- A.J. Perlis 1 + 2 + 3 + 4 + ... = -1/12 -- Srinivasa Ramanujan
MMD thoughts 2008
TSa Thomas.Sandlass-at-barco.com |Perl 6| wrote: The fundamental flaw of metric mmd is that it trades degrees of specificity. Consider the subtype chain E : D : C : B : A where the rule is that having an E it is better handled by a method dealing with a D than one dealing with an A. The same is the case for having a D being better handled by a C than an A method. Now consider a multi with the two signatures :(A,C,C) and :(D,A,A) and a call with (E,D,D) that goes to :(D,A,A) since 7 8. But note that it handles the two Ds as As instead of Cs as in single dispatch. OK, why would someone create those forms in the first place? The subtyping relationship could mean either value subset (e.g. integer passed to code that can handle reals) or polymorphic isa objects. The implementation should treat the E correctly because of virtual functions on E, even though the code was written for an A. So why write different forms with =related= classes? I would define operators with the same name around unrelated classes, so I can use that operator with things that don't already know what to do. So why are we focusing on the pathalogical cases? That's like saying we should not support division because you could divide by zero. Rather, what is the common typical use? For the bad stuff, don't do that and do this instead. I think the MMD should work well and be tuned for the areas in which it ought to be used, and the above problem analyzed to see what the programmer was really trying to accomplish. Maybe for special tuning in hacked-up (as opposed to nicely refactored code) we need something like submethods, that handle the exact case and don't get in the way of other distances. Maybe some of this should be done with generics rather than MMD. For example, I don't need to define something on a wide variety of number-like types individually, I'll use generic types to specify the minimal properties of the kind of type it applies to, and that the arguments match. So my MMD is between two forms: anything that is integral in nature and anything that is a type of Vehicle, without any analysis concerning whether a Bus is more like a generic Vehicle than a BCD is like an abstract integer concept. --John
Re: my TypeName $x;
TSa wrote: Jon Lang wrote: My thoughts: .HOW returns information concerning the implementation type; .WHAT returns information concerning the value type. BTW, S12 more or less confirms the above: .WHAT returns a prototype object that stringifies to its short name, while .HOW allows introspection of the attributes and methods and composed roles and inherited classes and... My addition to these thoughts is that the WHAT and HOW are cascaded. Let's say we start at level 0 with the objects, thingies or however we want to name the atoms of our discourse. At the zero level HOW, WHAT etc. are vacuously identical with the object. They fall apart on level 1 from each other and among them selfs but they are all sets of level-0 objects. In general a level n concept contains level 0..^n objects and is the name for a something they share. In English, please? I _think_ that you're saying that you can use WHAT and HOW recursively: that is, you can talk about WHAT.WHAT, WHAT.HOW, HOW.WHAT, HOW.HOW, etc. If so, note a few caveats: first, if $x is a Foo, then $x.WHAT will be a Foo. As such, there is no difference between $x.WHAT and $x.WHAT.WHAT. Likewise, forget about my comments about $x.WHAT.HOW; since $x is of exactly the same type as $x.WHAT, you can get the same information by saying $x.HOW as you could about $x.WHAT.HOW. Second, $x.HOW.WHAT gives you a prototype of the metaclass object. If you're ever doing type checking that refers to the metaclass class, this might be useful; otherwise, don't bother. Third, $x.HOW.HOW would let you look at the inner workings of the metaclass class. Going beyond that would be redundant, since you'd be using a metaclass object to look at the metaclass class. role Bar { } my Bar $x; # $x is ??? say $x; # ??? say $x.WHAT; # ??? # This means we can only assign to $x something that does Bar? This one's tricky: roles cannot be instantiated, so .WHAT cannot be a Bar. What? I would say it is a level 1 WHAT. The next level concept $x.WHAT.WHAT is role. BTW, there are not very many levels up. Again, English please? As I said, roles cannot be instantiated. $x is not a Bar; it is an object of an anonymous class that does Bar. $x.WHAT is a prototype object of $x, meaning that it, too, is an object of an anonymous class that does Bar. The only difference between them is that $x may eventually have a value assigned to it; $x.WHAT never will. Well... that, and $x.WHAT stringifies differently than $x does. subset EvenInt of Int where { $_ % 2 == 0 }; my EvenInt $x; # $x is ??? say $x; # ??? say $x.WHAT; # Failure? # This means we can only assign to $x something that matches the # constraint my guess: .WHAT is an EvenInt that stringifies to EvenInt. If you want to know about the structure of EvenInt (e.g., which class is it based on, and which subset restrictions have been applied to it), you would refer to .WHAT.HOW. I would argue that $x.WHAT.WHAT is subset. I think the idea of introspection is to have $x.WHAT.of return Int as a level 1 WHAT and $x.WHAT.where return the constraint closure. That said I would expect $x.HOW to be the identical level 1 HOW object that $x.WHAT.of.HOW returns. When Int.WHAT.WHAT is a role then this is undef of Int. Ah; _that's_ what you mean by cascading levels. Ugh. By my understanding, $x and $x.WHAT are both the same kind of thing: they're both EvenInt. Again, the only difference is that $x.WHAT will always be undefined and will stringify to EvenInt. class Dog { } class Cat { } my Dog|Cat $x; # $x is ??? say $x; # ??? say $x.WHAT; # Failure? # This means we can only assign to $x something that isa Dog or isa Cat my guess: .WHAT is a Junction that stringifies to Dog|Cat. To access the details as to which classes are in the junction and how they are joined, refer to appropriate methods (I believe that Junction includes a method that returns a Set of its members) or maybe to .WHAT.HOW. On level 1 the WHATs of Dog and Cat are distinct. Dog|Cat is a level 2 WHAT. The level 2 $x.WHAT.HOW is a union. $x.WHAT.WHAT is class. Huh? -- Jonathan Dataweaver Lang
Minimal Distance (Re: Where is Manhattan Dispatch discussion?)
Mark A. Biggar mark-at-biggar.org |Perl 6| wrote: To do multi method dispatch, you want to select the method that best matches the parameters in the call. One way to do that is to define a measure for distances between types and they use the method that's at the minimum distance. One simple measure is that a type is distance 0 from itself and distance 1 from it's immediate super-types, distance 2 from the immediate super-types of it's immediate super-types, etc. When dispatching over a single parameter picking the method at the minimum distance is the usual most specific type match. But when you want to do multi-method dispatch, you need some rule to combine the various distances of the individual parameters into a single measure value, then pick the method at the minimum distance by that combined measure. Manhattan Distance or Taxicab Distance is the rule that the combined distance is just the simple unweighted sum of the individual parameter distances. The is named after the fact that a taxi must follow the streets and to go 3 block north and 4 blocks west it must travel 7 blocks not the 5 blocks of the euclidean distance. OK, so basically the fit is the sum of the fits of all the parameters. If form A has a distance of 2 for the first argument and 5 for the second, and form B has a distance of 0 for the first and 10 for the second, form A is better. I heard this term come up the other day with respect to matching value types =and= other attributes such as rw or ref-ness. I thought he meant that these were different directions like streets and avenues, of one parameter. I have problems with a simple sum. The distance is artificially inflated if you make lots of small derivation steps vs one large change. The concept of derivation steps is ill-defined for parameterized types and types that change virtual type names during derivation so there is no subtype relationship. In C++, which must be resolved at compile time, the overloading resolution mechanism demands that =every= parameter be at least as good of a match, and one strictly better match. So the implementation never guesses if worse-left/better-right is a better fit than better-left/worse-right. However, you are assured that everything is brought to your attention at program build time, before run time, so complaining is not as serious as a run-time error where you might prefer DWIM. --John
Re: Minimal Distance (Re: Where is Manhattan Dispatch discussion?)
HaloO, John M. Dlugosz wrote: In C++, which must be resolved at compile time, the overloading resolution mechanism demands that =every= parameter be at least as good of a match, and one strictly better match. So the implementation never guesses if worse-left/better-right is a better fit than better-left/worse-right. However, you are assured that everything is brought to your attention at program build time, before run time, so complaining is not as serious as a run-time error where you might prefer DWIM. Perl 6 is the same, just at runtime with actual types of actual objects. That's it. Regards, TSa. -- The unavoidable price of reliability is simplicity -- C.A.R. Hoare Simplicity does not precede complexity, but follows it. -- A.J. Perlis 1 + 2 + 3 + 4 + ... = -1/12 -- Srinivasa Ramanujan
Re: nested 'our' subs - senseless?
On 2008-May-6, at 6:07 am, TSa wrote: Just to ensure that I get the our behavior right, consider sub foo { our $inner = 3; } sub bar { our $inner = 4; # redeclaration error? } say $inner; Does this print 3 even when foo was never called? No, it throws an error about $inner not being declared properly -- just as in P5 you'd get 'Variable $inner is not imported. Global symbol $inner requires explicit package name'. There's no redeclaration error in bar() because it's declaring the name for the first time (in bar's scope, that is), and then (re)assigning a value to $inner, which is fine. If foo said our Int $inner and then bar said our Str $inner, that should be an error though. sub foo { our $inner = 3; } sub bar { our $inner = 4; # fine, assigns or re-assigns $inner } say $inner; # error, name $inner not recognised here our $inner; # now the name is available in this scope say $inner; # OK, $inner is undef foo; say $inner; # prints 3 bar; say $inner; # prints 4 IOW, is the assignment in foo a real one that only happens when foo is invoked or is it a pseudo-assignment that initializes the variables as if the whole statement where outside of foo? The assignment happens only when foo() is invoked. However, the variable $*Main::inner is declared at compile-time. Similarly, an our sub inner inside foo() would declare the name, but you couldn't call inner() until after running foo() --or bar()-- since you can't call an undefined sub. The consequence of a sub not doing Package is that there are no separate foo::inner and bar::inner classes as in class foo { our class inner { has $.x = 3 } } class bar { our class inner { has $.x = 4 } } say inner.new.x; # error: no inner in scope My personal idea is to unify class and sub by allowing sub to do Package. I don't understand what a sub doing Package is supposed to do. I think you get the same thing from that last example whether foo and bar are classes or whether they're subs: either way, bar will raise a redefinition error, and say inner.new.x will throw a no 'inner' in scope error. -David
Re: MMD thoughts 2008
HaloO, John M. Dlugosz wrote: OK, why would someone create those forms in the first place? I would think they grow like that historically. A five steps long subtyping chain is not particularly extraordinary. Note that multi entries live outside of classes and their single dispatch. The subtyping relationship could mean either value subset (e.g. integer passed to code that can handle reals) or polymorphic isa objects. The implementation should treat the E correctly because of virtual functions on E, even though the code was written for an A. Yes, but code that specifies to get an A sanely only uses functionality covered by that requirement. E : A of course means that the A interface works on an E. But a multi method target should be the most specific choice for *all* parameters. Only that guarantees that all relationships amongst the involved types are taken into account up to a *deterministic* level of specificity. So why write different forms with =related= classes? Different forms? I would define operators with the same name around unrelated classes, so I can use that operator with things that don't already know what to do. If I understand what you say, then you mean homogeneous multis. These can be implemented with single dispatch on the invocant and generic type enforcement for the other parameters. But MMD is about the heterogeneous case! BTW, the types that already know what to do must be implemented with the same features as all the others. There are no magic built-ins. So why are we focusing on the pathalogical cases? That's like saying we should not support division because you could divide by zero. But we throw an exception just as with a faulty dispatch. Rather, what is the common typical use? For the bad stuff, don't do that and do this instead. I think the MMD should work well and be tuned for the areas in which it ought to be used, and the above problem analyzed to see what the programmer was really trying to accomplish. You want a runtime analysis what the programmers might have meant? So Perl 6 requires AI? Regards, TSa. -- The unavoidable price of reliability is simplicity -- C.A.R. Hoare Simplicity does not precede complexity, but follows it. -- A.J. Perlis 1 + 2 + 3 + 4 + ... = -1/12 -- Srinivasa Ramanujan
Re: Minimal Distance (Re: Where is Manhattan Dispatch discussion?)
On Tuesday 06 May 2008 10:38:38 John M. Dlugosz wrote: I have problems with a simple sum. The distance is artificially inflated if you make lots of small derivation steps vs one large change. The concept of derivation steps is ill-defined for parameterized types and types that change virtual type names during derivation so there is no subtype relationship. Those are precisely my objections. I'm not a fan of derivation in general, but I've never understood how changing MMD resolution based on degree of derivation didn't break Liskov. (Damian tried to explain it to me at least once, but he's smarter than I am and I didn't get it.) -- c
Re: nested 'our' subs - senseless?
HaloO, David Green wrote: The assignment happens only when foo() is invoked. However, the variable $*Main::inner is declared at compile-time. Similarly, an our sub inner inside foo() would declare the name, but you couldn't call inner() until after running foo() --or bar()-- since you can't call an undefined sub. Do you mean there is an uninitialized variable *Main::inner that is only bound when either foo or bar are executed? How is the body handled? If there are different bodies in foo and bar, is that a re-definition of inner error at compile time? If not, does the body bound to *Main::inner depend on whether foo or bar was called first? Or does it even toggle? I don't understand what a sub doing Package is supposed to do. I think you get the same thing from that last example whether foo and bar are classes or whether they're subs: either way, bar will raise a redefinition error, and say inner.new.x will throw a no 'inner' in scope error. No, a class definitely does Package. So, my classes foo and bar get two separate classes foo::inner and bar::inner and there is *no* *Main::inner class at all. In particular there should be no re-definition error in bar. This is exactly the behavior I want for subs as well. Regards, TSa. -- The unavoidable price of reliability is simplicity -- C.A.R. Hoare Simplicity does not precede complexity, but follows it. -- A.J. Perlis 1 + 2 + 3 + 4 + ... = -1/12 -- Srinivasa Ramanujan
Re: Minimal Distance (Re: Where is Manhattan Dispatch discussion?)
On Tue, May 06, 2008 at 08:20:40PM +0200, TSa wrote: HaloO, John M. Dlugosz wrote: In C++, which must be resolved at compile time, the overloading resolution mechanism demands that =every= parameter be at least as good of a match, and one strictly better match. So the implementation never guesses if worse-left/better-right is a better fit than better-left/worse-right. However, you are assured that everything is brought to your attention at program build time, before run time, so complaining is not as serious as a run-time error where you might prefer DWIM. Perl 6 is the same, just at runtime with actual types of actual objects. That's it. Indeed, Perl 6 threw out Manhattan distance a couple years ago. Do we have to spec everything that Perl 6 ever was but isn't now? :) Larry
Re: MMD thoughts 2008
Sorry to reply to the wrong comment, but I lost the original thread in my mail archives and didn't notice this until now. On Tue, May 6, 2008 at 1:54 PM, John M. Dlugosz [EMAIL PROTECTED] wrote: TSa Thomas.Sandlass-at-barco.com |Perl 6| wrote: The fundamental flaw of metric mmd is that it trades degrees of specificity. Consider the subtype chain E : D : C : B : A where the rule is that having an E it is better handled by a method dealing with a D than one dealing with an A. The same is the case for having a D being better handled by a C than an A method. Now consider a multi with the two signatures :(A,C,C) and :(D,A,A) and a call with (E,D,D) that goes to :(D,A,A) since 7 8. But note that it handles the two Ds as As instead of Cs as in single dispatch. Is this right? (E,D,D) to (A,C,C) is (4,1,1), with a L1 metric of 6. (E,D,D) to (D,A,A) is (1,3,3) with an L1 metric of 7. Are you sure (E,D,D) would bind to (D,A,A)?
Re: Minimal Distance (Re: Where is Manhattan Dispatch discussion?)
TSa Thomas.Sandlass-at-barco.com |Perl 6| wrote: HaloO, John M. Dlugosz wrote: In C++, which must be resolved at compile time, the overloading resolution mechanism demands that =every= parameter be at least as good of a match, and one strictly better match. So the implementation never guesses if worse-left/better-right is a better fit than better-left/worse-right. However, you are assured that everything is brought to your attention at program build time, before run time, so complaining is not as serious as a run-time error where you might prefer DWIM. Perl 6 is the same, just at runtime with actual types of actual objects. That's it. Regards, TSa. Then why is everyone against no worse for all parameters, rather than summing?
Re: Minimal Distance (Re: Where is Manhattan Dispatch discussion?)
Larry Wall larry-at-wall.org |Perl 6| wrote: On Tue, May 06, 2008 at 08:20:40PM +0200, TSa wrote: HaloO, John M. Dlugosz wrote: In C++, which must be resolved at compile time, the overloading resolution mechanism demands that =every= parameter be at least as good of a match, and one strictly better match. So the implementation never guesses if worse-left/better-right is a better fit than better-left/worse-right. However, you are assured that everything is brought to your attention at program build time, before run time, so complaining is not as serious as a run-time error where you might prefer DWIM. Perl 6 is the same, just at runtime with actual types of actual objects. That's it. Indeed, Perl 6 threw out Manhattan distance a couple years ago. Do we have to spec everything that Perl 6 ever was but isn't now? :) Larry No, just point me to what it says now. Or the scraps so I can collect them together and say it during my productive period. When I mentioned this before, there was big flack over mentioning the way C++ did it. I think that must have been miscommunicated, since I wasn't even talking about summing all the arguments when he brought up Manhattan dispatch.
Re: my TypeName $x;
Larry Wall wrote: Jonathan Worthington wrote: role Bar { } my Bar $x; # $x is ??? say $x; # ??? say $x.WHAT; # ??? # This means we can only assign to $x something that does Bar? Correct, and for the same reason. The container checks the role--it has little to do with what's in $x currently, which *cannot* have the type of Bar, since you can't instantiate that. subset EvenInt of Int where { $_ % 2 == 0 }; my EvenInt $x; # $x is ??? say $x; # ??? say $x.WHAT; # Failure? # This means we can only assign to $x something that matches the constraint Yes, again, checked by the container, not by $x. $x cannot have the type of a subset either! The actual type of $x is Int. Objects may only be blessed as valid storage types of some kind or other. Subsets are merely extra constraints on a storage type (here Int). class Dog { } class Cat { } my Dog|Cat $x; # $x is ??? say $x; # ??? say $x.WHAT; # Failure? # This means we can only assign to $x something that isa Dog or isa Cat Well, maybe $x is just Object, or whatever is the closest type that encompasses both Dog and Cat. But note that Object is just the most generic kind of undef, so this is more or less equivalent to doing no initialization in p5-think. I don't think I'm interested in making the run-time system calculate a Dog|Cat storage type, so it comes out to just a constraint. Really, the main reason we initialize with an undef of the correct sort is so that you can say my Dog $x .= new(); But what would (Dog|Cat).new() do? Constructors are not required to know about subset types or roles. Constructors just create plain ordinary classes, I expect. Composition and constraint checking happen elsewhere. Two questions: 1. Apparently, my presumption that $x.WHAT was for retrieving the value type was wrong; from the above, it's sounding like it is supposed to retrieve the implementation type. Is this correct? If so, for what purpose does $x.WHAT exist that you can't do just as well with $x itself? If it's for the stringification of the container's name, couldn't that be accomplished just as easily by means of a $x.HOW method, such as $x.^name? 2. How _do_ you retrieve the value type of $x? That is, how can the program look at $x and ask for the constraints that are placed on it? I don't see $x.HOW being useful for this, since HOW is essentially there to let you look at the inner workings of the container; and none of the other introspection metamethods in S12 come close to addressing this question. -- Jonathan Dataweaver Lang
Re: my TypeName $x;
On Tue, May 06, 2008 at 07:01:29PM -0700, Jon Lang wrote: : 1. Apparently, my presumption that $x.WHAT was for retrieving the : value type was wrong; from the above, it's sounding like it is : supposed to retrieve the implementation type. I don't know what you mean by those terms. .WHAT gives you an value of undef that happens to be typed the same as the object in $x, presuming your metaobject believes in types. .HOW gives you the metaobject that manages everything else for this object. It might or might not believe in classes or types. : Is this correct? If : so, for what purpose does $x.WHAT exist that you can't do just as well : with $x itself? You can do type reasoning with the WHAT type just as you can with a real value of the same type. Int is a prototypical integer from the standpoint of the type system, without actually having to *be* any particular integer. In contrast, the .HOW object for Int is very much *not* an Int. Perl doesn't know or care what the type of the .HOW object is, as long as it behaves like a metaclass in a duck-typed sort of way. It's probably a mistake to try to use the type of the .HOW object in any kind of type-inferential way. : If it's for the stringification of the container's : name, couldn't that be accomplished just as easily by means of a : $x.HOW method, such as $x.^name? No, that's not what it's for at all. It's only convenient that it generally stringifies to something that looks like a package name, assuming it's not an anonymous type. But the primary purpose is to provide a closed system of types that is orthogonal to whether the object is defined or not. In Haskell terms, they're all Maybe types, only with a little more ability to carry error information about *why* they're undefined, if they're undefined. : 2. How _do_ you retrieve the value type of $x? Do you mean the variable, or its contents? The contents returns its object type via $x.WHAT, which for an Int is always Int, regardless of any extra constraints imposed by the container. : That is, how can the : program look at $x and ask for the constraints that are placed on it? Placed by the variable, or by the type of the contents? The constraints on the value are solely the concern of whatever kind of object it is. If you mean the constraints of the container, then VAR($x).WHAT will be, say, Scalar of Int where 0..*, and VAR($x).of probably can tell you that it wants something that conforms to Int. I'm not sure if the of type should include any constraints, or just return the base type. Probably a .where method would return extra constraints, if any. : I don't see $x.HOW being useful for this, since HOW is essentially : there to let you look at the inner workings of the container; and none : of the other introspection metamethods in S12 come close to addressing : this question. $x.HOW is not the inner workings of the container, but of the value. You'd have to say VAR($x).HOW to get the inner workings of the container. Scalar containers always delegate to their contents. In contrast, @x.HOW would be equivalent to VAR(@x).HOW, because composite objects used as scalars assume you're talking about the container. Larry
Re: my TypeName $x;
On Tue, May 6, 2008 at 8:09 PM, Larry Wall [EMAIL PROTECTED] wrote: On Tue, May 06, 2008 at 07:01:29PM -0700, Jon Lang wrote: : 1. Apparently, my presumption that $x.WHAT was for retrieving the : value type was wrong; from the above, it's sounding like it is : supposed to retrieve the implementation type. I don't know what you mean by those terms. Oh? I took them straight out of S2: Explicit types are optional. Perl variables have two associated types: their value type and their implementation type. (More generally, any container has an implementation type, including subroutines and modules.) The value type is stored as its of property, while the implementation type of the container is just the object type of the container itself. The word returns is allowed as an alias for of. The value type specifies what kinds of values may be stored in the variable. By my reading of this: given my Dog|Cat $x, the value type would be Dog|Cat, since you've specified that $x can store values that are Dogs or Cats. .WHAT gives you an value of undef that happens to be typed the same as the object in $x, presuming your metaobject believes in types. .HOW gives you the metaobject that manages everything else for this object. It might or might not believe in classes or types. OK; that's what I thought you were saying. : Is this correct? If : so, for what purpose does $x.WHAT exist that you can't do just as well : with $x itself? You can do type reasoning with the WHAT type just as you can with a real value of the same type. Int is a prototypical integer from the standpoint of the type system, without actually having to *be* any particular integer. Yes; but what can you do with $x.WHAT that you _can't_ do just as easily with $x itself? After all, you've already got $x; and it has already been initialized with an undefined Int upon creation, making it a prototypical integer until such time as you assign a value to it. Furthermore, whether or not it has a value is utterly immaterial for type-checking purposes. So why would I ever say $x.WHAT instead of just $x? In contrast, the .HOW object for Int is very much *not* an Int. Perl doesn't know or care what the type of the .HOW object is, as long as it behaves like a metaclass in a duck-typed sort of way. It's probably a mistake to try to use the type of the .HOW object in any kind of type-inferential way. That's more or less what I understood. : If it's for the stringification of the container's : name, couldn't that be accomplished just as easily by means of a : $x.HOW method, such as $x.^name? No, that's not what it's for at all. It's only convenient that it generally stringifies to something that looks like a package name, assuming it's not an anonymous type. But the primary purpose is to provide a closed system of types that is orthogonal to whether the object is defined or not. In Haskell terms, they're all Maybe types, only with a little more ability to carry error information about *why* they're undefined, if they're undefined. Right. I didn't think that the stringification was a big deal; but it was the only thing that I could find that differentiated $x from $x.WHAT. : 2. How _do_ you retrieve the value type of $x? Do you mean the variable, or its contents? The contents returns its object type via $x.WHAT, which for an Int is always Int, regardless of any extra constraints imposed by the container. I've been assuming that the value type is associated to the variable; otherwise, a simple assignment of a completely different container to the variable would completely bypass any and all constraints. Am I wrong about this? : That is, how can the : program look at $x and ask for the constraints that are placed on it? Placed by the variable, or by the type of the contents? The constraints on the value are solely the concern of whatever kind of object it is. If you mean the constraints of the container, then VAR($x).WHAT will be, say, Scalar of Int where 0..*, and VAR($x).of probably can tell you that it wants something that conforms to Int. I'm not sure if the of type should include any constraints, or just return the base type. Probably a .where method would return extra constraints, if any. OK; I'll have to look up what I can about VAR. : I don't see $x.HOW being useful for this, since HOW is essentially : there to let you look at the inner workings of the container; and none : of the other introspection metamethods in S12 come close to addressing : this question. $x.HOW is not the inner workings of the container, but of the value. You'd have to say VAR($x).HOW to get the inner workings of the container. Scalar containers always delegate to their contents. In contrast, @x.HOW would be equivalent to VAR(@x).HOW, because composite objects used as scalars assume you're talking about the container. ...and you appear to be using