Operator sleuthing...

2009-01-15 Thread Mark Lentczner
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...

2009-01-18 Thread Mark Lentczner
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

2009-01-18 Thread Mark Lentczner
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]