Re: set operations for roles
HaloO, Jonathan Lang wrote: role R3 does A B { ... } R3.does(A) # false: R3 can't neccessarily do everything that A can. A.does(R3) # false: A can't neccessarily do everything that R3 can. That last one should be true. Role R3 contains the things that A and B have in common. Hence each of them has everything that R3 has. And because you have the ability to add methods to R3 that aren't in A or B, you can't make use of the fact that A B is a subset of A for type-checking purposes. The really funny thing is what can be written into the body of role R3. Should it be forbidden to introduce new methods? Or should new methods automatically enter into A and B? The latter would be more useful but then roles become somewhat open like classes because code that did not typecheck before the superrole creation suddenly typechecks after it. Or if the role R3 adds a yada method that propagates down the composition chains, classes might retroactively fail to compile! Regards, TSa. --
Re: Interrogative statements
Jonathan Lang skribis 2006-10-19 18:27 (-0700): Let's say that I want $expression?; to mean the same thing as the statement $_ = $expression; That is, any statement that ends with a '?;' instead of a ';' evaluates in scalar context instead of void context and stores the result as the topic '$_'. (I was going to suggest '?' intead of '?;', but a quick review of the specs pointed out that this would be ambiguous wrt the ? prefix operator.) Prefix and postfix live in different places, so you can just use a normal postfix operator: sub postfix:? ($lhs) { $CALLER::_ = $lhs; } 42?; say($_); # prints 42! # This code is not futuristic. It already works with Pugs. But you wanted a statement thingy. That would require that you modify the Perl 6 grammar. Yes, you can do that with Perl 6. -- korajn salutojn, juerd waalboer: perl hacker [EMAIL PROTECTED] http://juerd.nl/sig convolution: ict solutions and consultancy [EMAIL PROTECTED] Ik vertrouw stemcomputers niet. Zie http://www.wijvertrouwenstemcomputersniet.nl/.
Re: classnames and HLL namespaces -- help!
Matt Diephouse wrote: Patrick R. Michaud [EMAIL PROTECTED] wrote: According to pdd21, each HLL gets its own hll_namespace. PGE is really a form of HLL compiler, so it should have its own hll_namespace, instead of using parrot's hll namespace: .HLL 'pge', '' I don't know that that's necessarily the case, but it's definitely an option. You can just as easily argue that it's a library. It comes down to a question of whether Perl 6 grammars are a high-level language. Debatable, so I'd go with whichever is easiest to work with both within PGE, and in code that uses PGE. Within PGE, it comes down to whether you have to prefix every access to a PGE module with the PGE namespace, or whether you can use the .HLL directive to set a default. Outside PGE, it's a question of whether you can access the module directly or have to take extra steps to reach it as a module outside your current HLL. Or, if we say you can only directly access namespaces within your current HLL, then it's a question of whether you can access PGE modules in the 'parrot' HLL (so in the general case you only have to work with two HLLs: your own and 'parrot'), or whether you have to work with an arbitrary number of different HLLs to access core modules like PGE and TGE. With this in mind, I lean toward putting PGE in the 'parrot' HLL. But, agreed, the namespace pollution problem needs to be solved either way. Now then, the 'PGE::' prefixes on the classnames were just implementation artifacts of working in a globally flat namespace -- as a high-level language PGE really ought to be referring to its classes as 'Match', 'Exp', 'Literal', etc. So, if we're in the PGE HLL, we ought to be able to drop the 'PGE::' prefix from our classnames and namespaces. So, here's the revised version of the code to create the classes: .HLL 'pge', '' .sub __onload :load $P0 = newclass 'Exp' $P0 = subclass 'Exp', 'Literal' $P0 = subclass 'Exp', 'Group' $P0 = subclass 'Exp', 'CGroup' $P0 = subclass 'Exp', 'Subrule' $P0 = subclass 'Exp', 'Closure' # ... .end This code fails when run from parrot, because Parrot seemingly already has a class named 'Closure': $ ./parrot ns.pir Class Closure already registered! current instr.: '__onload' pc 19 ( ns.pir:9) $ So, this brings me to my question: What is the official best practice pattern for HLLs to create their own classes such that we avoid naming conflicts with existing classes in Parrot and other HLLs? This is unspecced. ATM, all classes go into the 'parrot' HLL. This is a relic of the past and I think it needs to change. I'm pretty sure that HLL classes will have to go into the HLL's root namespace (this needs to happen anyway to prevent namespace pollution). That leaves us with the question of how to differentiate core PMCs from HLL PMCs. I'm not sure how to handle that, but that's what a spec is for. Aye, if a class is defined in an HLL namespace, it shouldn't also exist in the 'parrot' namespace. I'd call this a bug, 'subclass' should respect the current namespace (which should be set by the .HLL directive). We discussed some of this briefly at the OSCON hackathon, when we talked about changing the class internals so that a Class isa Namespace. That discussion hasn't led to any changes yet as Chip has been kidnapped by his Real Life (tm). That's still a possibility, but it may also end up as Class is linked to a Namespace. (Anonymous classes have no namespace, but may be associated with a namespace at runtime.) I think the object model needs a thorough going over in general Yup. It's on the list right after I/O, threads, and events. -- for the reasons above and because it's an unproven system. I'm not convinced that it will handle all of Perl 6's needs as is. No serious OO language has been implemented yet on Parrot; everything up to this point has been either procedural or functional. Ruby is a serious OO language, but it's not finished yet. For that matter, Perl 6 is partially implemented. But, I entirely agree on the core point that pushing these languages forward will help push Parrot forward. Allison
Re: classnames and HLL namespaces -- help!
Matt Diephouse wrote: Patrick R. Michaud [EMAIL PROTECTED] wrote: On Thu, Oct 19, 2006 at 10:01:29PM -0400, Matt Diephouse wrote: This is unspecced. ATM, all classes go into the 'parrot' HLL. This is a relic of the past and I think it needs to change. I'm pretty sure that HLL classes will have to go into the HLL's root namespace (this needs to happen anyway to prevent namespace pollution). That leaves us with the question of how to differentiate core PMCs from HLL PMCs. I'm not sure how to handle that, but that's what a spec is for. Why is the differentiation necessary -- wouldn't core PMCs simply be part of the 'parrot' HLL? That's the place to put them. But how do you make the core PMCs visible to the compiler and not to the user? I expect the Perl 6 compiler will want to use a ResizablePMCArray in places without making it a builtin Perl 6 class. But how can you if there's only one new opcode? If we have a strict separation between the HLL namespace and the Parrot namespace (and I think we should), then the only way instantiate a core Parrot class/PMC from within an HLL is to first retrieve the 'parrot' namespace, and preferably through the typed interface. Speculatively: $P0 = get_root_namespace ['parrot'] $P1 = $P0.find_class('ResizablePMCArray') $P2 = new $P1 $P2.INIT() How Perl 6 (or some other HLL) chooses to distinguish loading a module written in the same HLL from loading a module written in a different HLL is an open question. It will need some syntax. One earlier proposal suggested separating the HLL from the rest of the name with a single colon ('python:NLTK-Lite::Parse::LamdaCalculus'). Allison
Re: set operations for roles
TSa wrote: Jonathan Lang wrote: role R3 does A B { ... } R3.does(A) # false: R3 can't neccessarily do everything that A can. A.does(R3) # false: A can't neccessarily do everything that R3 can. That last one should be true. Role R3 contains the things that A and B have in common. Hence each of them has everything that R3 has. The '...' above isn't the yadda-yadda operator; it's a standin for whatever gets declared in R3. Which leads directly to... And because you have the ability to add methods to R3 that aren't in A or B, you can't make use of the fact that A B is a subset of A for type-checking purposes. The really funny thing is what can be written into the body of role R3. Should it be forbidden to introduce new methods? Or should new methods automatically enter into A and B? The latter would be more useful but then roles become somewhat open like classes because code that did not typecheck before the superrole creation suddenly typechecks after it. Or if the role R3 adds a yada method that propagates down the composition chains, classes might retroactively fail to compile! In short, R3 isn't neccessarily a subset of A; it's a superset of A B. In a partial ordering graph, there's no reliable ordering between R3 and A. The standard syntax for creating roles can't reliably produce a subset of an existing role, because it always allows you to add to it. That's why I suggested the idea of binding a role name to a set operation: with 'role Foo ::= A B', Foo is a subset of A, because Foo is 'A B', and 'A B' is a subset of A. In addition, this syntax doesn't rely on the 'does' keyword, so there's no implication that the LHS must be a semantic superset of the RHS. Also, there's no danger of overriding a yadda-yadda in A: the only way to bring your own definitions into Foo would be to use an anonymous role as one of the roles on the RHS: either that role gets brought in via '' (in which case only those methods that are common to A and the anonymous role will end up in Foo, and thus will be overridden by A), or it gets brought in via '|' (in which case Foo is no longer a subset of A, and 'A.does(Foo)' will be false). In fact, role Foo does A does B { ... } can be thought of as being semantically equivalent to role Foo ::= (A | B) | role { ... } The only problem that might crop up is the use of 'A | B' in signatures to mean 'can match any of A, B' - that is: in signatures, 'A | B' refers to the junctive operator; while in the above proposal, 'A | B' refers to the set union operator. Different semantics. -- Jonathan Dataweaver Lang
Embedded perl5 modules
Upgraded to pugs 6.13 after seeing comprehensive support for interoperability with Perl 5 modules. I want to test gui modules and I am trying the Gtk2 and Wx modules. The following program works under perl5: use strict; use Wx; my $app = Wx::SimpleApp-new; my $frame=Wx::Frame-new(undef, -1, 'Hello world!'); $frame-Show; $app-MainLoop; The program places a window on the desktop with Hello world! as the title. I naively modified to perl6 (wxtest.p6) as follows: use perl5:Wx; my $app = Wx::SimpleApp.new; my $frame=Wx::Frame.new(undef, -1, 'Hello world!'); $frame.Show; $app.MainLoop; The following is the result: $pugs wxtest.p6 *** No compatible subroutine found: Wx::SimpleApp at wxtest.p6 line 2, column 1-28 Is the perl6 wrong? I have also tested use perl5:Wx SimpleApp; Richard
Re: Embedded perl5 modules
Richard Hainsworth [EMAIL PROTECTED] writes: use perl5:Wx; my $app = Wx::SimpleApp.new; my $frame=Wx::Frame.new(undef, -1, 'Hello world!'); $frame.Show; $app.MainLoop; The following is the result: $pugs wxtest.p6 *** No compatible subroutine found: Wx::SimpleApp at wxtest.p6 line 2, column 1-28 Is the perl6 wrong? I have also tested use perl5:Wx SimpleApp; Maybe an additional use perl5:Wx::SimpleApp; ? I'm just guessing... Steffen -- Steffen Schwigon [EMAIL PROTECTED] Dresden Perl Mongers http://dresden-pm.org/
Re: set operations for roles
HaloO, Jonathan Lang wrote: In short, R3 isn't neccessarily a subset of A; it's a superset of A B. In a partial ordering graph, there's no reliable ordering between R3 and A. The standard syntax for creating roles can't reliably produce a subset of an existing role, because it always allows you to add to it. Yes, but I was conjecturing that the additions to AB are pushed down to A and B such that their intension sets remain strict supersets of AB. The only problem that might crop up is the use of 'A | B' in signatures to mean 'can match any of A, B' - that is: in signatures, 'A | B' refers to the junctive operator; while in the above proposal, 'A | B' refers to the set union operator. Different semantics. In fact if we decide to specify a role combination syntax then it should be the same everywhere. That means in a signature A|B would require a more specific type and pure A or B wouldn't be admissible. To get the old meaning of | you have to write AB or perhaps the juxtaposition which currently means what A|B should mean. Alternatively the meaning of the role combination AB could be defined to mean the union and A|B the intersection. Regards, TSa. --
Threads, magic?
How does one do this: http://www.davidnaylor.co.uk/archives/2006/10/19/threaded-data-collection-with-python-including-examples/ in perl 6? Assumin get_feed_list, get_feed_contents, parse_feed, and store_feed_items are handled by modules like LWP and XML::Parser. Will there be something native and magic like: @feeds = threaditize ( Paralelize = fetch_feeds, Parameters = @urls, Thread_Limit = 20, Timeout = 5 sec); with @urls being a list of urls, or a list of lists (each sublist would contain the parameters for fetch_feeds). -- Relipuj, just curious.
Re: set operations for roles
HaloO, I wrote: In fact if we decide to specify a role combination syntax then it should be the same everywhere. That means in a signature A|B would require a more specific type and pure A or B wouldn't be admissible. To get the old meaning of | you have to write AB or perhaps the juxtaposition which currently means what A|B should mean. Alternatively the meaning of the role combination AB could be defined to mean the union and A|B the intersection. Here is yet another idea to go with the two lattice operations: /\ meet also: infimum, intersection, glb (greatest lower bound) \/ join also: supremum, union,lub (least upper bound) These have nice graphical mnemonics meet={x} /\ / \ /\ A={a,x} B={b,x} \/ \ / \/ join={a,b,x} and also read nice as english words: role J joins A, B, C; # same as role J does A \/ B \/ C role M meets A, B, C; # same as role M does A /\ B /\ C Comments? --
Re: requirements gathering on mini transformation language
chromatic writes: That's part of it With his permission, I've put the relevant section of Stefan Kral's master's thesis online at: http://stud4.tuwien.ac.at/~e0225855/kral_optimizer.pdf The chapter describes the implementation of a rule-based peep-hole optimizer using Prolog DCGs. The rules start at page 55. They are all quite concise, and I hope that the syntax is a useful starting point for the language to be used in Parrot. If you have any questions about it or the implementation of the rewrite system, please let me know. Best wishes! Markus Triska
Re: Re: classnames and HLL namespaces -- help!
Allison Randal [EMAIL PROTECTED] wrote: Matt Diephouse wrote: Patrick R. Michaud [EMAIL PROTECTED] wrote: On Thu, Oct 19, 2006 at 10:01:29PM -0400, Matt Diephouse wrote: This is unspecced. ATM, all classes go into the 'parrot' HLL. This is a relic of the past and I think it needs to change. I'm pretty sure that HLL classes will have to go into the HLL's root namespace (this needs to happen anyway to prevent namespace pollution). That leaves us with the question of how to differentiate core PMCs from HLL PMCs. I'm not sure how to handle that, but that's what a spec is for. Why is the differentiation necessary -- wouldn't core PMCs simply be part of the 'parrot' HLL? That's the place to put them. But how do you make the core PMCs visible to the compiler and not to the user? I expect the Perl 6 compiler will want to use a ResizablePMCArray in places without making it a builtin Perl 6 class. But how can you if there's only one new opcode? If we have a strict separation between the HLL namespace and the Parrot namespace (and I think we should), then the only way instantiate a core Parrot class/PMC from within an HLL is to first retrieve the 'parrot' namespace, and preferably through the typed interface. Speculatively: $P0 = get_root_namespace ['parrot'] $P1 = $P0.find_class('ResizablePMCArray') $P2 = new $P1 $P2.INIT() I think we have to keep in mind here that there will be a *lot* of hand-written code that needs to create PMCs from the Parrot core. I don't want to have to use the above snippet in all my hand written code; it adds a lot of bulk and is a huge pain. Patrick threw out the idea of letting .Type constants refer to core PMCs. That's a reasonable idea, I think. It lets me create them easily and doesn't get in the way of HLL classes. And I don't think there's any way to get those constants to work with anything but core PMCs anyway. How Perl 6 (or some other HLL) chooses to distinguish loading a module written in the same HLL from loading a module written in a different HLL is an open question. It will need some syntax. One earlier proposal suggested separating the HLL from the rest of the name with a single colon ('python:NLTK-Lite::Parse::LamdaCalculus'). This is included in PDD21. Perl 6 will strip off the language, split the module name and end up with a string (python) and an array (['NLTK-Lite', 'Parse', 'LamdaCalculus']). It can use the string to load the correct compiler (this is still unimplemented, by the way). The compiler object it gets will take the array and load the appropriate library (this is also unimplemented atm). Perl 6 could presumably install the class into it's own HLL, which makes instantiation easy. -- Matt Diephouse http://matt.diephouse.com
Re: set operations for roles
HaloO, I wrote: Yes, but I was conjecturing that the additions to AB are pushed down to A and B such that their intension sets remain strict supersets of AB. Think of the Complex example that might read role Complex does Num !Comparable { method im { return 0; } method re { return self as Num } # a no-op for Num } class Complex does Complex { has $.re; # accessor overwrites role method has $.im; # accessor overwrites role method } Apart from the fact that the role and the class compete for the same name slot this looks like what you need to make Num applicable wherever a Complex is expected: module A { use Complex; Num $a; say $a.im; # statically type correct, prints 0 } module B { Num $b; say $b.im; # syntactically admissible, but produces runtime error } Actually the 'self as Num' should return the self type ::?CLASS to preserve as much type information as possible. Hmm, could we get the keyword Self for that? Have a nice weekend, TSa. --
Re: set operations for roles
TSa wrote: Jonathan Lang wrote: In short, R3 isn't neccessarily a subset of A; it's a superset of A B. In a partial ordering graph, there's no reliable ordering between R3 and A. The standard syntax for creating roles can't reliably produce a subset of an existing role, because it always allows you to add to it. Yes, but I was conjecturing that the additions to AB are pushed down to A and B such that their intension sets remain strict supersets of AB. I know; but as you pointed out, a single undefined method brought in this way would break every existing class that composes A or B. Besides, there's the principle of the matter: creating a new role should not change the behavior of existing roles. Admittedly, I'm bending that rule when I suggest that A should get AB added to its list of roles when AB is created; but I'm not breaking it, because AB won't have anything in it that A doesn't already have, and A will uniformly override any behaviors that AB might provide. The _only_ thing that this change does is to let A match AB for type-checking purposes. But letting R3 backend new methods into A _does_ change A's behavior: it now has methods that it didn't used to have. This can lead to a more subtle version of the yadda-yadda problem that you pointed out: if someone has a routine that depends on a failure occurring if A.m is called, then the routine will stop working as expected if you backend .m into A via R3. The only problem that might crop up is the use of 'A | B' in signatures to mean 'can match any of A, B' - that is: in signatures, 'A | B' refers to the junctive operator; while in the above proposal, 'A | B' refers to the set union operator. Different semantics. In fact if we decide to specify a role combination syntax then it should be the same everywhere. Agreed - but we're not talking about role combination syntax in both places. In signatures, we're talking about a conjunction of two distinct roles, which is not the same as any sort of combined role (union or intersection). In particular, the conjunction treats each role as an atomic unit, while unions and intersections deal with their elements. -- Jonathan Dataweaver Lang
Re: set operations for roles
TSa wrote: Here is yet another idea to go with the two lattice operations: /\ meet also: infimum, intersection, glb (greatest lower bound) \/ join also: supremum, union,lub (least upper bound) I have to admit: if it turns out that '' and '|' can't be used for 'intersection' and 'union', '/\' and '\/' wouldn't be the worst choices to replace them. But I'd like to verify that we can't use what we currently have first, before we go changing things. and also read nice as english words: role J joins A, B, C; # same as role J does A \/ B \/ C role M meets A, B, C; # same as role M does A /\ B /\ C I'm less enthusiastic about this, though: perl already uses 'join' for list concatenation. -- Jonathan Dataweaver Lang
Re: classnames and HLL namespaces -- help!
Matt Diephouse writes: Allison Randal [EMAIL PROTECTED] wrote: Matt Diephouse wrote: Patrick R. Michaud [EMAIL PROTECTED] wrote: On Thu, Oct 19, 2006 at 10:01:29PM -0400, Matt Diephouse wrote: This is unspecced. ATM, all classes go into the 'parrot' HLL. This is a relic of the past and I think it needs to change. I'm pretty sure that HLL classes will have to go into the HLL's root namespace (this needs to happen anyway to prevent namespace pollution). That leaves us with the question of how to differentiate core PMCs from HLL PMCs. I'm not sure how to handle that, but that's what a spec is for. Why is the differentiation necessary -- wouldn't core PMCs simply be part of the 'parrot' HLL? That's the place to put them. But how do you make the core PMCs visible to the compiler and not to the user? I expect the Perl 6 compiler will want to use a ResizablePMCArray in places without making it a builtin Perl 6 class. But how can you if there's only one new opcode? If we have a strict separation between the HLL namespace and the Parrot namespace (and I think we should), then the only way instantiate a core Parrot class/PMC from within an HLL is to first retrieve the 'parrot' namespace, and preferably through the typed interface. Speculatively: $P0 = get_root_namespace ['parrot'] $P1 = $P0.find_class('ResizablePMCArray') $P2 = new $P1 $P2.INIT() I think we have to keep in mind here that there will be a *lot* of hand-written code that needs to create PMCs from the Parrot core. I don't want to have to use the above snippet in all my hand written code; it adds a lot of bulk and is a huge pain. Patrick threw out the idea of letting .Type constants refer to core PMCs. That's a reasonable idea, I think. It lets me create them easily and doesn't get in the way of HLL classes. And I don't think there's any way to get those constants to work with anything but core PMCs anyway. Don't forget static core pmcs vs. dyanamic core pmcs: pretty sure you can't use the . notation safely on the dynpmcs. How Perl 6 (or some other HLL) chooses to distinguish loading a module written in the same HLL from loading a module written in a different HLL is an open question. It will need some syntax. One earlier proposal suggested separating the HLL from the rest of the name with a single colon ('python:NLTK-Lite::Parse::LamdaCalculus'). This is included in PDD21. Perl 6 will strip off the language, split the module name and end up with a string (python) and an array (['NLTK-Lite', 'Parse', 'LamdaCalculus']). It can use the string to load the correct compiler (this is still unimplemented, by the way). The compiler object it gets will take the array and load the appropriate library (this is also unimplemented atm). Perl 6 could presumably install the class into it's own HLL, which makes instantiation easy. -- Matt Diephouse http://matt.diephouse.com
Re: set operations for roles
On Fri, Oct 20, 2006 at 09:10:12AM -0700, Jonathan Lang wrote: : TSa wrote: : Here is yet another idea to go with the two lattice operations: : :/\ meet also: infimum, intersection, glb (greatest lower bound) :\/ join also: supremum, union,lub (least upper bound) : : I have to admit: if it turns out that '' and '|' can't be used for : 'intersection' and 'union', '/\' and '\/' wouldn't be the worst : choices to replace them. But I'd like to verify that we can't use : what we currently have first, before we go changing things. I think we should reserve | and for matching predicates (read: signatures and where clauses) rather than type construction. We have to remember that type theory is completely inside-out to the way most Perl programmers think. Type theory is all about Platonic objects and how you go about constructing such abstractions in the abstract. Most people don't want to think on that level, and are quite willing to delegate the high-powered abstractions to someone else. Therefore I'd like these to be illegal: subset X of Y | Z; subset X of Y Z; subset X of Y ^ Z; and need to be written more like: subset X of Any where Y | Z; subset X of Any where Y Z; subset X of Any where Y ^ Z; I now think it's a bad idea to overload | or to do type construction, especially since the tendency is to define them backwards from the operational viewpoint that most Perl programmers will take. : and also read nice as english words: : :role J joins A, B, C; # same as role J does A \/ B \/ C :role M meets A, B, C; # same as role M does A /\ B /\ C : : I'm less enthusiastic about this, though: perl already uses 'join' for : list concatenation. We can negotiate the color of the bikeshed over time. I don't personally have a problem with meets and joins, and while you might think that \/ makes it impossible to write [\/] to get a reducing divide, that's not an operator you'd likely want anyway. But one of the basic underlying principles of Perl 6 is that we don't have to overload different operators in a confusing way anymore. \/ should probably be the ASCII workaround for ∨ while /\ is the ASCII for ∧. And at one point @Larry reserved all the parenthesized operators for the ASCII workarounds for set operators. Anyway, I think the type constructors need to avoid overloading the logic operators. Perl 6 is an operator-rich language because that contributes to long-term clarity despite the short-term confusion. Larry
Re: set operations for roles
Larry Wall wrote: Anyway, I think the type constructors need to avoid overloading the logic operators. Perl 6 is an operator-rich language because that contributes to long-term clarity despite the short-term confusion. OK. My main dog in this race is the idea of defining new roles through the concepts of the intersection or difference between existing roles (even the union was thrown in there mainly for the sake of completion), with the consequent extension of the type system in the opposite direction from the usual one (toward the more general); the exact syntax used for this is less of an issue, as long as it is straightforward and simple. Given that the set analogy is exactly what I'm using, I'd be fine using the Set operators (presumably '\xAD\xFC' and '\xAD\xFB') and their ASCII workarounds ('(|)' and '()'?) instead of '|' and ''. Presumably, '-' is still the difference of Sets operator. And yes, this roles as sets paradigm would presumably mean that you could examine roles using '⊂', '⊃', '∈', and so on. Given the semantic aspect of roles, I don't think that I'd go along with saying that 'A ⊃ B' is equivalent to 'A.does(B)' - although I _would_ agree that if 'A.does(B)' then 'A ⊃ B'. Rather, I'd think of 'A ⊃ B' as being the means that one would use for duck-typing, if one really wanted to (presuming that one can mess with how perl 6 does type-checking). Likewise, 'm ∈ R' will match if 'R.can(m)'; but the definition of 'element' might be broader than just methods. -- Jonathan Dataweaver Lang
Re: class interface of roles
On Thu, Oct 19, 2006 at 03:31:18PM -0700, Jonathan Lang wrote: : Larry Wall wrote: : Though actually, now that I think about it, the cascaded notation : in S12 is illegal according to S03, since does is classified as : non-chaining, which implies non-associative. : : Wait a minute. Isn't chaining specifically referring to the idea : that A op B op C implicitly becomes something like A op B B op : C? That would seem to be unrelated to the concept of associativity, : other than the fact that you can't have chaining without : associativity. Why would does have to be chaining in order to be : associative? I was using non-chaining to indicate a particular precedence level. (In actual fact, all precedence levels but chaining are non-chaining, but only one precedence level actually has that name.) The non-chaining precedence level is a bunch non-associative operators like .. and cmp. Historically, all operators of a particular precedence level have had the same associativity, so that when you analyze $a op1 $b op2 $c you only have to compare op1 with op2 if they're the same precedence, and given the prededence you don't actually have to look at the individual ops. What would it mean to have a left-associative op at the same precedence level as a right-associative op: $a lefty $b righty $c Who would win? So generally we try not to mix associativity within a precedence level. For now the conservative thing is probably that we should just leave does as non-associative and make you write $obj.also_does(A,B,C) or some such if you want to get fancy. Larry
Re: class interface of roles
On Fri, Oct 20, 2006 at 04:47:04PM -0700, Larry Wall wrote: : For now the conservative thing is probably that we should just leave : does as non-associative and make you write : : $obj.also_does(A,B,C) : : or some such if you want to get fancy. Presumably $obj does (A,B,C) could also be made to work even with non-associative does. Larry
[svn:perl6-synopsis] r13252 - doc/trunk/design/syn
Author: larry Date: Fri Oct 20 17:01:15 2006 New Revision: 13252 Modified: doc/trunk/design/syn/S12.pod Log: does operator is non-associative according to S03. Leave it that way for now. Modified: doc/trunk/design/syn/S12.pod == --- doc/trunk/design/syn/S12.pod(original) +++ doc/trunk/design/syn/S12.podFri Oct 20 17:01:15 2006 @@ -12,9 +12,9 @@ Maintainer: Larry Wall [EMAIL PROTECTED] Date: 27 Oct 2004 - Last Modified: 4 Oct 2006 + Last Modified: 20 Oct 2006 Number: 12 - Version: 28 + Version: 29 =head1 Overview @@ -1017,10 +1017,17 @@ $fido does Sentry -The Cdoes operator returns the object so you can nest mixins: +The Cdoes operator is non-associative, so this is a syntax error: $fido does Sentry does Tricks does TailChasing does Scratch; +You can, however, say + +$fido does Sentry; +$fido does Tricks; +$fido does TailChasing; +$fido does Scratch; + Unlike the compile-time role composition, each of these layers on a new mixin with a new level of inheritance, creating a new anonymous class for dear old Fido, so that a C.chase method from CTailChasing hides a @@ -1028,7 +1035,7 @@ You can also mixin a precomposed set of roles: -$fido does Sentry | Tricks | TailChasing | Scratch; +$fido does (Sentry, Tricks, TailChasing, Scratch); This will level the playing field for collisions among the new set of roles, and guarantees the creation of no more than one more anonymous class.
Re: class interface of roles
Larry Wall wrote: Presumably $obj does (A,B,C) could also be made to work even with non-associative does. Right. Note that you _do_ want to be able to do something to the effect of ordered composition in a single statement, though: role A { ... method m { ... } } $x does A; A.m will override $x.m - assuming that $x.m exists at all. As such, you end up with an anonymous class with an undefined method - a distinct no-no. Maybe what you need to say is that $x does ... is a macro that treats what follows as part of an anonymous class definition. So $x does A does B { method m { doit } } ^^ would be equivalent to something like $x.WHAT := class is $x.WHAT does A does B { method m { doit } } ^^ You'd need to have the macro work some magic involving curly-braces and terminating semicolons, so that $x does A; doit; ... becomes $x.WHAT := class is $x.WHAT does A { } doit; ... instead of $x.WHAT := class is $x.WHAT does A { doit; ... } And you'd have to decide what to do with $x does role { ... } { ... } Should this become $x.WHAT := class is $x.WHAT does role { ... } { ... } or $x.WHAT := class is $x.WHAT does role { ... } { } { ... } ? But otherwise, this approach allows runtime composition to use exactly the same syntax and semantics as compile-time composition as soon as you hit infix:does. -- Jonathan Dataweaver Lang