Re: Operator sleuthing...
On Thu, Jan 15, 2009 at 10:52:55PM -0800, Mark Lentczner wrote: > I'm re-working my "Periodic Table of the Operators" chart to be up-to- > date. I did the first major pass based on S03-operators. However, the > last few days I've been plowing through STD.pm and have discovered that > there some differences. Since STD.pm is considered more up to date, I'll > be changing the chart to match that. However, I thought it would be > useful to share the detailed list of differences I found. Besides, there > are some embedded questions in there, I'd love to have answered. > > Thanks, > - Mark > > > STD.pm: r24855 | lwall | 2009-01-10 > S03-operators.pod r24895 | lwall | 2009-01-13 > > == Associativity == > > Prefix and postfix precedence levels have no associativity in STD, but > are left (mostly) or right in S03. Levels affected are: > %methodcall > %autoincrement > %symbolic_unary > %named_unary > %loose_unary > %list_prefix Fixed, but it took a while. :) > Some levels have left associativity in STD, but are list in S03. Levels > affected: > %concatenation > %tight_and > %tight_or > %loose_and > %loose_or Fixed. > Oddly, sym<^^> ( --> Tight_or) is forced to :assoc in STD. It is now naturally list. > ?? Even though for most of these operators there is no computational > difference between left and list assoc, list seems more "in the spirit" > to me. I plan on leaving them listed as 'list' assoc in the chart unless > there is a reason to make them left. List is correct. And, in fact, list associativity now devolves to right associativity rather than left. > Conditional level is right in STD, and left in S03. Is right. > == Added == > > STD has a new Methodcall operator construction: > token privop ( --> Methodcall) { > '!' > } > ?? What is this? Private method call, described in S12. > STD has postfix:sym. I understand this is the imaginary operator. Yes. > STD has infix:sym<.=>. I understand this to be the method call > assigning form when there is space after the operator. > ?? Is this right? Putting no space before and a space after may be a syntax error. We have a postfix form, and an infix form, but mixing the two will look to the parser like an incomplete postfix. Then again, it might backtrack and find it currently. It's arguable whether "progress" has been made in a predictive parser sense. > STD has <==, ==>, <<==, and ==>> as true operators. S03 groups them as > terminators. Fixed S03. > STD has sym<;> as both an infix operator ( --> Sequencer), and as a > terminator. > ?? Which is it? Since I think most people think of it as a statement > terminator, I plan on leaving it off the chart. STD now parses it consistently as a statement terminator (or as a special delimiter in argument lists, but that's more or less the same). > STD is missing sym<\\> at Symbolic_unary level. > ?? Did capture cease to be an operator? It's a special form, primarily to distinguish it from "unspace", but also to discourage its application to temporary results without use of full \(...) capture notation. Or to look at it another way, it's an operator at "term" precedence. :) > STD is missing sym at Multiplicative level. > ?? I'm assuming this is just an oversight. Indeed. > == Misc == > > The ff and fff family are at %nonchaining precedence in STD, but at > %conditional precedence in S03. Conditional, since they involve thunks, and the right associativity doesn't really hurt them (or help them). More practically, it lets you use && and || in the conditionals. > STD has infix:sym and infix:sym each declared as tokens > twice. I'm assuming this is just some accidental duplication. Yes. > At Loose_unary, STD has which seems more general than the > operator adverbs discussed in S03 at Loose unary precedence. The cutoff is actually at "epsilon tighter than comma", which allows for user-defined precedence levels in between. > The infix:sym<:> invocant marker is at Comma precedence in STD, but List > prefix in S03. It is also left assoc. in STD, but right in S03. It is at comma precedence, which is list assoc. Since we switched to right associative degeneracy meth $x: 1,2,3 and since : and , are at the same level, it now groups as: meth ($x : (1,2,3)) rather than the old meth (($x : 1), 2, 3) which I only discovered a couple days ago, and was greatly astonished. :) An alternative would be to establish a category of list assoc operators that pay no attention to changing operators. That might also allow us to treat p5=> as exactly identical to comma. Basically we'd have operators lying about their sym, which implies that they'd have to store a "reallysym" somewhere to have any semantic effect downstream. Still thinking about the ramifications of that, and whether there's some more general idea I'm missing. > The sigils used as operators at List_prefix in STD incl
r25060 - docs/Perl6/Spec src/perl6
Author: lwall Date: 2009-01-27 18:43:18 +0100 (Tue, 27 Jan 2009) New Revision: 25060 Modified: docs/Perl6/Spec/S03-operators.pod src/perl6/STD.pm Log: [STD] more operator hacking inspired by mtnviewmark++ [S03] added comparison-reversion metaoperator Modified: docs/Perl6/Spec/S03-operators.pod === --- docs/Perl6/Spec/S03-operators.pod 2009-01-27 10:11:54 UTC (rev 25059) +++ docs/Perl6/Spec/S03-operators.pod 2009-01-27 17:43:18 UTC (rev 25060) @@ -12,9 +12,9 @@ Maintainer: Larry Wall Date: 8 Mar 2004 - Last Modified: 24 Jan 2009 + Last Modified: 27 Jan 2009 Number: 3 - Version: 149 + Version: 150 =head1 Overview @@ -1472,7 +1472,7 @@ $a < 1 && $b == 2 :carefully does the C<&&> carefully because C<&&> is of -tighter precedence than "loose unary". Use +tighter precedence than "comma". Use $a < 1 && ($b == 2 :carefully) @@ -3400,7 +3400,7 @@ operators yourself. Similarly, the carets that exclude the endpoints on ranges are there by convention only. -In contrast to that, Perl 6 has five standard metaoperators for +In contrast to that, Perl 6 has six standard metaoperators for turning a given existing operator into a related operator that is more powerful (or at least differently powerful). These differ from a mere naming convention in that Perl automatically generates these new @@ -3483,8 +3483,9 @@ =head2 Negated relational operators -Any infix relational operator may be transformed into its negative -by prefixing with C. A couple of these have traditional shortcuts: +Any infix relational operator returning type C may be transformed +into its negative by prefixing with C. A couple of these have +traditional shortcuts: Full form Shortcut - @@ -3506,6 +3507,23 @@ The precedence of any negated operator is the same as the base operator. +Note that logical operators such as C<||> and C<^^> do not return a Bool, +but rather one of the operands. + +=head2 Reversed comparison operators + +Any infix comparison operator returning type C may be transformed into its reversed sense +by prefixing with C<->. + +-cmp +-leg +-<=> + +To avoid confusion with the C<-=> operator, you may not modify +any operator already beginning with C<=>. + +The precedence of any reversed operator is the same as the base operator. + =head2 Hyper operators The Unicode characters C<»> (C<\x[BB]>) and C<«> (C<\x[AB]>) and Modified: src/perl6/STD.pm === --- src/perl6/STD.pm2009-01-27 10:11:54 UTC (rev 25059) +++ src/perl6/STD.pm2009-01-27 17:43:18 UTC (rev 25060) @@ -150,7 +150,7 @@ chars graphs codes bytes say print open close printf sprintf slurp unlink link symlink -elems grep map first reduce sort uniq push reverse take splice +elems grep map first reduce sort min max uniq push reverse take splice lines getc zip each roundrobin caller @@ -233,7 +233,7 @@ constant %junctive_or = (:dba('junctive_or') , :prec, :assoc, :assign); constant %named_unary = (:dba('named_unary') , :prec, :assoc, :uassoc); constant %nonchaining = (:dba('nonchaining') , :prec, :assoc); -constant %chaining= (:dba('chaining'), :prec, :assoc, :bool); +constant %chaining= (:dba('chaining'), :prec, :assoc, :returns); # XXX Bool string, not type constant %tight_and = (:dba('tight_and') , :prec, :assoc, :assign); constant %tight_or= (:dba('tight_or'), :prec, :assoc, :assign); constant %conditional = (:dba('conditional') , :prec, :assoc); @@ -272,7 +272,7 @@ } # end role -class Hyper does PrecOp { +class Transparent does PrecOp { our %o = (:transparent); } # end class @@ -1031,6 +1031,7 @@ } token infixish { +:my $infix; :dba('infix or meta-infix') @@ -1050,7 +1051,7 @@ | { $ = $; $ = $; } -| )> +| ; }> { $ = $.; $ = $.; } ] } @@ -1129,20 +1130,32 @@ token postfix_prefix_meta_operator:sym< » >{ | '>>' } -token infix_prefix_meta_operator:sym ( --> Chaining) { +token infix_prefix_meta_operator:sym ( --> Transparent) { = $; }> [ -|| eq 'chain'}> -|| and $ }> -|| <.panic: "Only boolean infix operators may be negated"> +|| // '') eq 'Bool' }> +|| <.worry: "Only boolean infix operators may be negated"> ] and $¢.panic("Negation of hyper operator not allowed") }> +} +token infix_prefix_meta_operator:sym<-> ( --> Transparent) { + + + = $; }> + + +[ +|| // '') eq 'Order' }> +|| <.worry: "Only comparison infix operators may be negated"> +] + + and $¢.panic("Negation of hyper operator not allowed") }> } method lex1 (Str $s) { @@ -1160,7 +1173,7 @@ } -token infix_circumfix_meta_operat
Re: r25060 - docs/Perl6/Spec src/perl6
On Tue, Jan 27, 2009 at 9:43 AM, wrote: > +=head2 Reversed comparison operators > + > +Any infix comparison operator returning type C may be transformed > into its reversed sense > +by prefixing with C<->. > + > +-cmp > +-leg > +-<=> > + > +To avoid confusion with the C<-=> operator, you may not modify > +any operator already beginning with C<=>. > + > +The precedence of any reversed operator is the same as the base operator. If there are only a handful of operators to which the new meta-operator can be applied, why do it as a meta-operator at all? This could be generalized to allow any infix operator returning a signed type (which would include C) to reverse the sign. In effect, "$x -op $y" would be equivalent to "-($x op $y)". (Which suggests the possibility of a more generalized rule about creating "composite operators" by applying prefix or postfix operators to infix operators in an analogous manner; but that way probably lies madness.) Also, wouldn't the longest-token rule cause C<-=> to take precedence over C<=> prefixed with C<->? Or, in the original definition, the fact that C<=> isn't a comparison operator? -- Jonathan "Dataweaver" Lang
Re: r25060 - docs/Perl6/Spec src/perl6
On Tue, Jan 27, 2009 at 10:59:34AM -0800, Jon Lang wrote: : If there are only a handful of operators to which the new : meta-operator can be applied, why do it as a meta-operator at all? As a metaoperator it automatically extends to user-defined comparison operators, but I admit that's not a strong argument. Mostly I want to encourage the meme that you can use - to reverse a comparison operator, even in spots where the operator is named by strings, such as (potentially) in an OrderingPair, which currently can be written &extract_key => &infix:<-leg> but that might be abbreviate-able to :extract_key<-leg> or some such. That's not a terribly strong argument either, but perhaps they're additive, if not addictive. :) : This could be generalized to allow any infix operator returning a : signed type (which would include C) to reverse the sign. In : effect, "$x -op $y" would be equivalent to "-($x op $y)". (Which : suggests the possibility of a more generalized rule about creating : "composite operators" by applying prefix or postfix operators to infix : operators in an analogous manner; but that way probably lies madness.) Well, even -+ seems a bit mad. And Int/Num don't do Order, since that's an enum subset of Int, not a role. : Also, wouldn't the longest-token rule cause C<-=> to take precedence : over C<=> prefixed with C<->? Or, in the original definition, the : fact that C<=> isn't a comparison operator? It would be a tie, since both operators are the same length. The current tiebreaking rules would make it depend on which was declared first, which may or may not make sense. Arguably autogenerated operators should give way to hardwired ones, much like foo\w* gives way to foobar currently. Larry
Re: r25060 - docs/Perl6/Spec src/perl6
On Tue, Jan 27, 2009 at 11:56:16AM -0800, Larry Wall wrote: : Arguably autogenerated operators should give way to hardwired ones, : much like foo\w* gives way to foobar currently. Though I should point out that this wouldn't help with -=, since it's autogenerated either way, unless you divide the token into literal and wildcard like foo\w*, in which case literal - and meta = wins over meta - and literal =, since wildcardness currently treats the remainder of the token as wild even if there are additional literal components. Larry
Re: spelunking in the meta-ops in STD.pm
On Sun, Jan 18, 2009 at 10:57:26PM -0800, Mark Lentczner wrote: > I was looking through STD.pm at the parsing of metaops. I was exploring > to see if the legal metaops for a given operator could be notated on the > operator chart. What I found was some oddness... Caveat: The actual autogeneration of metaop tokens needs to be refactored somewhat. Currently any constraints are enforced at match-time, which doesn't help trim down the list of possible tokens. The absence of a declarative framework induces various distortions in how the rules are formulated currently. > op= (infix_postfix_meta_operator:sym<=>) > > The internal op is restricted to be not :assoc('chain') and not > :assoc('non')... But, the various precedence groupings have a property, > :assign on them that is never used. Yet, this property seem like just > the thing. To my eye, :assign seems like the right set of operators that > are expected to be used here. The current test is too liberal, allowing > things like ,= and ==>>= (gasp!) Agreed. > !op (infix_prefix_meta_operator:sym) > --- > The internal op is restricted to be :assoc('chain'), or not have a > default :assoc and be :bool. This seems overly defined: The only > operators with :assoc('chain') have :bool. Like above, I think the > internal op should be restricted on the :bool property alone. Changed to :returns now. > [op] (prefix_circumfix_meta_operator.reduce) > > This internal op is restricted to not have :assoc('non') nor be at the > same precedence level as %conditional. That later test strikes me as > strange. The restriction should be not having :assoc('chain') nor > :assoc('non'). There maybe needs to be a restriction on "thunky" macro-operators. > Now - the classes of what can be applied to what, especially considering > other metaops, is a bit tangled: > > >>op -- op can be any >>op, postfix, dotty, privop, or postcircumfix > the later is odd: what could >>(...) mean? > > op<< -- op can be any prefix, a [op], or another < > I suppose these multiply applied ops might be useful? op and op > ? The intent was to restrict any kind of recursion for something that must be recognized by LTM, where recursion means revisiting the same metaop. I'd like all other allowed compositions of metaops, though. However, the LTM is not yet powerful enough to handle that many tokens. > op=, !op, >>op<< -- op can only be a (simple) infix operator > > [op], XopX -- op can an infix, or !op or XopX or >>op<< > or, put another way, any simple or complex infix op, except op= > > I understand why op= and !op have highly restricted internal op sets. > But why should >>op<< be so restricted as well? It means that >><=<< > and >>~~<< are legal, but >>!<=<< and >>!~~<< are not. The intent is to allow these eventually. > And, if the prefix and postfix hyper metaops can be nested... then why > not the infix: + anybody? (Not, mind you, that *I* would > advocate for them, or such exotic beasts as [X>>+<>>>+ are disallowed because you can't use recursive patterns in the LTM if it is to remain in the realm of regular languages. [X>>+< Lastly, the token for [x] (prefix_circumfix_meta_operator.reduce) has an > oddity that it allows an optional trailing << (acutally, only the > Unicode version of that!). I'm not sure why the prefix hyper metaop is > parsed here... especially since the code for token PRE clearly parses > this construction. Again has to do with faking out the LTM pattern generator for now. Should get better later. Larry
Re: r25060 - docs/Perl6/Spec src/perl6
Larry Wall wrote: > Jon Lang wrote: > : If there are only a handful of operators to which the new > : meta-operator can be applied, why do it as a meta-operator at all? > > As a metaoperator it automatically extends to user-defined comparison > operators, but I admit that's not a strong argument. Mostly I want > to encourage the meme that you can use - to reverse a comparison > operator, even in spots where the operator is named by strings, such > as (potentially) in an OrderingPair, which currently can be written > >&extract_key => &infix:<-leg> > > but that might be abbreviate-able to > >:extract_key<-leg> > > or some such. That's not a terribly strong argument either, but > perhaps they're additive, if not addictive. :) So "$a -<=> $b" is equivalent to "$b <=> $a", not "-($a <=> $b)". OK. I'd suggest choosing a better character for the meta-operator (one that conveys the meaning of reversal of order rather than opposite value); but I don't think that there is one. > : Also, wouldn't the longest-token rule cause C<-=> to take precedence > : over C<=> prefixed with C<->? Or, in the original definition, the > : fact that C<=> isn't a comparison operator? > > It would be a tie, since both operators are the same length. I guess I don't understand the longest-token rules, then. I'd expect the parser to be deciding between operator "-=" (a single two-character token) vs. meta-operator "-" (a one-character token) followed by operator "=" (a separate one-character token). Since meta-op "-" is shorter than op "-=", I'd expect op "-=" to win out. -- Jonathan "Dataweaver" Lang
Re: r25060 - docs/Perl6/Spec src/perl6
On Jan 27, 2009, at 12:29 PM, Jon Lang wrote: So "$a -<=> $b" is equivalent to "$b <=> $a", not "-($a <=> $b)". OK. I'd suggest choosing a better character for the meta-operator (one that conveys the meaning of reversal of order rather than opposite value); but I don't think that there is one. There are two I can think of: ~ is used in regex to mean inversion of order as in: '(' ~ ')' which is the same as '(' ')' Though, of course, ~ is the prefix a number of hardwired operators, and they all pertain to strings, so this might be awkward. ^ is used to mean 'compliment' and is the prefix to only six operators (where it means exclusive of start point: ^.. ^..^ ^ff ^ff^ ^fff and ^fff^) So, I could easily see: ~cmp ~<=> ~leg Or, ^cmp ^<=> ^leg If you REALLY want to get creative, you just spell these operators backwards: pmc >=< gel Okay.. forget I said that - MtnViewMark