Well, I finally ran into a Python Unicode problem, sort of
BartC
bc at freeuk.com
Mon Jul 4 06:05:03 EDT 2016
On 04/07/2016 03:30, Steven D'Aprano wrote:
> On Mon, 4 Jul 2016 10:17 am, BartC wrote:
>
>> On 04/07/2016 01:00, Lawrence D’Oliveiro wrote:
>>> On Monday, July 4, 2016 at 11:47:26 AM UTC+12, eryk sun wrote:
>>>> Python lacks a mechanism to add user-defined operators. (R has this
>>>> capability.) Maybe this feature could be added.
>>>
>>> That would be neat. But remember, you would have to define the operator
>>> precedence as well. So you could no longer use a recursive-descent
>>> parser.
>>
>> That wouldn't be a problem provided the new operator symbol and its
>> precedence is known at a compile time, and defined before use.
>
> You're still having problems with the whole Python-as-a-dynamic-language
> thing, aren't you? :-)
Well it isn't completely dynamic, not unless code only exists as a eval
or exec argument string (and even there, any changes will only be seen
on calling eval or exec again on the same string).
Most Pythons seem to pre-compile code before executing the result. That
pre-compilation requires that operators and precedences are known in
advance and the resulting instructions are then hard-coded before execution.
> In full generality, you would want to be able to define unary prefix, unary
> suffix and binary infix operators, and set their precedence and whether
> they associate to the left or the right. That's probably a bit much to
> expect.
No, that's all possible. Maybe that's even how some language
implementations work, defining all the set of standard operators at the
start.
> But if we limit ourselves to the boring case of binary infix operators of a
> single precedence and associtivity, there's a simple approach: the parser
> can allow any unicode code point of category "Sm" as a legal operator, e.g.
> x ∇ y. Pre-defined operators like + - * etc continue to call the same
> dunder methods they already do, but anything else tries calling:
>
> x.__oper__('∇', y)
> y.__roper__('∇', x)
>
> and if neither of those exist and return a result other than NotImplemented,
> then finally raise a runtime TypeError('undefined operator ∇').
A simpler approach is to treat user-defined operators as aliases for
functions:
def myadd(a,b):
return a+b
operator ∇:
(myadd,2,+3) # map to myadd, 2 operands, prio 3, LTR
x = y ∇ z
is then equivalent to:
x = myadd(y,z)
However you will usually want to be able overload the same operator for
different operand types. That means mapping the operator to one of
several methods. Maybe even allowing the operator to have either one or
two operands.
Trickier but still doable I think.
--
Bartc
More information about the Python-list
mailing list