Re: class interface of roles
HaloO, Jonathan Lang wrote: What do you mean by uncomposed class? The self always refers to the object as instance of the composed class. Methods are therefore resolving to the outcome of the composition process. But super in a role refers to methods from the class definition even when the final method comes from method combination in the composition process. I think the word super is already to overloaded to be used for this purpose. Setting that aside for now... Better ideas? Is there a super keyword already? Or do you mean overloaded in general OO and type speak? Do you mean that super.blah() appearing in a method defined in a role A should require that all classes which do A need to provide a blah implementation? (or produce a composition time error if they don't) Yes, this is exactly what I mean with superclass interface of roles. I hope not; that's exactly what declaring an unimplemented method in a role is supposed to do. My idea is that the type system calculates a type bound for the class from the definition of the role. That includes attributes and their accessor methods. It's a matter of taste how explicit this interface is declared or how much of it is infered. (And declaring an implemented method does the same thing, with the addition that it also suggests an implementation that the class is free to use or ignore as it sees fit.) We have a priority conflict here. The question is if the class or the role is seeing the other's methods for method combination. A Role should be able to say to do this Role you need to implement these methods and have a compile/composition time error if not. Agreed. I agree as well. But on a wider scope then just method provision. (There does need to be a way to call, in a Role A, both the blah defined in A and whatever the blah the final class may use. Yes, this is the subject of the current debate. I'm opting for a method combination semantics that allows the role to call the class method. $self.blah() is the later, $self.A::blah() or similar is likely to be the former.) No, there doesn't. Given that Cclass Foo does A and Crole A does B, There needs to be a way to call, in class Foo, both the blah defined in Foo, the blah defined in A (so that Foo can reimplement A's version as a different method or as part of its own), and the blah defined in B; From the class all composed parts are available through namespace qualified names. But a role is a classless and instanceless entity. The self refers to the objects created from the composed class. The role is not relevant in method dispatch. That is a method is never dispatched to a role. But the role should be able to participate in the method definition of the composed class. and there needs to be a way to call, in role A, both the blah defined in Foo and the blah defined B; but role A does not need a way to explicitly call a method defined in A. I'm not sure if I get this right. But as I said above a role can not be dispatched to. Which method do you think should take precedence the role's or the class's? That is who is the defining entity in the method combination process? I would hope it is the role if a as of now unknown syntax has declared it. Perhaps it should be even the default. The rational for my claim is that a role is composed several times and then every class doing the role automatically gets the correct version. Otherwise all classes are burdened with caring for the role's part in the method. It should assume that if Foo overrides A's implementation of blah, Foo knows what it's doing; by the principle of least surprise, Foo should never end up overriding A's implementation of blah only to find that the original implementation is still being used by another of the methods acquired from A. Could you make an example because I don't understand what you mean with original implementation and how that would be used by role methods. Method dispatch is on the class never on the role. As far as dispatch is concerned the role is flattend out. But the question is how the class's method is composed in the first place. Regards, --
Re: class interface of roles
HaloO, Jonathan Lang wrote: So if I'm reading this right, a class that does both A and B should be lower in the partial ordering than a class that does just one or the other. And if A does B, then you'll never have a class that does just A without also doing B, which trims out a few possible nodes and paths from the lattice for practical purposes: Any={} | \ | \ |\ | \ | \ B={y} C={z} / \ | / \ | / \| / \ | / \ | / \ | A|B={x,y} B|C={y,z} \ / \ / \ / \ / \ / A|B|C={x,y,z} Correct. The lattice is a structural analysis of the roles. I note that while the lattice is related to whatever role hierarchies may or may not exist, it is not the same as them. In particular, roles that have no hierarchal relationship to each other _will_ exist in the same lattice. In fact, all roles will exist in the same lattice, on the first row under Any. Right? Yes, if they are disjoined structurally. Otherwise intersection roles appear as nodes under Any. Or does the fact that A does B mean that A would be placed where A|B is, and A|C would end up in the same node as A|B|C? To get at the node labeled A|B above you either need a definition role A does B { has $.x } or an outright full definition role A { has $.x; has $.y } So, yes the node should be called A and A|C coincides with A|B|C. I'm not sure if this ordering of roles can be called duck typing because it would put roles that have the same content into the same lattice node. The well known bark method of Dog and Tree comes to mind. But the arrow types of the methods will be different. One has type :(Dog -- Dog) the other :(Tree -- Tree) and a joined node will have type :(DogTree -- Dog|Tree). This might just give enough information to resolve the issues surrounding the DogTree class. By most specific, you'd mean closest to the top? No, closer to the bottom. The join operator | of the lattice produces subtypes with a larger interface that is more specific. It's like the more derived class in a class hierarchy. Regards, TSa. --
Runtime role issues
Hi all, I posted this to Perl6 users, but I was Warnocked, it was the wrong list, or both. Here's another stab at it. In doing a bit of work with traits (roles) in Perl 5 (http://perlmonks.org/?node_id=577477), I've realized some edge cases which could be problematic. First, when a role is applied to a class at runtime, a instance of that class in another scope may specifically *not* want that role. Is there a way of restricting a role to a particular lexical scope short of applying that role to instances instead of classes? Second, how can I remove roles from classes? I've create some code which adds an is_selected method to some classes but when I'm done, I'd like top easily remove that role. How do I do that? Seems closely related to my first question, but it's still a distinct issue, I think. Third, http://dev.perl.org/perl6/doc/design/syn/S12.html says: You can also mixin a precomposed set of roles: $fido does Sentry | Tricks | TailChasing | Scratch; Should that be the following? $fido does Sentry Tricks TailChasing Scratch; Cheers, Ovid -- Buy the book -- http://www.oreilly.com/catalog/perlhks/ Perl and CGI -- http://users.easystreet.com/ovid/cgi_course/
Re: Runtime role issues
HaloO, Ovid wrote: Third, http://dev.perl.org/perl6/doc/design/syn/S12.html says: You can also mixin a precomposed set of roles: $fido does Sentry | Tricks | TailChasing | Scratch; Should that be the following? $fido does Sentry Tricks TailChasing Scratch; If you follow my idea of a type lattice build from roles with | as join and as meet operator these two mean something completely different. The first is the join or union of the roles while the second is their meet or intersection. The first creates a subtype of the roles the second a supertype. But the typishness of roles is debated. Regards, TSa. --
Re: Runtime role issues
HaloO, Ovid wrote: First, when a role is applied to a class at runtime, a instance of that class in another scope may specifically *not* want that role. Is there a way of restricting a role to a particular lexical scope short of applying that role to instances instead of classes? I think you'll need an intermediate class that you use to apply your role. Classes are open and that implies the possibility to merge further roles into them. But this applies for all users of the class. How this works when there are already instances I don't know. Second, how can I remove roles from classes? Is that a wise thing to do? Roles are not assigned and removed as a regular operation. What is your use case? Regards, TSa. --
P5's s[pat][repl] syntax is dead
@larry[0] wrote: Log: P5's s[pat][repl] syntax is dead, now use s[pat] = repl Wow, I really missed this one! That's a pretty big thing to get my head around. Are embedded closures in the string handled correctly so that: s:g[\W] = qq{\\{$/}}; Will do what I seem to be expecting it will? How will that be defined in the Perl6-based parser? Will macros be able to act as an LVALUE and modify their RVALUE in this way, or is this just some unholy magic in the parser? + s[pattern] = doit() + s[pattern] = eval doit() [...] +There is no syntactic sugar here, so in order to get deferred +evaluation of the replacement you must put it into a closure. The +syntactic sugar is provided only by the quotelike forms. [...] +This is not a normal assigment, since the right side is evaluated each +time the substitution matches (much like the pseudo-assignment to declarators +can happen at strange times). It is therefore treated as a thunk, that is, +as if it has implicit curlies around it. In fact, it makes no sense at +all to say + +s[pattern] = { doit } Please clarify quotelike forms, since to my untrained eye, the above appeared to be contradictory at first (I read quotelike forms as s/// not s{...}). Very interesting.
Re: Runtime role issues
First, when a role is applied to a class at runtime, a instance of that class in another scope may specifically *not* want that role. Is there a way of restricting a role to a particular lexical scope short of applying that role to instances instead of classes? Seems like you could use an empty intermediate role to accomplish the same thing while leaving the shared class alone. Shared Class A Mixin Role B Class C isa A does B Class D isa A Shared Class A is unmodified. Otherwise, I think that any runtime modification of a class should affect all instances and future instances of that class. On closer inspection, is it even possible to add a Role to a Class at runtime? I thought that Class and Role composition outside of compile time resulted in a new pseudo Class for the subsequent instances of that composition - in which case the original Class would remain unmodified. Paul
Re: P5's s[pat][repl] syntax is dead
On Wed, Oct 11, 2006 at 10:32:13AM -0400, Aaron Sherman wrote: : @larry[0] wrote: : : Log: : P5's s[pat][repl] syntax is dead, now use s[pat] = repl : : Wow, I really missed this one! That's a pretty big thing to get my head : around. Are embedded closures in the string handled correctly so that: : : s:g[\W] = qq{\\{$/}}; : : Will do what I seem to be expecting it will? Yes, the right side is implicitly closurized and evaluated repeatedly by the left side. : How will that be defined in the Perl6-based parser? Will macros be able : to act as an LVALUE and modify their RVALUE in this way, or is this just : some unholy magic in the parser? This is just a macro with a fancy is parsed rule, I think. It eats the = in complete disregard for precedence. Nothing much to generalize, I think. : + s[pattern] = doit() : + s[pattern] = eval doit() : [...] : +There is no syntactic sugar here, so in order to get deferred : +evaluation of the replacement you must put it into a closure. The : +syntactic sugar is provided only by the quotelike forms. : [...] : +This is not a normal assigment, since the right side is evaluated each : +time the substitution matches (much like the pseudo-assignment to : declarators : +can happen at strange times). It is therefore treated as a thunk, that : is, : +as if it has implicit curlies around it. In fact, it makes no sense at : +all to say : + : +s[pattern] = { doit } : : Please clarify quotelike forms, since to my untrained eye, the above : appeared to be contradictory at first (I read quotelike forms as s/// : not s{...}). s{...} is also a quotelike form. Basically I mean anything where you get to choose your own quote characters, whether or not they are brackets. : Very interesting. Yeah, we whacked on possible syntaxes a goodly long time on IRC the other night. Trying to balance out history and visuals and semantics and failure modes was all quite interesting, but in the absence of more Unicode keys on the keyboard I'm liking this notation pretty well, particularly since we've already used pseudo assignment in other places to thunkize the right side. Larry
signature subtyping and role merging
HaloO, with my idea of deriving a type lattice from all role definitions the problem of subtyping signatures arises. Please help me to think this through. Consider role Foo { sub blahh(Int, Int) {...} } role Bar { sub blahh(Str) {...} } role Baz does Foo does Bar # Foo|Bar lub { # sub blahh(IntStr,Int?) {...} } The role Baz has to be the lub (least upper bound) of Foo and Bar. That is the join of two nodes in the lattice. This means first of all the sub blahh has to be present. And its signature has to be in a subtype relation : to :(Int,Int) and :(Str). Note that Int : IntStr and Int|Str : Int. The normal contravariant subtyping rules for functions gives +- : ---+ || :(IntStr,Int?) : :(Int,Int) | | +--- : ---+ and +- : ---+ || :(IntStr,Int?) : :(Str) I hope you see the contravariance :) The question mark shall indicate an optional parameter that allows the subtype to be applicable in both call sites that have one or two arguments. The choice of glb for the first parameter makes the sub in Baz require the implementor to use the supertype of Int and Str which in turn allows the substitution of Int and Str arguments which are subtypes---that is types with a larger interface. Going the other way in the type lattice the meet FooBar of the two roles Foo and Bar is needed. But here the trick with the optional parameter doesn't work and it is impossible to reconcile the two signatures. This could simply mean to drop sub blahh from the interface. But is there a better way? Perhaps introducing a multi? Apart from the arity problem the lub Int|Str works for the first parameter: +- : ---+ || :(Int|Str,Int) : :(Int,Int) | | +--- : ---+ + : ---+ | | :(Int|Str) : :(Str) Regards, TSa. --
Re: class interface of roles
TSa wrote: Jonathan Lang wrote: What do you mean by uncomposed class? The self always refers to the object as instance of the composed class. Methods are therefore resolving to the outcome of the composition process. But super in a role refers to methods from the class definition even when the final method comes from method combination in the composition process. Still not following. Can you give an example? I hope not; that's exactly what declaring an unimplemented method in a role is supposed to do. My idea is that the type system calculates a type bound for the class from the definition of the role. That includes attributes and their accessor methods. It's a matter of taste how explicit this interface is declared or how much of it is inferred. Note that it's entirely possible for attributes to not make it into the final class, if the accessor methods get redefined in such a way as to remove reference to the attributes. This is part of the notion that roles supply an outline of what the class should do, but only the class actually supplies the definitive details of how to do it. As I see it: is and does declarations in a role impose requirements on the final class: it must derive from another class (is), or it must compose another role (does). method and has are each one part requirement and one part suggestion: for method, the class is required to include a method that matches the given name (which, of course, includes the method's signature), and a particular closure is suggested that the class can accept or override. For has, the class is required to provide accessor methods corresponding to the attribute's read/write capabilities (a rw method if it's a rw attribute; a regular method if it's a regular attribute; and no method if it's a private attribute); like any other method, a closure is suggested that the class may accept or override. In addition, the role suggests that a given attribute be added to the class' state information. This suggestion is implicitly accepted if any of the methods that are used by the final class refer to the attribute; it is implicitly rejected if none of them do. The same rule applies to private methods. Thus, the only things that I'd recommend using to calculate a type-boundary would be the superclasses (provided by is) and the method names (provided by method and has). (And declaring an implemented method does the same thing, with the addition that it also suggests an implementation that the class is free to use or ignore as it sees fit.) We have a priority conflict here. The question is if the class or the role is seeing the other's methods for method combination. I believe that I address this later on; if not, please clarify. (There does need to be a way to call, in a Role A, both the blah defined in A and whatever the blah the final class may use. Yes, this is the subject of the current debate. I'm opting for a method combination semantics that allows the role to call the class method. Agreed. $self.blah() is the later, $self.A::blah() or similar is likely to be the former.) No, there doesn't. Given that Cclass Foo does A and Crole A does B, There needs to be a way to call, in class Foo, both the blah defined in Foo, the blah defined in A (so that Foo can reimplement A's version as a different method or as part of its own), and the blah defined in B; From the class all composed parts are available through namespace qualified names. But a role is a classless and instanceless entity. The self refers to the objects created from the composed class. The role is not relevant in method dispatch. That is a method is never dispatched to a role. But the role should be able to participate in the method definition of the composed class. Also agreed. In particular, I'm referring to _how_ a role should participate in the method definition of the composed class; I am not referring to method dispatch, which is limited to the class hierarchy. and there needs to be a way to call, in role A, both the blah defined in Foo and the blah defined B; but role A does not need a way to explicitly call a method defined in A. I'm not sure if I get this right. But as I said above a role can not be dispatched to. Which method do you think should take precedence the role's or the class's? That is who is the defining entity in the method combination process? I agree with the idea behind the current definition of this: if the class provides its own definition for a method, that should take precedence over the role's definition. If it doesn't, then it adopts the role's definition as its own. I would hope it is the role if a as of now unknown syntax has declared it. Perhaps it should be even the default. The rational for my claim is that a role is composed several times and then every class doing the role automatically gets the correct version. Otherwise all classes are burdened with caring for the role's part in the method. Huh?
Re: signature subtyping and role merging
This is the dog does bark vs tree does bark problem. You can assume that the two methods blahh have naything semantically to do with each other at all. Unless ther is a specif annotation from the programmer creating the Role union that they are the same you must assume that they are different. Therefore your proposed signiture merge is nonsense in the general case. Even if the signature are the same the only case where you are justified in assuming that are the same method is if both composed Roles inherited the method from a common ancestor and even then you must solve the diamond inheritence problem. -- Mark Biggar [EMAIL PROTECTED] [EMAIL PROTECTED] [EMAIL PROTECTED] -- Original message -- From: TSa [EMAIL PROTECTED] HaloO, with my idea of deriving a type lattice from all role definitions the problem of subtyping signatures arises. Please help me to think this through. Consider role Foo { sub blahh(Int, Int) {...} } role Bar { sub blahh(Str) {...} } role Baz does Foo does Bar # Foo|Bar lub { # sub blahh(IntStr,Int?) {...} } The role Baz has to be the lub (least upper bound) of Foo and Bar. That is the join of two nodes in the lattice. This means first of all the sub blahh has to be present. And its signature has to be in a subtype relation : to :(Int,Int) and :(Str). Note that Int : IntStr and Int|Str : Int. The normal contravariant subtyping rules for functions gives +- : ---+ || :(IntStr,Int?) : :(Int,Int) | | +--- : ---+ and +- : ---+ || :(IntStr,Int?) : :(Str) I hope you see the contravariance :) The question mark shall indicate an optional parameter that allows the subtype to be applicable in both call sites that have one or two arguments. The choice of glb for the first parameter makes the sub in Baz require the implementor to use the supertype of Int and Str which in turn allows the substitution of Int and Str arguments which are subtypes---that is types with a larger interface. Going the other way in the type lattice the meet FooBar of the two roles Foo and Bar is needed. But here the trick with the optional parameter doesn't work and it is impossible to reconcile the two signatures. This could simply mean to drop sub blahh from the interface. But is there a better way? Perhaps introducing a multi? Apart from the arity problem the lub Int|Str works for the first parameter: +- : ---+ || :(Int|Str,Int) : :(Int,Int) | | +--- : ---+ + : ---+ | | :(Int|Str) : :(Str) Regards, TSa. --
Re: signature subtyping and role merging
On 10/11/06, TSa [EMAIL PROTECTED] wrote: HaloO, with my idea of deriving a type lattice from all role definitions the problem of subtyping signatures arises. Please help me to think this through. Consider role Foo { sub blahh(Int, Int) {...} } role Bar { sub blahh(Str) {...} } role Baz does Foo does Bar # Foo|Bar lub { # sub blahh(IntStr,Int?) {...} } Please, no attempts to merge signatures. Instead, use multiple dispatch (though technically this doesn't kick in until the role is composed into a class). Thus: role Foo { multi blahh(Int, Int) {...} } role Bar { multi blahh(Str) {...} } role Baz does Foo does Bar # Foo|Bar lub { # multi blahh(Int, Int) {...} # multi blahh(Str) {...} } Remember that the name and the signature are used together to identify the routine for dispatch and composition purposes. Also, sub is an odd choice to use while illustrating role composition; while subs _are_ allowed in roles AFAIK, they're generally not put there. Methods and submethods are by far more common. -- Jonathan Dataweaver Lang
Re: Runtime role issues
--- TSa [EMAIL PROTECTED] wrote: First, when a role is applied to a class at runtime, a instance of that class in another scope may specifically *not* want that role. Is there a way of restricting a role to a particular lexical scope short of applying that role to instances instead of classes? I think you'll need an intermediate class that you use to apply your role. Classes are open and that implies the possibility to merge further roles into them. But this applies for all users of the class. How this works when there are already instances I don't know. Ah, that makes sense. Second, how can I remove roles from classes? Is that a wise thing to do? Roles are not assigned and removed as a regular operation. What is your use case? I don't think I have a clear use case here because the examples that come to mind all involve adding and then quickly removing the extra behaviors when I'm done with them. That's going to be fraught with bugs. The intermediate class solves the problem but it instantly suggests that we have a new design pattern we have to remember. Basically, if I can't lexically scope the additional behavior a role offers, I potentially need to remove the role or use the intermediate class pattern. I suppose one could look at this as separation of concerns. If I have an MVC framework, instances of objects in the M, V, or C portions might want to exhibit different behaviors, depending upon what I'm doing with them, but I don't necessarily want those behaviors to bleed over to the other layers of my application. Whether or not this is a clean way of looking at the problem, I don't know. Cheers, Ovid -- Buy the book -- http://www.oreilly.com/catalog/perlhks/ Perl and CGI -- http://users.easystreet.com/ovid/cgi_course/
Re: Synposis 26 - Documentation [alpha draft]
Jonathan Lang wrote: The only thing that I'd like to see changed would be to allow a more flexible syntax for formatting codes - in particular, I'd rather use something analogous to the 'embedded comments' described in S02, replacing the leading # with an appropriate capital letter (as defined by Unicode) and insisting on a word break just prior to it. It was a deliberate decision to restrict the delimiters to angles. Unlike embedded comments, formatting codes are predominantly embedded in text, not code, so it's important to keep them easy-to-locate (i.e. with a consistent delimiter) and not to allow too many syntaxes (which increases the chance of unintended codes in normal text). A leading word break is not really practical either, since documenters will need to use codes in the middle of words: PractIise (and then practIice) saying GarEccedilon! I'd also prefer a more Wiki-like dialect at some point (e.g., '__underlined text__', '_italicized text_' and '*bold*' instead of 'Uunderlined text', 'Iitalicized text' and 'Bbold'); but that can wait. That's Kwid. Which Ingy has proposed as a standard Perldoc dialect. You'll be able to flip into kwid mode (for Perldoc parsers that support it) using: =begin kwid =end kwid Damian
s[pattern] = { doit } illegal, why?
While I agree with most of the changes made to the s[]... notation, there's one oddity that I just spotted: S05 says: This is not a normal assigment, since the right side is evaluated each time the substitution matches (much like the pseudo-assignment to declarators can happen at strange times). It is therefore treated as a thunk, that is, as if it has implicit curlies around it. In fact, it makes no sense at all to say s[pattern] = { doit } because that would try to substitute a closure into the string. So I can't say something like s[(\d+)!] = { my $num = 1; $num *= $_ for 0..$0; return $num; } or s:s:g[(\w+): (\d+) dB] = @() - $name, $num { $num = exp($num/10, 10); say $name has excessive wattage: $num Watts if $num 100; $name: $num Watts; } or s:s:g[, (\w+): (.+) ,] = @() - $key, $val { $key = $val } ? That seems like a pretty significant limitation. Could closures be an exception to the implicit curlies rule? That is: if you supply your own closure on the right, the substitution algorithm accepts it as is; if you supply anything else, it gets wrapped in a closure as described. -- Jonathan Dataweaver Lang
Re: s[pattern] = { doit } illegal, why?
On Wed, Oct 11, 2006 at 05:55:45PM -0700, Jonathan Lang wrote: : While I agree with most of the changes made to the s[]... notation, : there's one oddity that I just spotted: : : S05 says: : This is not a normal assigment, since the right side is : evaluated each time the substitution matches (much like the : pseudo-assignment to declarators can happen at strange times). : It is therefore treated as a thunk, that is, as if it has : implicit curlies around it. In fact, it makes no sense at all : to say : : s[pattern] = { doit } : : because that would try to substitute a closure into the string. : : So I can't say something like : :s[(\d+)!] = { my $num = 1; $num *= $_ for 0..$0; return $num; } s[(\d+)!] = { my $num = 1; $num *= $_ for 0..$0; return $num; } s[(\d+)!] = { my $num = 1; $num *= $_ for 0..$0; return $num; }.() s[(\d+)!] = do { my $num = 1; $num *= $_ for 0..$0; return $num; } : or : :s:s:g[(\w+): (\d+) dB] = : @() - $name, $num { :$num = exp($num/10, 10); :say $name has excessive wattage: $num Watts if $num 100; : :$name: $num Watts; : } s:s:g[(\w+): (\d+) dB] = do given @() - [$name, $num] { $num = exp($num/10, 10); say $name has excessive wattage: $num Watts if $num 100; $name: $num Watts; } : or : :s:s:g[, (\w+): (.+) ,] = @() - $key, $val { $key = $val } s:s:g[, (\w+): (.+) ,] = - $key, $val { $key = $val }.(@()) s:s:g[, (\w+): (.+) ,] = do for @().each - $key, $val { $key = $val } : ? That seems like a pretty significant limitation. Could closures be : an exception to the implicit curlies rule? That is: if you supply : your own closure on the right, the substitution algorithm accepts it : as is; if you supply anything else, it gets wrapped in a closure as : described. Could do that too (and there's even precedent with attribute defaults), but outlawing it (at least for now) keeps people from cargo culting P5's s{foo}{bar} into P6's s{foo}={bar}. Larry
Re: s[pattern] = { doit } illegal, why?
On Wed, Oct 11, 2006 at 06:29:00PM -0700, Larry Wall wrote: : s:s:g[, (\w+): (.+) ,] = - $key, $val { $key = $val }.(@()) Hmm, that won't work, since @() is a single argument. It'd have to be one of: s:s:g[, (\w+): (.+) ,] = - [$key, $val] { $key = $val }.(@()) s:s:g[, (\w+): (.+) ,] = - $key, $val { $key = $val }.(|@()) Larry
Re: s[pattern] = { doit } illegal, why?
In short, nearly every case where I'm looking to use a raw closure can be handled almost as easily by prefacing it with Cdo (if the block doesn't take parameters) or Cdo given (if it does). A bit more wordy than I'd like, but acceptable; it still reads well. Although I'd recommend pointing this option out in S05, right after you say that s[pat] = { doit() } won't work. On 10/11/06, Larry Wall [EMAIL PROTECTED] wrote: s:s:g[, (\w+): (.+) ,] = do for @().each - $key, $val { $key = $val } Minor point: Since the right side gets called for each left-side match, isn't the C.each redundant? For that matter, isn't the Cfor overkill as well? C@() will only ever have two elements per call, after all... : Could closures be : an exception to the implicit curlies rule? That is: if you supply : your own closure on the right, the substitution algorithm accepts it : as is; if you supply anything else, it gets wrapped in a closure as : described. Could do that too (and there's even precedent with attribute defaults), but outlawing it (at least for now) keeps people from cargo culting P5's s{foo}{bar} into P6's s{foo}={bar}. This would be the ye olde code doesn't do a text substitution anymore issue, right? And there _is_ still the possibility of permitting it in some later subversion of Perl 6, once people have gotten Perl 5 out of their systems... -- Jonathan Dataweaver Lang
Re: Synposis 26 - Documentation [alpha draft]
Dave Whipp wrote: I'm not a great fan of this concept of reservation when there is no mechanism for its enforcement (and this is perl...). What makes you assume there will be no mechanism for enforcement? The standard Pod parser (of which I have a 95% complete Perl 5 implementation) will complain bitterly--as in cyanide--when unknown pure-upper or pure-lower block names are used. The whole point of reserving these namespaces is not to prevent users from misusing them, but to ensure that when we eventually get around to using a particular block name, and those same users start screaming about it, we can mournfully point to the passage in the original spec and silently shake our heads. ;-) Damian