On Thu, Oct 30, 2008 at 05:41:11PM +0100, Moritz Lenz wrote: : Xiao Yafeng wrote: : > Off the top of one's head, since there is no particular difference between : > an operator and a function, can I see a function as a operator: : > : > (1, 2, 3, 4) >>elems<<(2, 3, 4, 5) #(2, 2, 2, 2) : > (1, 2, 3, 4) >>shift<<(2, 3, 4, 5) #(2, 3, 4, 5) : : But remember that operators come with an associativity: : : $a / $b / $c == ($a / $b) / $c # left associative : $a ** $b ** $c == $a ** ($b ** $c) # right associative : : When you make a function into an operator, you need a good syntax for : defining the associativity of the new pseudo-operator. : : Also note that shift(1, 2) doesn't work, because it gets a list, not an : array, and lists are immutable.
Note also that by conflating unary with binary operators you make ambiguities. By the above definition, >>+<< might be expected to return 2,2,2...*, whereas the existing >>+<< returns the pairwise sums. : > Moreover, can I see a subroutine as a operator: : > : > (1, 2, 3, 4) >>{$a>$b??$a!!$b}<<(2, 3, 4, 5) #(2, 3, 4, 5) : : Every operator is accessible as a function (or a macro) already, for : example the operator in 2 + 3 is known as &infix:<+>. And note that >>{ ... }<< cannot be parsed as a single token without infinitely large token tables. We place some fairly severe restrictions on what can occur within a metatoken for this reason: no embedded spaces, no recursive metaoperators, etc. So putting a closure in the middle would have to be parsed as a >>{ token followed by some code followed by a }<< token. Alternately, we'd have to split out metaoperators as separate tokens, and that is likely to violate the principle of Least Astonishment in some cases, since it would mean we could not have both an infix:<X> and infix_circumfix_meta_operator:<X X>. As it currently stands, by relying on LTM (longest-token matching) we can express all of: @a X @b @a X*X @b [X*X] [EMAIL PROTECTED], [EMAIL PROTECTED] and we know that [ X ... must be the start of an array composer, where X is a function name. The only way I could see to relax this would be to require whitespace around *all* infix operators, which seems like a plan that would inspire a truly massive quantity of righteous grumbling. And it still wouldn't let you write: X{ $^a * $^b }X as a single infix since that has whitespace in it. You'd again have to define X{ and }X to be parsed as a special infix operator, just as ??!! is handled in STD currently. Similar considerations apply for reduce operators that contain whitespace. At some point you just give up on composable token syntax and make people call reduce() or cross() or hyper(). And basically, while an arbitrarily complicated closure can be considered an individual term, it cannot be considered an individual token. Token composition must be restricted to whatever can be recognized by regular languages, by my current understanding of LTM, and of how much complexity normal users will put up with. : The ternary is a rather ugly case, I guess it's called &infix:<?? : !!>($condition, $true, $false), and it's short-circuiting, so it must be : a macro rather than normal function. And it would have to be implemented specially in any case. The STD grammar parses the true case as part of the infix operator, so the operator officially has only a condition and a false argument! But it's possible there could be a built-in function: if($condition, {$true}, {$false}) The lazy short-circuit nature would be explicit there via the closure args. I suppose one could specially implement a statement_control:<if> macro though, as in the ??!! case. Similar considerations would apply for functional/macro forms of && and ||. Larry