On Thu, Jan 29, 2009 at 10:58:18PM -0800, Mark Lentczner wrote: >> [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<non> > 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.
The purpose of the 'non' test is to give the user a better error message than "You can't do that". The reason that non-associatives don't work for assignment ops is that non-associatives typically return a different type than they take as arguments, and so an assignment op based on a non-associative is going to be changing the type of the target strangely, which seems more likely to be a braino than intended. > !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<Bool> just so this works > seems a bit ugly to me. Why not simply define infix:sym<!%>? Well, we may open that up a bit more, as discussed on irc, and not tie it to official Bool return in any case, since in Perl anything may be used as a boolean. The problem with defining an override including the metaop is that, 1), you don't get the automatic benefit of whatever autogen the metaop invokes, and 2), it doesn't work right if you have, say, a user-defined %% operator. > ** Why is the test for .text eq '=' in there? infix:sym<!=> is already > defined. Yes, but the != rule currently requires whitespace after it, which is suboptimal. If we don't require the whitespace, then it misparses !== and !===, because the LTM will call != before it calls !. So most of these special forms need to move into the metaoperator and check the result after trying for a compile infix, as the '=' is doing. I had to work around problems with !~ and +< and ~< as well, which caused ambiguity with !~~, >>+<<, and >>~<<. There's a penalty for not running all metaops through LTM, which is that all the strange forms need to be recognized by the metaop itself. Haven't quite got that all straight yet in STD. > 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. Ah, that was a fossil from when we were disallowing -= and - was allowed only on comparisons. It makes no sense since - change to R and was generalized to argument reversal. > [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 Or the veto forms of that, as we discussed on irc. Anyway, not really trying to restrict the freedom of people to shoot themselves in the foot so much as just hoping to be able to warn them why their foot is about to go missing with a reasonable error message when something is obviously misthought. And I obviously ought to go to bed before I write much more stream-of-unconsciousness prose... Larry