[Numpy-discussion] global overloading of 1+1 -> MyClass(1, 1)

Ondrej Certik ondrej at certik.cz
Mon Aug 18 17:17:26 EDT 2008


On Mon, Aug 18, 2008 at 10:45 PM, Andrew Dalke
<dalke at dalkescientific.com> wrote:
> On Aug 18, 2008, at 10:01 PM, Ondrej Certik wrote:
>
>> with Andrew permission, I am starting a new thread, where our
>> discussion is ontopic. :)
>
> Though I want to point out that without specific proposals
> of how the implementation might look, this thread will
> not go anywhere as it will be too distant from usable code.
>
> I sent examples to show how such a system might look, as
> the basis for getting a feel if it was practical.  I do
> not think my examples are practical, but they were meant
> as an example of how such a proposal might look.
>
> Since I know that the Python implementation will not change
> to support per-module or per-scope redefinitions for "1+2"
> and builtin object constructors, the only feasible mechanism
> is through some sort of alternate grammar that compiles to
> either Python or directly to the Python virtual machine.
>
> One such was is through import hooks.
>
>> Yes, this is a mess, this is just like preparsing. Well, not like --
>> this is preparsing.
>>
>
> It's not preparsing.  It's parsing.  There's no pre about it.
> It's not a macro language.  My ply4python tutorial compiles
> various Python-like languages to the Python virtual machine
> bytecode.
>
>
>> I mean what is the difference between [1] and [2]?
>
> I want to see how you would extend Python to support such
> a mechanism before I worried about how to interpret it.
>
> Or in other words, the difference between [1] and [2]
> is that [2] can be fully evaluated through simple static
> analysis, while [1] cannot.
>
> BTW, this is unexpected.  Python does constant folding
> of that expression, but only with specific settings.
>
>  >>> import dis
>  >>> def f():
> ...   print 1/2*3/4
> ...
>  >>> dis.dis(f)
>   2           0 LOAD_CONST               1 (1)
>               3 LOAD_CONST               2 (2)
>               6 BINARY_DIVIDE
>               7 LOAD_CONST               3 (3)
>              10 BINARY_MULTIPLY
>              11 LOAD_CONST               4 (4)
>              14 BINARY_DIVIDE
>              15 PRINT_ITEM
>              16 PRINT_NEWLINE
>              17 LOAD_CONST               0 (None)
>              20 RETURN_VALUE
>  >>>
>  >>> from __future__ import division
>  >>> def f():
> ...   print 1/2*3/4
> ...
>  >>> dis.dis(f)
>   2           0 LOAD_CONST               7 (0.375)
>               3 PRINT_ITEM
>               4 PRINT_NEWLINE
>               5 LOAD_CONST               0 (None)
>               8 RETURN_VALUE
>  >>>
>
>
>
> The only way I can see to do what you want requires
> multimethods, which don't currently exist in Python
> except as third-party extensions.  The one I know about,
> from Philip J. Eby, works on a global-level, not module
> level, because of how registration happens, so it does
> not support what you would like.

One way to fix that would be to use the trick that Travis Oliphant
told me at EuroSciPy -- hack the while (or if) statement and do the
preparsing in there.

So clearly the language seems to support that, so imho it could be
made more official. E.g. you would write:

while sympy:
    e = 1/2

and "e" would be Integer(1)/Integer(2).

But anyway, it's kind of hackish and I don't know what to say more
about it, besides what I already said. The problem is that I don't
have time to dig more into Python internals and without it it seems I
cannot provide more constructive answer besides I want some way to
avoid Python reducing 1/2 to 0.

Generally I believe that if there is will, it can always be done. :)

Ondrej



More information about the NumPy-Discussion mailing list