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

Andrew Dalke dalke@dalkescientific....
Mon Aug 18 17:32:53 CDT 2008

On Aug 18, 2008, at 11:22 PM, Christian Heimes wrote:
> Example syntax (rough idea):
>>>> type(1.0)
> <type 'float'>
>>>> with float as from decimal import Decimal
>>>> type(1.0)
> <class 'decimal.Decimal'>

When would this "with float ... " considered valid?

For example, could I define things before asking
for a redefinition?

def f(a=1.0):
   print a+2.0

with float as from decimal import Decimal

In this case would the 1.0 be a float and
the 2.0 be a decimal?  Or would they both
be floats?

Would the following be allowed?

def f(x):
   with float as from decimal import Decimal
   return 1.0

and would that affect things in the function
scope or the entire module scope?  What if
I stuck in a "global int" in that function?

What about the following, which uses gmpy
if it's available, otherwise uses decimal.

   import gmpy
   # Pretend there's a bug in some versions
   # of the library, and don't use gmpy
   # if that bug is present.
   if gmpy.mpf("3.0") == 3.0:
     with float as from gmpy import gmpy.mpf
     # work around the hypothetical bug
     raise ImportError
except ImportError:
   with float as from decimal import Decimal

Hmm.. though this could be handled with
some support library, making the result be

with float as support_library.the_float_to_use

The simplest is that if that statement type appears
in the module at all then int/float/complex/string/
dict/list creation goes through a module function,
and the statement simply redefines that function.

This would slow down the entire module, but if
it's what the developer wanted...  But I really
don't like the unexpected slow down and I think
that will be a constant gotcha, with people
rewriting code from

   sum(1 for x in data if x > 100)

into something like

   one = 1
   one_hundred = 100
   # or possibly: one = __builtin__.int("1")
   sum(one for x in data if x > one_hundred)

in order to eek out performance by not
calling new_int("1") so many times.

Also, in the use-case for SymPy it means that
all modules would start with:

   with float as from SymPy import float
   with int as from SymPy import int
   with complex as from SymPy import complex

which makes for tedious boilerplate.  Better might be

   with (float, int, complex) as from SymPy import (float, int, complex)

If there's support for

   with str as ....

then how does one create an actual Python string
in a module where string is redefined?  For example,

   with str as from MyModule import string

wouldn't necessarily work because "/path/to" gets
converted to something else, and that something else
might not be convertible back to a Python string.

Blowing my own horn again, I wrote python4ply
precisely to support experimentation like this.
We can discuss pros and cons but with a change
this extensive it's hard to judge the usefulness
with without some real-world experience.  And I
didn't want to wait for PyPy. ;)


More information about the Numpy-discussion mailing list