Re: syntax-variants, RPN (was: Re: $_ defaulting for mutating ops)
On Wed, 2 Nov 2005, Ruud H.G. van Tol wrote: http://www.nntp.perl.org/group/perl.perl6.language/17556 I understand that Perl6 allows blocks with changed/enhanced syntax, so it is or will become possible (to add it) as if it was in the core language. Do I understand that right? Something as simple as a 'use RPN' in a block? (assuming that someone created such an RPN-pre-processor or -compiler) Indeed this is what that we all know. Of course the possibility of doing so will depend on the possiblity of building up suitable RPN syntax consistent with the rest of the syntax. Michele -- E' molto piu' facile affrontare il lutto, il disonore e la perdita della propria anima - che questo tipo di fame prolungata. - Joseph Conrad, Cuore di Tenebra.
Re: $_ defaulting for mutating ops
On Thu, 3 Nov 2005, Sam Vilain wrote: That being said, there are probably other more pressing reasons that ops should not accept $_ as default; I would guess, for a start, it makes determining semantics very difficult. Does ++; mean postfix:++ or prefix:++ ? If we had it, I think we would be more interested in it for incrementing $_ than for its return value, so it wouldn't make such a huge difference. However I find myself using $var++ much more often than ++$var, and I'm biased to think this is the general situation: if it is actually so, then the choice should fall on the former. If my impression is just a personal artifact... oh, don't mind! Michele -- Billy: I'm scared Poncho. Poncho: Bullshit! You ain't afraid of no man! Billy: There's something out there waiting for us, and it ain't no man. We're all gonna die. - Predator (1987)
Re: syntax-variants, RPN (was: Re: $_ defaulting for mutating ops)
On 11/3/05, Michele Dondi [EMAIL PROTECTED] wrote: On Wed, 2 Nov 2005, Ruud H.G. van Tol wrote: http://www.nntp.perl.org/group/perl.perl6.language/17556 I understand that Perl6 allows blocks with changed/enhanced syntax, so it is or will become possible (to add it) as if it was in the core language. Do I understand that right? Something as simple as a 'use RPN' in a block? (assuming that someone created such an RPN-pre-processor or -compiler) Indeed this is what that we all know. Of course the possibility of doing so will depend on the possiblity of building up suitable RPN syntax consistent with the rest of the syntax. If Perl6 is parseable by Perl6, then wouldn't you be able to completely throw out the default Perl6 syntax and create your own, completely unrelated syntax? I don't know ... maybe you have PGE::Ruby that would throw out the P6 grammar and give you Ruby's grammar within the block. Then, it's just a matter of describing what PGE::RPN does - what it adds, what it removes, and what it modifies. In my opinion, if you use a grammar extension, ALL bets are off within that scope until you've read the documentation. Literally anything and everything can happen, if the author deemed it so. It's a source filter-like construct that doesn't suck because source filter-like constructs are part of the spec. Rob
Re: Role Method Conflicts and Disambiguation
On Nov 2, 2005, at 9:02 PM, Jonathan Lang wrote: Let's say you have this: role A {method foo() { code1; } } role B {method foo() { code2; } } role C does A does B { method foo() { A::foo(); } method bar() { B::foo(); } } Should the following be valid? role D does C { method foo() { B::foo(); } } IMHO, it shouldn't, because D doesn't do B. Not valid in what way? Should this be a fatal error? Are you implying that B is not local to D, so it cannot use it? that somehow disambiguation must be done using one of your local subroles only? I think this is too restrictive, D should be able to freely disambiguate or override using anything it want's to. It need not be related at all to it's subroles. Stevan
Re: Role Method Conflicts and Disambiguation
On Nov 2, 2005, at 9:02 PM, Jonathan Lang wrote: Let's say you have this: role A {method foo() { code1; } } role B {method foo() { code2; } } role C does A does B { method foo() { A::foo(); } method bar() { B::foo(); } } Should the following be valid? role D does C { method foo() { B::foo(); } } IMHO, it shouldn't, because D doesn't do B. Additionally, D most certainly does B. That it does B through a proxy is irrelevant. Think about it this way - if you had Surfer and Dog and SurferDog does Surfer does Dog, wouldn't you want to know that class ScoobyDoo does SurferDog does Dog? If SurferDog doesn't do Dog, how would ScoobyDoo do Dog? I think this is too restrictive, D should be able to freely disambiguate or override using anything it want's to. It need not be related at all to it's subroles. To further expand on this, D's disambiguation of method foo() could be: role D does C { method foo() { Completely::Unrelated::foo() } } Rob
Re: Why submethods
HaloO, Luke Palmer wrote: On 10/29/05, Damian Conway [EMAIL PROTECTED] wrote: So we need a mechanism that is externally (i.e. from a class interface point-of-view) a subroutine, but internally has the features of a method (i.e. has an invocant). Since it's externally sub-like but internally method-like, we call this useful construct a submethod. Wouldn't the semantics fall out naturally from 1) beeing a scoped 'our sub' 2) the topic type ^_ of the topic item $_ beeing contra-variantly defined to the concrete class type? Number 1) assumes that a sub definition in a class without my or our gets a sig of :(Any $_ = CALLER$_, [EMAIL PROTECTED]). The property 2) ensures the non-inheritance indirectly because an overriding sub in a derived class would permit the Foo::bar application. That is Luke's example could read class Foo { has $.data; # creates rw accessor our sub bar # sig is :( void: Foo $_, [EMAIL PROTECTED] ) { $.data = 23; # Not allowed outside of class scope? # .data = 23; # Or force through accessor? } } my $foo = Foo.new; $foo.bar; # binds $_ := $foo and all member refs through $foo, # then calls Foo::bar with empty @_ say $foo.data; # prints 23 For most of that, doesn't a private method suffice? When it doesn't, I feel uneasy about: class Foo { submethod bar() { ... } } my $foo = Foo.new; $foo.bar; If that's externally sub-like, why does it look so much like a method? Isn't looking like a method more a feature of the dot syntax than anything else? Does bar($foo) cause the same perception? If my signature assumptions above are correct then an argumentless bar call without invocant is a too few arguments error. If I understand the term 'package dispatch' of Sam Vilain correctly the package that contains class Foo would maintain a dispatch into class scoped subs depending on the immediate class---is that the eigenclass?---of the invocant. That is we could define class Bar { has $.data; # creates rw accessor our sub bar # sig is :( void: Bar $_, [EMAIL PROTECTED] ) { $.data = 42; } } in addition to the Foo from above and then sub package_dispatched ($x) { $x.bar } my $bar = Bar.new; package_dispatched( $foo ); say $foo.data; # 23 package_dispatched( $bar ); say $bar.data; # 42 But I can understand that Damian thinks that spelling 'our sub' as 'submethod' is good documentation and not a subtlety. OTOH, a 'my sub' is not considered too subtle. Actually a 'has sub foo ...' form might be an alternate spelling for 'has .foo = sub ...' and we can drop the strange word 'submethod' and nicely unify all code types. That is sub = package dispatch on void method = unary dispatch on single invocant item type multi = symmetric multi dispatch on invocant tuple type or left biased successive single dispatch on invocant list or a mix of both --
Re: Role Method Conflicts and Disambiguation
HaloO, Rob Kinyon wrote: On Nov 2, 2005, at 9:02 PM, Jonathan Lang wrote: Let's say you have this: role A {method foo() { code1; } } role B {method foo() { code2; } } I think, A and B might just be aliases to the *identical* structural type because the only constraint that both roles impose on their implicit type parameter is the presence of a method foo() on the type of just this parameter. The implementation parts are of course different. In other words the roles A and B are interchangable as far as the structural type checker is concerned! That is there is a theory T{^R} { multi foo (^R) {...} } A ::= T{A}; B ::= T{B}; A::foo.block ::= code1; # or however .block is spelled A::foo.block ::= code2; # or { code2; } ? role C does A does B { method foo() { A::foo(); } method bar() { B::foo(); } } Should the following be valid? role D does C { method foo() { B::foo(); } } IMHO, it shouldn't, because D doesn't do B. Additionally, D most certainly does B. That it does B through a proxy is irrelevant. Think about it this way - if you had Surfer and Dog and SurferDog does Surfer does Dog, wouldn't you want to know that class ScoobyDoo does SurferDog does Dog? Semantic wise or type wise? If SurferDog doesn't do Dog, how would ScoobyDoo do Dog? Assuming that the type system supervises the constraint addition in role composition, a meta information lookup on SurferDog should yield all you need to know about what kind of thing it is! Just think of electrons and the double slit, if you don't require them to know through which slit they passed, they don't bother to remember it ;) I think this is too restrictive, D should be able to freely disambiguate or override using anything it want's to. It need not be related at all to it's subroles. Well, it can't step out of the frame that the constraints of C impose. Actually it can because not all contstraints are computer enforceable but it shouldn't for social reasons. To further expand on this, D's disambiguation of method foo() could be: role D does C { method foo() { Completely::Unrelated::foo() } } Yes, of course. But these are the boring cases. More interesting is something like role X { method foo (: XA $a, XB $b -- XC ) {...} } role Y does X { method foo (: YA $a, YB $b -- YC ) {...} } where the definition of Y should succeed only iff Y::foo : X::foo which requires YC : XC and (XA,XB) : (YA,YB) where : denotes the subtype relation. --
co/contra variance of roles/factories in theory.pod
HaloO, I don't understand why theory.pod states that roles are covariant, unary theories and factories are contravariant. I would expect the opposite from the requirement that all functions in roles only take the topic type while function in factories only return the topic type. So if A : B, I would expect Role{B} : Role{A} and Factory{A} : Factory{B} on the following rational. Thinking of A beeing a proper subset of B we get the reverse relation for their complements because parts of the outside of A are inside of B. Functions in roles have type (R -- None(R)) and functions in factories have type (None(F) -- F) with R and F the implicit topic types of the role and factory respectively. Normal arrow subtyping rules then result in roles beeing *contravariant*, unary theories and factories beeing *covariant*, unary theories. OTOH, theory.pod talks about the topic type appearing in the invocant position of methods of roles, which subtypes covariantly. Note also that the return type is covariant. So I neither understand the part about roles having methods that return the type the role defines. Thanks in advance for clarification. --
Re: co/contra variance of roles/factories in theory.pod
On 11/3/05, TSa [EMAIL PROTECTED] wrote: So if A : B, I would expect Role{B} : Role{A} and Factory{A} : Factory{B} on the following rational. Well, it's possible that I'm abusing the terms, since I first heard the terms from you and inferred what they meant. However, there is a problem in your statement: A : B implies Role{B} : Role{A} Since Role{B} is not a type: it is a predicate. The way I put it (and I think it is put this way in the document): If Role{B} and A : B, then Role{A} (for any role Role) Similarly: If Factory{A} and A : B, then Factory{B} (for any factory Factory) Thinking of A beeing a proper subset of B we get the reverse relation for their complements because parts of the outside of A are inside of B. Functions in roles have type (R -- None(R)) and functions in factories have type (None(F) -- F) with R and F the implicit topic types of the role and factory respectively. Normal arrow subtyping rules then result in roles beeing *contravariant*, unary theories and factories beeing *covariant*, unary theories. Hmm, okay. Then I probably reversed them (I need to read more about arrow subtyping). OTOH, theory.pod talks about the topic type appearing in the invocant position of methods of roles, which subtypes covariantly. Note also that the return type is covariant. So I neither understand the part about roles having methods that return the type the role defines. Let's see if I understand what you're asking. You're asking about: role Foo { method bar(-- Foo) {...} } Expanding this to a theory: theory Foo{^T} { method bar(^T: -- ^U = Foo{^U}) {...} } This is different from: theory Foo2{^T} { method bar2(^T: -- ^T) {...} } We can see the difference when we have, say: class Bar does Foo does Foo2 {...} class Baz does Foo does Foo2 {...} my $bar = Bar.new; $bar.bar;# may return a Bar or a Baz $bar.bar2; # may only return a Bar If Foo2 were a role (that is, if it obeys the role relation above), then the only thing bar2() could do would be to take some side-effect action and then return the same object it was passed. Here's a proof: Given ^T $x where Foo{^T}. Because of the role relation, Foo{{$x}} (The singleton set {$x} does Foo). Therefore the signature of bar in this instance is :({$x} -- {$x}). Since $x was unrestricted, bar() must be the identity on things that do Foo. But of course, that's probably not what the author of the Foo role intended. So we allow any Foo to be returned. Did I answer your question? Luke
Re: co/contra variance of roles/factories in theory.pod
On 11/3/05, Luke Palmer [EMAIL PROTECTED] wrote: If Foo2 were a role (that is, if it obeys the role relation above), then the only thing bar2() could do would be to take some side-effect action and then return the same object it was passed. Here's a proof: Given ^T $x where Foo{^T}. Because of the role relation, Foo{{$x}} (The singleton set {$x} does Foo). Therefore the signature of bar in this instance is :({$x} -- {$x}). Since $x was unrestricted, bar() must be the identity on things that do Foo. Excuse me, s:g/Foo/Foo2/; s:g/bar/bar2/. Luke