From: Jim Weirich Date: 2004-10-09T07:39:19+09:00 Subject: Re: ANN: Free-form-operators patch Charles Hixson said: > This is one place that I don't think Eiffel got things quite right. > Precedence should be defineable, not necessarily higher than all > built-in operators. If one is defining a cross-product, e.g., one > doesn't necessarily want it to be of higher precedence than whatever one > is using to define the literal representation of the matrix. And > ordinary arithmetic might be of even higher precedence. E.G.: > > | .< 1 + 3, 5 * 2, 6 / 3 >. .. .. | .*. M Hmmmm ... I'm not sure that the .<, >. and | are technically operators (certainly not binary operators). They seem to be merely syntactical markers. The problem with definable precedence is that precedence is a compile time operation and the selection of the operator implementation is a run time thing. Consider ... x @a y @b z (note: Syntax is Eiffel style syntax, so @a and @b are operators. Ignore for the moment that this conflicts with Ruby syntax for instance variables and go with me here). Should this be parsed ((x @a y) @b z) or (x @a (y @b z))? Operators are generally transformed into method calls, e.g. (x @a y) => (x.@a(y)). So we look at the runtime class of x to find the operator and determine the precedence. Unfortunately, at the time the expression is compiled the runtime class of x isn't available! Indeed, x may have a different class every time the expression is executed. So, that leaves us two choices: (1) Reparse the expression everytime it is executed, or (2) globally define the precedence of an operator across all classes. (1) seems a bit too dynamic for my taste, and (2) is troublesome when you have more than one class defining the operator. Given that, I wouldn't mind user defined operators in Ruby under the following conditions... (A) The operators are visually distinctive. In Eiffel, all user defined operators must begin with a limited set of symbols (@, #, &, and | IIRC). After the initial symbol, any printable, non-space character is allowed. So @in, @cross, &and, #..# are all recognized as operators according to the Eiffel rules. (B) Fixed precedence. User defined unary operators should have the same precedence as other unary operators. User defined Binary operators should be the same as the highest precedence binary operator under the unary operators. Point A means that I don't have to parse a random string of symbols in my head and decide whether it is legal Ruby syntax or user defined operators (or Beetle Baily swearing). Ruby's problem is that all the punctuation characters are already used for other purposes, it would be difficult to set aside yet another character for this purpose. Perhaps something like @op@ can be used. Regarding the matrix example, I find it less than compiling, especially when existing Ruby can be used to get something quite readable ... Matrix [ [ 1 + 3, 5 * 2, 6 / 3 ], [ n21, n22, n23 ], [ n31, n32, n33 ] ].cross M -- -- Jim Weirich jim@weirichhouse.org http://onestepback.org ----------------------------------------------------------------- "Beware of bugs in the above code; I have only proved it correct, not tried it." -- Donald Knuth (in a memo to Peter van Emde Boas)