Operator sleuthing...
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 Some levels have left associativity in STD, but are list in S03. Levels affected: %concatenation %tight_and %tight_or %loose_and %loose_or Oddly, sym<^^> ( --> Tight_or) is forced to :assoc in STD. ?? 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. Conditional level is right in STD, and left in S03. == Added == STD has a new Methodcall operator construction: token privop ( --> Methodcall) { '!' } ?? What is this? STD has postfix:sym. I understand this is the imaginary operator. STD has infix:sym<.=>. I understand this to be the method call assigning form when there is space after the operator. ?? Is this right? STD has <==, ==>, <<==, and ==>> as true operators. S03 groups them as terminators. 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. == Removed == STD is missing sym<\\> at Symbolic_unary level. ?? Did capture cease to be an operator? STD is missing sym at Multiplicative level. ?? I'm assuming this is just an oversight. == Misc == The ff and fff family are at %nonchaining precedence in STD, but at %conditional precedence in S03. STD has infix:sym and infix:sym each declared as tokens twice. I'm assuming this is just some accidental duplication. At Loose_unary, STD has which seems more general than the operator adverbs discussed in S03 at Loose unary precedence. 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. The sigils used as operators at List_prefix in STD include sym<&>. It isn't listed in S03. ?? Should it be included as an operator, or is it senseless as an operator? S03 lists the a number of named listops: all one any none die warn fail item list slice hash These aren't coded expressly in STD, presumably as they are all handled by the generic named listop code. ?? Is there any reason to call them out in a list of operators as S03 does? Or is it just that these named listops happen to be the same as existing symbolic ones and are worth pointing out. The named listops seem to be handled in STD by token term:identifier ( --> Term ) But this is at Term precendence, not List_prefix. ?? Did these move? The ! metaop in STD requires that the op be either chaining or have an associativity (any) and be :bool. But %chaining is the only set of operators that has :bool... ?? Is this just "belt and suspenders" checking, or can that meta op apply to more? Mark Lentczner http://www.ozonehouse.com/mark/ m...@glyphic.com
Method Postfix sleuthing...
Here's some more sleuthing and differences between STD.pm and Synopsis 3: Methodcall precedence operators in STD.pm seem to include this set: .meth - single call .?meth - 0 or 1 call .+meth - 1 or more call .*meth - 0 or more call .=meth - mutating call .:meth - ?? what is this .^meth - meta call !meth - private call .^!meth - private meta call S03 doesn't have the private versions. S03 defines .:prefix as the dotted form of a prefix operator, but that is clearly not what STD.pm parses. ?? What does <.:> mean? Now, meth is really , which can be one of three things: a method name (or variable with such in it) a postfix operator which in this context is just <++>, <-->, and their hyper forms ?? I think I heard that in this context, won't be considered an operator though STD.pm parses it this way for now a postcircumfix while is one of (~) [~] {~} <~> <<~>> «~» S03 doesn't explain that the postcircumfix form can be used with any of the Methodcall operators, it only calls out <.>. STD.pm actually treats differently here - it only takes a method name. ?? Is <.^!> meant to be different in this regard from ? ?? Also, only matches the token privop -- shouldn't <.^!> match that production as well? The expansion for a method name (really ) includes not only the name of the method, but also optionally the arguments, via either '(' ~ ')' form, '.(' ~ ')' form, or ':' invocant marker form. This later one has me stumped: Won't it mean that the ':' as invocant marker will have different precedence depending on if it is preceded by an explicit dotted method call vs. a computed expression... I'm not sure I can think of a case that the parses would in fact be different, but why the two different ways to parse this use of <:>? - mark
spelunking in the meta-ops in STD.pm
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... 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!) !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. [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'). 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 >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. 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>>+< 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. - Mark
small patch to STD.pm
This fixes a typo and enables X>>+< X | X -| X +| X ] = $; }>
three little operator questions
I've got three small operator questions before the new table of the operators is done: 1) Is C no longer an operator? It is still listed in S03, but STD.pm doesn't parse it. 2) Is C<\> no longer an operator? S03 lists it as a symbolic unary, but STD.pm doesn't parse it that way. 3) Should C<&> be considered a contextualizer list prefix operator like the other sigils? S03 doesn't list this one, but STD.pm will parse it that way. I suspect it is not listed because unlike the others, it makes no sense to contextualize a list of values as a routine. I'd be grateful for anyone who wants to take a stab at answering these! - MtnViewMark
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
Re: slaughter of the LTM metatokens
[STD, S03] slaughter of the LTM metatokens This cleans up the metaop scene quite a bit. Bravo! I went through STD.pm with a fine tooth comb again, to extract what I'd say about which operators were allowed to be meta'd by each given metaop: (The notation "foo --> bar" means, takes an operator of type foo and makes an operator of type bar) op= infix --> infix op can't be :assoc op must be :assign ** The first test is excessive: There are no non-associative operators that have the :assign property. Hence, testing for :assign should be enough. Besides, I'm not sure what about this metaop should require non-associativity from its internal operator. !op infix --> infix op must not start with '!' op must return 'bool', these are the chaining ops and % or op can be '=' ** Declaring that infix:sym<%> is :returns just so this works seems a bit ugly to me. Why not simply define infix:sym? ** Why is the test for .text eq '=' in there? infix:sym is already defined. Rop infix --> infix op must not start with '=' ** The restriction seems unneeded and has odd side-effects. It is true that there is no reason to all R== R=:= or R===, since they are the same as their non-reversed selves. But the restriction means that: Rp5=> is an operator, but R=> is not R:= is an operator, but R= is not In the first case, I'd imagine I'd want them both to be. In the second, I imagine I'd want neither -- but not sure I care all that much. Xop infix --> infix op<< prefix --> prefix >>op postfix --> postfix >>op<< infix --> infix ++ No restrictions here... Woot! [op]infix --> prefix op can't be :assoc('non') op can't have same precedence as %conditional ** The second test should probably be can't be :assoc('chain') ** Really, the restriction on the operator is that it has to return a type that is compatible with being on its left side for a given type on its right. There are things that are currently allowed here, like [:=] or [=>] that may not make much sense. Perhaps there should be :reduce like there is :assign to indicate which are - MtnViewMark
Normalization of metaops
The concept of which metaops can apply to which other ops is looking pretty clear. The goal, as I understand it from Larry, is that while in general, metaops should be allowed, we want to disallow them where they either make no sense, or are very unlikely to be what the programmer thought they were doing. In addition, it seems to me that since metaops should be applicable to user created ops, the particular tests the parser performs must be well defined because users will be annotating their operators to get them to have the right metaop applicability. I propose the following: Rop infix --> infix Xop infix --> infix op<< prefix --> prefix >>op postfix --> postfix >>op<< infix --> infix - the inner op should be "value" like, that is things like ==> and .= and ^ff^ don't ever really make sense here - these should test for :value [op]infix --> prefix op= infix --> infix - the inner op needs to be associative, and needs to produce a value of similar type to its arguments - these should test for :iso - [op] has an explicit provision for chained operators - so [op] should support :assoc(chain) if the op is :value !op infix --> infix - the inner op must return a value that makes sense when used in a boolean context, and hence when negated - this should test for :bool The current levels would then have: %methodcall %autoincrement :value %exponentiation :value :iso %symbolic_unary :value %multiplicative :value :iso %additive:value :iso %replication :value :iso %concatenation :value :iso %junctive_and:value :iso %junctive_or :value :iso %named_unary :value %nonchaining :value %chaining:value :bool %tight_and :value :iso %tight_or:value :iso %conditional %item_assignment %loose_unary :value %comma %list_infix :value :iso %list_assignment %list_prefix %loose_and :value :iso %loose_or:value :iso %sequencer Two exceptions to these lists: sym<,> gets :value and :iso sym<%> gets :bool as well I'm not so happy with these names, :boolish? :simple? I just don't know... This does explicitly remove a few classes of operator from being used in hyper, reverse and cross: Such things as the sequencer ops, assignment, and method call. Testing with the current form of STD.pm (r25127), not all of those things parse anyway. I almost have a patch against STD.pm ready to go that implements this and passes teststd... What do you think? Post it here? Check it in? This is a goofy idea, drop it? - MtnViewMark
Periodic Table of the Operators, version 3
Friends - Just a note to let you know that the third version of the Periodic Table of the Operators is complete: http://www.ozonehouse.com/mark/periodic/ Thanks again to all those who helped me dive deep into perl6. - MtnViewMark Mark Lentczner http://www.ozonehouse.com/mark/ m...@glyphic.com
Re: On Junctions
What I see here is that there is a tendency to want to think about, and operate on, the eigenstates as a Set, but this seems to destroy the "single value" impersonation of the Junction. Further, if one ever calls .!eigenstates() on a Junction, then you have really bollox'd your code up, as then this code fails if the value you thought was a Junction happens to be, actually, just a single value! (Unless .!eigenstates() is defined on Object, and returns a Set of self...) I think what is needed is a "single value" threshing function, which can be applied to, well, single values. Such a function would take a value and a predicate, and if the predicate applied to the value is true, returns the value, else it returns... nothing. If such a function were applied to a Junction, then the result would be a Junction of just those those eigenstates that "passed" this function. The "nothings" would not end up contributing to the Junction. Now, I'm not sure I know how to return "nothing" in Perl6, but I'll guess that undef can serve the purpose, since I can't think of a useful use of undef as part of a Junction. sub suchthat(Any $v, &predicate) { predicate($v) ?? $v !! undef } So now: $a = 1|2|3|4|5 say suchthat($a, odd) >>> 1|3|5 $b = 1&2&3&4&5 say suchthat($a, odd) >>> 1&3&5 And in the poker example: @p = 1|11, 2, 1|11; @d = 1|11, 3, 1|11; $pv = suchthat([+] @p, {$_ <= 21}) $dv = suchthat([+] @d, {$_ <= 21}) if $pv and (!$dv or $pv > $dv) { say 'p wins!' }; - MtnViewMark Mark Lentczner http://www.ozonehouse.com/mark/ m...@glyphic.com
Periodic Table of the Operators
All - Awhile back, I saw Larry Wall give a short talk about the current design of Perl 6. At some point he put up a list of all the operators - well over a hundred of them! I had a sudden inspiration, but it took a few months to get around to drawing it... http://www.ozonehouse.com/mark/blog/code/PeriodicTable.html - Mark Mark Lentczner http://www.ozonehouse.com/mark/ markl (at) glyphic (dot) com
Re: Periodic Table of the Operators
LOL! That's fantastic! We _must_ put it on dev.perl.org. Thank you. You are welcome to put it on dev.perl.org. I can't help myself but to correct it, though :-) Please do. It was clear that many discussions happened after the TAKE 6 list, my primary reference. I will be happy to update it in a few days. What do the numbers in the upper-right mean? Relative precedence: See the key in the lower left corner. - Mark
Re: Periodic Table of the Operators
Thanks for all the comments. I started this thing as a goof, but I can already see that it will serve dual purposes. Presenting information in such a form can lead people to further insights and questions. Deborah Pickett's comments in this thread are an example. (For some real inspiring examples, see Edward Tufte's "Visual Explanations".) To answer some comments: What's periodic about it? and We hope it will be periodically updated. :) I am preparing a second edition incorporating the corrections. While I don't anticipate updating the chart this frequently in general, I would like it to be mostly accurate at the start. Thereafter I'd be happy to update it when Michael Lazzaro publishes the next version of the operator list. (Perhaps he can give me a heads up and we'll strive for a simultaneous release!) I'd like to have this on a big poster, once it's up to date. Perhaps you can set up a Cafepress store for this? I will just as soon as the second edition is complete. a few other words like 'termplars' don't make much sense to me. The group names are, admittedly, flights of fancy. Not all of them make sense, some are deliberate jokes, and many just sound funny to me. "Declars" seems to be a term in use 'round these parts. Some of the items in Michael's list were named "terms". The "Templars" were crusading monks in the Middle Ages. And so I arrived at "Termplars". Then "Bazaars" just came naturally. You weren't expecting any logic to this, were you? - Mark Mark Lentczner http://www.ozonehouse.com/mark/ [EMAIL PROTECTED]
Predicting Operators
Uri Guttman wrote: are you going to predict any new operators based on missing boxes as mendeleev did? :) Funny you should ask! It is clear that there is a missing "list concatenate" operator, and that its spelling should be ~~. Alas, that is already taken by "smart match". On the other hand, perhaps comma fills this role - though I couldn't find my way through the discussion on comma to know where it now stands. I was going to predict a quasi-operator for an alternate form of qw/.../, but seems I just missed the thread where «...» was introduced for that purpose. It will be corrected in the next version of the chart. - Mark Mark Lentczner http://www.ozonehouse.com/mark/ [EMAIL PROTECTED]
Re: Periodic Table of the Operators
Not to beat a dead horse, but I've updated the Periodic table with almost all the changes that people here sent me, as well as reading a few more threads and references. This will be the last update for some time. I'll be uploading a version to cafepress so people can get posters, tee-shirts and mouse pads since so many people have asked for it. Check back on the chart's blog page ( http://www.ozonehouse.com/mark/blog/code/PeriodicTable.html ) in a few days for the details. (I won't post that info here - I don't mean to clog this mailing list with my frivolity.) Lastly, in Apocalypse 3, Larry says: "Operator precedence should be as simple as possible. Perl's precedence table currently has 24 levels in it. This might or might not be too many. We could probably reduce it to about 18 levels, if we abandon strict C compatibility of the C-like operators." The chart currently has 29 precedence levels (from left to right in the chart) - which was based on various writings about the operators, inferences drawn from examples (such as 1|2|3 + 4), any my own guesses. I can't wait to see how this gets down to 18! Or even back to Perl 5's 24... - Mark
Re: Precedence table update
On Aug 14, 2004, at 12:17 AM, Larry Wall wrote: Here's the current precedence table as I see it, based mostly on what the, er, cabal came up with after the Perl conference. Okay, time to get out the quill and parchment and start work on revising the Periodic Table of the Operators - Mark "hope the tallow candle lasts 'till dawn" Lentczner Mark Lentczner http://www.ozonehouse.com/mark/ [EMAIL PROTECTED]
Re: Precedence table update
I apologize if the answers to these questions are in the list somewhere, but I can't find any archive of this list that lets me search for things like ^..^ or ?&= ! In reviewing the operator precedence table update, I have some questions: 1) What is unary ** ? I assume it is prefix. 2) Did the boolean logics (?&, ?|. ?^ and their assignment forms) get dropped? 3) Am I right in assuming the file tests (-x, -r, etc...) are considered named unaries? 4) Am I right in assuming ^.. , ..^ and ^..^ are open ended versions of .. ? 5) Did ... get dropped? 6) What is the precedence of postfix () , {} and [] ? They surely are tighter than the list ops: print @foo[4], @bar[$i]; The [4] doesn't close the virtual parenthesis of print, so [] must be tighter than that. Is the whole construct @foo[4] considered a term and hence the postfix [] is even tighter than every operator listed? (Though I would consider it a postfix operator.) 7) The operator .+foo is listed twice on the method postfix line. Did a real operator accidentally get missed? 8) What is .«» ? 9) What is "{} as control block" mean? As if after a for or if? Does this really count as an operator? Similarly, the statement modifiers are in the same boat. Does these things act as operators or are then in the realm of the recursive descent grammar? - Mark Mark Lentczner http://www.ozonehouse.com/mark/ [EMAIL PROTECTED]