Re: [Cython] Bindings performance issue

2011-06-02 Thread Vitja Makarov
2011/6/2 Robert Bradshaw :
> On Wed, Jun 1, 2011 at 7:26 AM, Vitja Makarov  wrote:
>> 2011/6/1 mark florisson :
>>> On 31 May 2011 20:25, Vitja Makarov  wrote:
 Hi!

 Is bindings performance issue valuable?

 $ cat bindbench.pyx
 def wo_bindings():
    pass

 def outer():
    def inner():
        pass
    return inner
 with_bindings = outer()

 $ python
>>> import timeit
>>> timeit.repeat('with_bindings()', setup='from bindbench import 
>>> wo_bindings, with_bindings', repeat=1, number=1)
 [6.169871807098389]
>>> timeit.repeat('wo_bindings()', setup='from bindbench import 
>>> wo_bindings, with_bindings', repeat=1, number=1)
 [4.609416961669922]

 PyCBindings makes it 1.3 (difference is about 15ns on my laptop) times
 slower for CPython interpreter execution.
 As CPython has some optimizations for CFunctions and PyCFunctions.

 Does it make sense for us? Or we can easily switch to bindings?

 --
 vitja.
 ___
 cython-devel mailing list
 cython-devel@python.org
 http://mail.python.org/mailman/listinfo/cython-devel

>>>
>>> I think switching should be fine, if you'd desperately need the speed
>>> you'd be calling c(p)def functions from Cython. In fact, when the
>>> fused cfunction will be ready it will be even slightly slower, as it
>>> overrides the tp_call. But perhaps that should really be made into a
>>> subclass...
>
> Yes, this should be a subclass, slowing all calls down is a bad idea.
>
>>> Anyway, would you use these for Python classes and module-level def
>>> functions (and closures) only, or would you also use them in extension
>>> classes? Because I found at least a bit of problem there, as extension
>>> class methods get 'self' passed as the first argument to the C
>>> function (as PyCFunctionObject.m_self), whereas methods in Python
>>> classes get 'self' passed in the args tuple (and the m_self is
>>> unused).
>>>
>>
>> Recently I've found a problem with static methods (__new__ for
>> example) of inner classes (classes created inside a function, for
>> instance)
>> I think binding version should be used for all regular def functions
>> (defs, staticmethods, classmethods and so on).
>
> +1 to moving that way. (Well, static and class methods bind
> differently, right?)
>
>> I also think that it's better to rename binding_PyCFunction_Type to
>> something like CyFunctionType and make it more like PyFunction.
>
> +1
>
> Is there any advantage to the method descriptors (other than that
> they're easier for a human to write?)

Initially bindings was written to support bound class methods (am I right?)
So when we use it for regular functions 'binding' in the name doesn't
reflect its purpose.

One the other hand it's much more easy to write manually.

About staticmethods: I think that CyFunction type should handle it as well
because staticmethods can have custom attributes and act just like
normal def one.

The difference is insde descr_get it should return bound method for
normal and self for staticmethods.

Here I've tried to support staticmethods inside bindings type:
https://github.com/vitek/cython/commit/c0725ab340a8173d8e6724c62be3a135df58980e

>
> I think that small speed regression for better compatibility is OK if
> we add a directive to not create binding functions. (It'd be nice if
> we could work around it, but that's hard as CPython has special
> hooks...) The bigger issue is that the binding behavior is backwards
> incompatible, and perhaps in a subtle way. Perhaps we need to have a
> phase where all currently non-binding functions that will become
> binding functions will raise an error (or at least a warning) to wean
> people off of the old behavior before making a switch.
>

Is the difference so significant?

-- 
vitja.
___
cython-devel mailing list
cython-devel@python.org
http://mail.python.org/mailman/listinfo/cython-devel


Re: [Cython] Bindings performance issue

2011-06-02 Thread Robert Bradshaw
On Thu, Jun 2, 2011 at 1:30 AM, Vitja Makarov  wrote:
> 2011/6/2 Robert Bradshaw :
>> On Wed, Jun 1, 2011 at 7:26 AM, Vitja Makarov  
>> wrote:
>>> 2011/6/1 mark florisson :
 On 31 May 2011 20:25, Vitja Makarov  wrote:
> Hi!
>
> Is bindings performance issue valuable?
>
> $ cat bindbench.pyx
> def wo_bindings():
>    pass
>
> def outer():
>    def inner():
>        pass
>    return inner
> with_bindings = outer()
>
> $ python
 import timeit
 timeit.repeat('with_bindings()', setup='from bindbench import 
 wo_bindings, with_bindings', repeat=1, number=1)
> [6.169871807098389]
 timeit.repeat('wo_bindings()', setup='from bindbench import 
 wo_bindings, with_bindings', repeat=1, number=1)
> [4.609416961669922]
>
> PyCBindings makes it 1.3 (difference is about 15ns on my laptop) times
> slower for CPython interpreter execution.
> As CPython has some optimizations for CFunctions and PyCFunctions.
>
> Does it make sense for us? Or we can easily switch to bindings?
>
> --
> vitja.
> ___
> cython-devel mailing list
> cython-devel@python.org
> http://mail.python.org/mailman/listinfo/cython-devel
>

 I think switching should be fine, if you'd desperately need the speed
 you'd be calling c(p)def functions from Cython. In fact, when the
 fused cfunction will be ready it will be even slightly slower, as it
 overrides the tp_call. But perhaps that should really be made into a
 subclass...
>>
>> Yes, this should be a subclass, slowing all calls down is a bad idea.
>>
 Anyway, would you use these for Python classes and module-level def
 functions (and closures) only, or would you also use them in extension
 classes? Because I found at least a bit of problem there, as extension
 class methods get 'self' passed as the first argument to the C
 function (as PyCFunctionObject.m_self), whereas methods in Python
 classes get 'self' passed in the args tuple (and the m_self is
 unused).

>>>
>>> Recently I've found a problem with static methods (__new__ for
>>> example) of inner classes (classes created inside a function, for
>>> instance)
>>> I think binding version should be used for all regular def functions
>>> (defs, staticmethods, classmethods and so on).
>>
>> +1 to moving that way. (Well, static and class methods bind
>> differently, right?)
>>
>>> I also think that it's better to rename binding_PyCFunction_Type to
>>> something like CyFunctionType and make it more like PyFunction.
>>
>> +1
>>
>> Is there any advantage to the method descriptors (other than that
>> they're easier for a human to write?)
>
> Initially bindings was written to support bound class methods (am I right?)
> So when we use it for regular functions 'binding' in the name doesn't
> reflect its purpose.

There's three kinds of functions we create: PyCFunctions, binding
PyCFunctions, and extension class methods (via descriptors). I was
asking about the latter.

As for the first two, it reflects the difference in behavior. If I
take the function and assign it to a class, it will bind as a method
when I go to look it up. This is arguably the biggest difference
between built-in functions and Python functions.

> One the other hand it's much more easy to write manually.
>
> About staticmethods: I think that CyFunction type should handle it as well
> because staticmethods can have custom attributes and act just like
> normal def one.
>
> The difference is insde descr_get it should return bound method for
> normal and self for staticmethods.

Yep. Does that merit a new class, or a flag that's checked on every
function invocation (false 99.9% of the time)?

> Here I've tried to support staticmethods inside bindings type:
> https://github.com/vitek/cython/commit/c0725ab340a8173d8e6724c62be3a135df58980e
>
>>
>> I think that small speed regression for better compatibility is OK if
>> we add a directive to not create binding functions. (It'd be nice if
>> we could work around it, but that's hard as CPython has special
>> hooks...) The bigger issue is that the binding behavior is backwards
>> incompatible, and perhaps in a subtle way. Perhaps we need to have a
>> phase where all currently non-binding functions that will become
>> binding functions will raise an error (or at least a warning) to wean
>> people off of the old behavior before making a switch.
>>
>
> Is the difference so significant?

If anyone is assigning a Cython function to an object and then using
it they're counting on the current non-binding behavior, and it will
break. The speed is probably a lesser issue, which is what benchmarks
are for.

- Robert
___
cython-devel mailing list
cython-devel@python.org
http://mail.python.org/mailman/listinfo/cython-devel


[Cython] Fused types syntax

2011-06-02 Thread Robert Bradshaw
In looking at merging fused types, it's time to nail down the syntax.
The current implementation is

ctypedef cython.fused_type(list, dict, object) fused_t

This requires an addition to the grammer to allow the "call" syntax in
a type declaration, as well as special casing to make it allowed only
in a typedef. What about

cython.fused_type[list, dict, object].

One advantage is that indexing is already valid in type declarations,
and its the typical syntax for parameterized types. Thoughts? Any
other ideas?

- Robert


P.S. Anyone remember buffers and C++ templated types are dissallowed
as typedefs?
___
cython-devel mailing list
cython-devel@python.org
http://mail.python.org/mailman/listinfo/cython-devel


Re: [Cython] Fused types syntax

2011-06-02 Thread Chris Colbert
Not that my opinion carriers any weight, but I'm +1 on this.


On Thu, Jun 2, 2011 at 11:39 AM, Robert Bradshaw <
rober...@math.washington.edu> wrote:

> In looking at merging fused types, it's time to nail down the syntax.
> The current implementation is
>
>ctypedef cython.fused_type(list, dict, object) fused_t
>
> This requires an addition to the grammer to allow the "call" syntax in
> a type declaration, as well as special casing to make it allowed only
> in a typedef. What about
>
>cython.fused_type[list, dict, object].
>
> One advantage is that indexing is already valid in type declarations,
> and its the typical syntax for parameterized types. Thoughts? Any
> other ideas?
>
> - Robert
>
>
> P.S. Anyone remember buffers and C++ templated types are dissallowed
> as typedefs?
> ___
> cython-devel mailing list
> cython-devel@python.org
> http://mail.python.org/mailman/listinfo/cython-devel
>
___
cython-devel mailing list
cython-devel@python.org
http://mail.python.org/mailman/listinfo/cython-devel


Re: [Cython] Bindings performance issue

2011-06-02 Thread mark florisson
On 2 June 2011 18:31, Robert Bradshaw  wrote:
> On Thu, Jun 2, 2011 at 1:30 AM, Vitja Makarov  wrote:
>> 2011/6/2 Robert Bradshaw :
>>> On Wed, Jun 1, 2011 at 7:26 AM, Vitja Makarov  
>>> wrote:
 2011/6/1 mark florisson :
> On 31 May 2011 20:25, Vitja Makarov  wrote:
>> Hi!
>>
>> Is bindings performance issue valuable?
>>
>> $ cat bindbench.pyx
>> def wo_bindings():
>>    pass
>>
>> def outer():
>>    def inner():
>>        pass
>>    return inner
>> with_bindings = outer()
>>
>> $ python
> import timeit
> timeit.repeat('with_bindings()', setup='from bindbench import 
> wo_bindings, with_bindings', repeat=1, number=1)
>> [6.169871807098389]
> timeit.repeat('wo_bindings()', setup='from bindbench import 
> wo_bindings, with_bindings', repeat=1, number=1)
>> [4.609416961669922]
>>
>> PyCBindings makes it 1.3 (difference is about 15ns on my laptop) times
>> slower for CPython interpreter execution.
>> As CPython has some optimizations for CFunctions and PyCFunctions.
>>
>> Does it make sense for us? Or we can easily switch to bindings?
>>
>> --
>> vitja.
>> ___
>> cython-devel mailing list
>> cython-devel@python.org
>> http://mail.python.org/mailman/listinfo/cython-devel
>>
>
> I think switching should be fine, if you'd desperately need the speed
> you'd be calling c(p)def functions from Cython. In fact, when the
> fused cfunction will be ready it will be even slightly slower, as it
> overrides the tp_call. But perhaps that should really be made into a
> subclass...
>>>
>>> Yes, this should be a subclass, slowing all calls down is a bad idea.
>>>
> Anyway, would you use these for Python classes and module-level def
> functions (and closures) only, or would you also use them in extension
> classes? Because I found at least a bit of problem there, as extension
> class methods get 'self' passed as the first argument to the C
> function (as PyCFunctionObject.m_self), whereas methods in Python
> classes get 'self' passed in the args tuple (and the m_self is
> unused).
>

 Recently I've found a problem with static methods (__new__ for
 example) of inner classes (classes created inside a function, for
 instance)
 I think binding version should be used for all regular def functions
 (defs, staticmethods, classmethods and so on).
>>>
>>> +1 to moving that way. (Well, static and class methods bind
>>> differently, right?)
>>>
 I also think that it's better to rename binding_PyCFunction_Type to
 something like CyFunctionType and make it more like PyFunction.
>>>
>>> +1
>>>
>>> Is there any advantage to the method descriptors (other than that
>>> they're easier for a human to write?)
>>
>> Initially bindings was written to support bound class methods (am I right?)
>> So when we use it for regular functions 'binding' in the name doesn't
>> reflect its purpose.
>
> There's three kinds of functions we create: PyCFunctions, binding
> PyCFunctions, and extension class methods (via descriptors). I was
> asking about the latter.

Yeah those descriptors have no advantage at all, it's simple
convenience. So we could just use our binding descriptor. The only
difference is that those descriptors return PyCFunctionObjects (which
may have special-cased performance-related advantages, at Vitja
demonstrated), and we would return a binding function (that would have
the same dict as the original).

I still believe that you'd have to do something different for
extension classes (e.g. depending on a flag pass 'self' as m_self or
in the args tuple, so tp_call would have to be overridden). Besides,
if you're going to return a binding pycfunction from descr_get, you'll
want to do type checking for 'self' for unbound method calls. I got
all that working for normal python classes here:
https://github.com/markflorisson88/cython/tree/fusedtypes . Currently
it is intermixed with support for fused Python functions, but seeing
you'd override tp_call anyway the overhead should be negligible.

> As for the first two, it reflects the difference in behavior. If I
> take the function and assign it to a class, it will bind as a method
> when I go to look it up. This is arguably the biggest difference
> between built-in functions and Python functions.
>
>> One the other hand it's much more easy to write manually.
>>
>> About staticmethods: I think that CyFunction type should handle it as well
>> because staticmethods can have custom attributes and act just like
>> normal def one.
>>
>> The difference is insde descr_get it should return bound method for
>> normal and self for staticmethods.
>
> Yep. Does that merit a new class, or a flag that's checked on every
> function invocation (false 99.9% of the time)?

Well, it only needs to do the chec

Re: [Cython] Bindings performance issue

2011-06-02 Thread Vitja Makarov
2011/6/2 Robert Bradshaw :
>> Initially bindings was written to support bound class methods (am I right?)
>> So when we use it for regular functions 'binding' in the name doesn't
>> reflect its purpose.
>
> There's three kinds of functions we create: PyCFunctions, binding
> PyCFunctions, and extension class methods (via descriptors). I was
> asking about the latter.
>
> As for the first two, it reflects the difference in behavior. If I
> take the function and assign it to a class, it will bind as a method
> when I go to look it up. This is arguably the biggest difference
> between built-in functions and Python functions.
>
>> One the other hand it's much more easy to write manually.
>>
>> About staticmethods: I think that CyFunction type should handle it as well
>> because staticmethods can have custom attributes and act just like
>> normal def one.
>>
>> The difference is insde descr_get it should return bound method for
>> normal and self for staticmethods.
>
> Yep. Does that merit a new class, or a flag that's checked on every
> function invocation (false 99.9% of the time)?
>

tp_descr_get() is called each time function gets bound, isn't so?
If it makes sens we can create both CyFunction and CyStaticFunction types.

>> Here I've tried to support staticmethods inside bindings type:
>> https://github.com/vitek/cython/commit/c0725ab340a8173d8e6724c62be3a135df58980e
>>
>>>
>>> I think that small speed regression for better compatibility is OK if
>>> we add a directive to not create binding functions. (It'd be nice if
>>> we could work around it, but that's hard as CPython has special
>>> hooks...) The bigger issue is that the binding behavior is backwards
>>> incompatible, and perhaps in a subtle way. Perhaps we need to have a
>>> phase where all currently non-binding functions that will become
>>> binding functions will raise an error (or at least a warning) to wean
>>> people off of the old behavior before making a switch.
>>>
>>
>> Is the difference so significant?
>
> If anyone is assigning a Cython function to an object and then using
> it they're counting on the current non-binding behavior, and it will
> break. The speed is probably a lesser issue, which is what benchmarks
> are for.
>




-- 
vitja.
___
cython-devel mailing list
cython-devel@python.org
http://mail.python.org/mailman/listinfo/cython-devel


Re: [Cython] Fused types syntax

2011-06-02 Thread mark florisson
On 2 June 2011 18:39, Robert Bradshaw  wrote:
> In looking at merging fused types, it's time to nail down the syntax.
> The current implementation is
>
>    ctypedef cython.fused_type(list, dict, object) fused_t
>
> This requires an addition to the grammer to allow the "call" syntax in
> a type declaration, as well as special casing to make it allowed only
> in a typedef. What about
>
>    cython.fused_type[list, dict, object].
>
> One advantage is that indexing is already valid in type declarations,
> and its the typical syntax for parameterized types. Thoughts? Any
> other ideas?

I like it, so I'll give another +1. Changing wouldn't be too much work anyways.

> - Robert
>
>
> P.S. Anyone remember buffers and C++ templated types are dissallowed
> as typedefs?

Yes, there's even a test for it: tests/errors/buffertypedef_T117.pyx
(http://trac.cython.org/cython_trac/ticket/117). But it looks more
like an easy fix than a feature.

> ___
> cython-devel mailing list
> cython-devel@python.org
> http://mail.python.org/mailman/listinfo/cython-devel
>
___
cython-devel mailing list
cython-devel@python.org
http://mail.python.org/mailman/listinfo/cython-devel


Re: [Cython] Bindings performance issue

2011-06-02 Thread Robert Bradshaw
On Thu, Jun 2, 2011 at 1:00 PM, mark florisson
 wrote:
> On 2 June 2011 18:31, Robert Bradshaw  wrote:
>> On Thu, Jun 2, 2011 at 1:30 AM, Vitja Makarov  
>> wrote:
>>> 2011/6/2 Robert Bradshaw :
 On Wed, Jun 1, 2011 at 7:26 AM, Vitja Makarov  
 wrote:
> 2011/6/1 mark florisson :
>> On 31 May 2011 20:25, Vitja Makarov  wrote:
>>> Hi!
>>>
>>> Is bindings performance issue valuable?
>>>
>>> $ cat bindbench.pyx
>>> def wo_bindings():
>>>    pass
>>>
>>> def outer():
>>>    def inner():
>>>        pass
>>>    return inner
>>> with_bindings = outer()
>>>
>>> $ python
>> import timeit
>> timeit.repeat('with_bindings()', setup='from bindbench import 
>> wo_bindings, with_bindings', repeat=1, number=1)
>>> [6.169871807098389]
>> timeit.repeat('wo_bindings()', setup='from bindbench import 
>> wo_bindings, with_bindings', repeat=1, number=1)
>>> [4.609416961669922]
>>>
>>> PyCBindings makes it 1.3 (difference is about 15ns on my laptop) times
>>> slower for CPython interpreter execution.
>>> As CPython has some optimizations for CFunctions and PyCFunctions.
>>>
>>> Does it make sense for us? Or we can easily switch to bindings?
>>>
>>> --
>>> vitja.
>>> ___
>>> cython-devel mailing list
>>> cython-devel@python.org
>>> http://mail.python.org/mailman/listinfo/cython-devel
>>>
>>
>> I think switching should be fine, if you'd desperately need the speed
>> you'd be calling c(p)def functions from Cython. In fact, when the
>> fused cfunction will be ready it will be even slightly slower, as it
>> overrides the tp_call. But perhaps that should really be made into a
>> subclass...

 Yes, this should be a subclass, slowing all calls down is a bad idea.

>> Anyway, would you use these for Python classes and module-level def
>> functions (and closures) only, or would you also use them in extension
>> classes? Because I found at least a bit of problem there, as extension
>> class methods get 'self' passed as the first argument to the C
>> function (as PyCFunctionObject.m_self), whereas methods in Python
>> classes get 'self' passed in the args tuple (and the m_self is
>> unused).
>>
>
> Recently I've found a problem with static methods (__new__ for
> example) of inner classes (classes created inside a function, for
> instance)
> I think binding version should be used for all regular def functions
> (defs, staticmethods, classmethods and so on).

 +1 to moving that way. (Well, static and class methods bind
 differently, right?)

> I also think that it's better to rename binding_PyCFunction_Type to
> something like CyFunctionType and make it more like PyFunction.

 +1

 Is there any advantage to the method descriptors (other than that
 they're easier for a human to write?)
>>>
>>> Initially bindings was written to support bound class methods (am I right?)
>>> So when we use it for regular functions 'binding' in the name doesn't
>>> reflect its purpose.
>>
>> There's three kinds of functions we create: PyCFunctions, binding
>> PyCFunctions, and extension class methods (via descriptors). I was
>> asking about the latter.
>
> Yeah those descriptors have no advantage at all, it's simple
> convenience. So we could just use our binding descriptor. The only
> difference is that those descriptors return PyCFunctionObjects (which
> may have special-cased performance-related advantages, at Vitja
> demonstrated), and we would return a binding function (that would have
> the same dict as the original).

We could do this too on binding if we wanted...

> I still believe that you'd have to do something different for
> extension classes (e.g. depending on a flag pass 'self' as m_self or
> in the args tuple, so tp_call would have to be overridden). Besides,
> if you're going to return a binding pycfunction from descr_get, you'll
> want to do type checking for 'self' for unbound method calls. I got
> all that working for normal python classes here:
> https://github.com/markflorisson88/cython/tree/fusedtypes . Currently
> it is intermixed with support for fused Python functions, but seeing
> you'd override tp_call anyway the overhead should be negligible.

I was thinking of avoiding descriptors altogether, and simply
populating the cdef class dict.

>> As for the first two, it reflects the difference in behavior. If I
>> take the function and assign it to a class, it will bind as a method
>> when I go to look it up. This is arguably the biggest difference
>> between built-in functions and Python functions.
>>
>>> One the other hand it's much more easy to write manually.
>>>
>>> About staticmethods: I think that CyFunction type should handle it as well
>>> because staticmethods can

Re: [Cython] Fused types syntax

2011-06-02 Thread Robert Bradshaw
On Thu, Jun 2, 2011 at 1:07 PM, mark florisson
 wrote:
> On 2 June 2011 18:39, Robert Bradshaw  wrote:
>> In looking at merging fused types, it's time to nail down the syntax.
>> The current implementation is
>>
>>    ctypedef cython.fused_type(list, dict, object) fused_t
>>
>> This requires an addition to the grammer to allow the "call" syntax in
>> a type declaration, as well as special casing to make it allowed only
>> in a typedef. What about
>>
>>    cython.fused_type[list, dict, object].
>>
>> One advantage is that indexing is already valid in type declarations,
>> and its the typical syntax for parameterized types. Thoughts? Any
>> other ideas?
>
> I like it, so I'll give another +1. Changing wouldn't be too much work 
> anyways.
>
>> - Robert
>>
>>
>> P.S. Anyone remember buffers and C++ templated types are dissallowed
>> as typedefs?
>
> Yes, there's even a test for it: tests/errors/buffertypedef_T117.pyx
> (http://trac.cython.org/cython_trac/ticket/117). But it looks more
> like an easy fix than a feature.

I could see how for buffers it would require at bit more work, but for
C++ types that shouldn't be a problem. In particular, I'm looking at
https://github.com/cython/cython/blob/master/Cython/Compiler/Parsing.py#L2615

- Robert
___
cython-devel mailing list
cython-devel@python.org
http://mail.python.org/mailman/listinfo/cython-devel


Re: [Cython] Bindings performance issue

2011-06-02 Thread mark florisson
On 2 June 2011 22:16, Robert Bradshaw  wrote:
> On Thu, Jun 2, 2011 at 1:00 PM, mark florisson
>  wrote:
>> On 2 June 2011 18:31, Robert Bradshaw  wrote:
>>> On Thu, Jun 2, 2011 at 1:30 AM, Vitja Makarov  
>>> wrote:
 2011/6/2 Robert Bradshaw :
> On Wed, Jun 1, 2011 at 7:26 AM, Vitja Makarov  
> wrote:
>> 2011/6/1 mark florisson :
>>> On 31 May 2011 20:25, Vitja Makarov  wrote:
 Hi!

 Is bindings performance issue valuable?

 $ cat bindbench.pyx
 def wo_bindings():
    pass

 def outer():
    def inner():
        pass
    return inner
 with_bindings = outer()

 $ python
>>> import timeit
>>> timeit.repeat('with_bindings()', setup='from bindbench import 
>>> wo_bindings, with_bindings', repeat=1, number=1)
 [6.169871807098389]
>>> timeit.repeat('wo_bindings()', setup='from bindbench import 
>>> wo_bindings, with_bindings', repeat=1, number=1)
 [4.609416961669922]

 PyCBindings makes it 1.3 (difference is about 15ns on my laptop) times
 slower for CPython interpreter execution.
 As CPython has some optimizations for CFunctions and PyCFunctions.

 Does it make sense for us? Or we can easily switch to bindings?

 --
 vitja.
 ___
 cython-devel mailing list
 cython-devel@python.org
 http://mail.python.org/mailman/listinfo/cython-devel

>>>
>>> I think switching should be fine, if you'd desperately need the speed
>>> you'd be calling c(p)def functions from Cython. In fact, when the
>>> fused cfunction will be ready it will be even slightly slower, as it
>>> overrides the tp_call. But perhaps that should really be made into a
>>> subclass...
>
> Yes, this should be a subclass, slowing all calls down is a bad idea.
>
>>> Anyway, would you use these for Python classes and module-level def
>>> functions (and closures) only, or would you also use them in extension
>>> classes? Because I found at least a bit of problem there, as extension
>>> class methods get 'self' passed as the first argument to the C
>>> function (as PyCFunctionObject.m_self), whereas methods in Python
>>> classes get 'self' passed in the args tuple (and the m_self is
>>> unused).
>>>
>>
>> Recently I've found a problem with static methods (__new__ for
>> example) of inner classes (classes created inside a function, for
>> instance)
>> I think binding version should be used for all regular def functions
>> (defs, staticmethods, classmethods and so on).
>
> +1 to moving that way. (Well, static and class methods bind
> differently, right?)
>
>> I also think that it's better to rename binding_PyCFunction_Type to
>> something like CyFunctionType and make it more like PyFunction.
>
> +1
>
> Is there any advantage to the method descriptors (other than that
> they're easier for a human to write?)

 Initially bindings was written to support bound class methods (am I right?)
 So when we use it for regular functions 'binding' in the name doesn't
 reflect its purpose.
>>>
>>> There's three kinds of functions we create: PyCFunctions, binding
>>> PyCFunctions, and extension class methods (via descriptors). I was
>>> asking about the latter.
>>
>> Yeah those descriptors have no advantage at all, it's simple
>> convenience. So we could just use our binding descriptor. The only
>> difference is that those descriptors return PyCFunctionObjects (which
>> may have special-cased performance-related advantages, at Vitja
>> demonstrated), and we would return a binding function (that would have
>> the same dict as the original).
>
> We could do this too on binding if we wanted...

That's what I mean, this all happens when we bind the function. If we
return a bound PyCFunctionObject, we lose our dict.

>> I still believe that you'd have to do something different for
>> extension classes (e.g. depending on a flag pass 'self' as m_self or
>> in the args tuple, so tp_call would have to be overridden). Besides,
>> if you're going to return a binding pycfunction from descr_get, you'll
>> want to do type checking for 'self' for unbound method calls. I got
>> all that working for normal python classes here:
>> https://github.com/markflorisson88/cython/tree/fusedtypes . Currently
>> it is intermixed with support for fused Python functions, but seeing
>> you'd override tp_call anyway the overhead should be negligible.
>
> I was thinking of avoiding descriptors altogether, and simply
> populating the cdef class dict.

Yes, that is my proposal. Without populating the class dict, you
cannot have custom pycfunctions.

>>> As for the first two, it reflects the difference in b

Re: [Cython] Bindings performance issue

2011-06-02 Thread Robert Bradshaw
On Thu, Jun 2, 2011 at 2:03 PM, mark florisson
 wrote:

 If anyone is assigning a Cython function to an object and then using
 it they're counting on the current non-binding behavior, and it will
 break. The speed is probably a lesser issue, which is what benchmarks
 are for.
>>>
>>> If you're binding functions to classes without expecting it to ever
>>> bind, you don't really have bitching rights when stuff breaks later
>>> on. You should have been using staticmethod() to begin with. And we
>>> never said that our functions would never bind :)
>>
>> No, you're assigning it to an object, counting on being able to call
>> it later on. E.g. the following is legal (though contrived in this
>> example):
>>
>> sage: class A:
>> :     pass
>> :
>> sage: a = A()
>> sage: a.foo = max
>> sage: a.foo([1,2,3])
>> 3
>>
>> If instead of len, it was one of our functions, then it would be bad
>> to suddenly change the semantics, because it could still run but
>> produce bad answers (e.g. if we had implemented max, suddenly a would
>> be included in the comparison). This is why I proposed raising an
>> explicit error as an intermediate step.
>>
>> If we don't promise anything, the contract is whatever the code does.
>> That's the problem with not having a specification (which would be
>> really nice, but is a lot of work).
>
> Functions on objects never get bound, they only get bound if they are
> on the class. So your code would still work with binding functions.

True. It would still break "A.foo = max" though. I'm not saying we
should support or encourage this, but lets break it hard before we
break it subtly.

- Robert
___
cython-devel mailing list
cython-devel@python.org
http://mail.python.org/mailman/listinfo/cython-devel


Re: [Cython] Fused types syntax

2011-06-02 Thread Dag Sverre Seljebotn

On 06/02/2011 06:39 PM, Robert Bradshaw wrote:

In looking at merging fused types, it's time to nail down the syntax.
The current implementation is

 ctypedef cython.fused_type(list, dict, object) fused_t

This requires an addition to the grammer to allow the "call" syntax in
a type declaration, as well as special casing to make it allowed only
in a typedef. What about

 cython.fused_type[list, dict, object].

One advantage is that indexing is already valid in type declarations,
and its the typical syntax for parameterized types. Thoughts? Any
other ideas?


I don't really like overloading [] even more, and I think () (or, 
perhaps, 'fused_type([list, dict, object])').


But I don't feel very strongly about it.

If you only want this allowed in typedefs, then, being puristic, I think 
that really a "fused type" is really different from a ctypedef, and that 
it would warrant something like a new keyword.


cdef fusedtype [list, dict, object] fused_t

That's rather horrible, but you get the gist. The thing is, once you use 
a ctypeudef, you really should allow


def f(fused_type(float, double) x, fused_type(float, double) y): ...

but then, how many fused types do you have, one or two?

So this makes it seem to me that using ctypedef is a rather horrible hack.

But, like I said, I don't feel strongly about this.




P.S. Anyone remember buffers and C++ templated types are dissallowed
as typedefs?


As for buffers I just think I never got around to it...

Dag Sverre
___
cython-devel mailing list
cython-devel@python.org
http://mail.python.org/mailman/listinfo/cython-devel


Re: [Cython] Bindings performance issue

2011-06-02 Thread mark florisson
On 2 June 2011 23:13, Robert Bradshaw  wrote:
> On Thu, Jun 2, 2011 at 2:03 PM, mark florisson
>  wrote:
>
> If anyone is assigning a Cython function to an object and then using
> it they're counting on the current non-binding behavior, and it will
> break. The speed is probably a lesser issue, which is what benchmarks
> are for.

 If you're binding functions to classes without expecting it to ever
 bind, you don't really have bitching rights when stuff breaks later
 on. You should have been using staticmethod() to begin with. And we
 never said that our functions would never bind :)
>>>
>>> No, you're assigning it to an object, counting on being able to call
>>> it later on. E.g. the following is legal (though contrived in this
>>> example):
>>>
>>> sage: class A:
>>> :     pass
>>> :
>>> sage: a = A()
>>> sage: a.foo = max
>>> sage: a.foo([1,2,3])
>>> 3
>>>
>>> If instead of len, it was one of our functions, then it would be bad
>>> to suddenly change the semantics, because it could still run but
>>> produce bad answers (e.g. if we had implemented max, suddenly a would
>>> be included in the comparison). This is why I proposed raising an
>>> explicit error as an intermediate step.
>>>
>>> If we don't promise anything, the contract is whatever the code does.
>>> That's the problem with not having a specification (which would be
>>> really nice, but is a lot of work).
>>
>> Functions on objects never get bound, they only get bound if they are
>> on the class. So your code would still work with binding functions.
>
> True. It would still break "A.foo = max" though. I'm not saying we
> should support or encourage this, but lets break it hard before we
> break it subtly.

Again, such code is highly fragile and frankly incorrect to begin
with, as it's based on the assumption that "Cython functions" never
get bound. Getting functions (defined outside of class bodies) to bind
in classes is a feature, I sometimes found myself to want it. So
basically an error would be fine, but it would prevent normal usage as
we have it in Python.

> - Robert
> ___
> cython-devel mailing list
> cython-devel@python.org
> http://mail.python.org/mailman/listinfo/cython-devel
>
___
cython-devel mailing list
cython-devel@python.org
http://mail.python.org/mailman/listinfo/cython-devel


Re: [Cython] Fused types syntax

2011-06-02 Thread Nathaniel Smith
On Jun 2, 2011 2:18 PM, "Dag Sverre Seljebotn" 
wrote:
> If you only want this allowed in typedefs, then, being puristic, I think
that really a "fused type" is really different from a ctypedef, and that it
would warrant something like a new keyword.
>
> cdef fusedtype [list, dict, object] fused_t

+1 (to some variant of this, not necessarily this exactly)

I find the argument that defining the same fused type twice results in two
different, incompatible types to be very compelling. That's a fundamental
difference from typedefs.

- Nathaniel
___
cython-devel mailing list
cython-devel@python.org
http://mail.python.org/mailman/listinfo/cython-devel


Re: [Cython] Fused types syntax

2011-06-02 Thread Robert Bradshaw
On Thu, Jun 2, 2011 at 2:18 PM, Dag Sverre Seljebotn
 wrote:
> On 06/02/2011 06:39 PM, Robert Bradshaw wrote:
>>
>> In looking at merging fused types, it's time to nail down the syntax.
>> The current implementation is
>>
>>     ctypedef cython.fused_type(list, dict, object) fused_t
>>
>> This requires an addition to the grammer to allow the "call" syntax in
>> a type declaration, as well as special casing to make it allowed only
>> in a typedef. What about
>>
>>     cython.fused_type[list, dict, object].
>>
>> One advantage is that indexing is already valid in type declarations,
>> and its the typical syntax for parameterized types. Thoughts? Any
>> other ideas?
>
> I don't really like overloading [] even more, and I think () (or, perhaps,
> 'fused_type([list, dict, object])').
>
> But I don't feel very strongly about it.
>
> If you only want this allowed in typedefs, then, being puristic, I think
> that really a "fused type" is really different from a ctypedef, and that it
> would warrant something like a new keyword.
>
> cdef fusedtype [list, dict, object] fused_t
>
> That's rather horrible, but you get the gist. The thing is, once you use a
> ctypeudef, you really should allow
>
> def f(fused_type(float, double) x, fused_type(float, double) y): ...
>
> but then, how many fused types do you have, one or two?

Two, and you can't refer to them. Such anonymous types could be handy
for one-off functions, e.g.

def f(fused_type[list, dict, object] x): ...

but maybe that's not needed.

> So this makes it seem to me that using ctypedef is a rather horrible hack.

Yeah, this is the crux of the issue. (To be clear, Mark's
implementation is good, it's our syntax that's hacky). It's perhaps
less ugly than
introducing a new keyword. A crazy idea:

cdef fused floating_t:
float
double
long double

(in analogy with how we declare types like structs and enums).

> But, like I said, I don't feel strongly about this.
>
>
>>
>> P.S. Anyone remember buffers and C++ templated types are dissallowed
>> as typedefs?
>
> As for buffers I just think I never got around to it...

And in that case you can't just punt the typedef to C :).

- Robert
___
cython-devel mailing list
cython-devel@python.org
http://mail.python.org/mailman/listinfo/cython-devel


Re: [Cython] Bindings performance issue

2011-06-02 Thread Robert Bradshaw
On Thu, Jun 2, 2011 at 2:21 PM, mark florisson
 wrote:
> On 2 June 2011 23:13, Robert Bradshaw  wrote:
>> On Thu, Jun 2, 2011 at 2:03 PM, mark florisson
>>  wrote:
>>
>> If anyone is assigning a Cython function to an object and then using
>> it they're counting on the current non-binding behavior, and it will
>> break. The speed is probably a lesser issue, which is what benchmarks
>> are for.
>
> If you're binding functions to classes without expecting it to ever
> bind, you don't really have bitching rights when stuff breaks later
> on. You should have been using staticmethod() to begin with. And we
> never said that our functions would never bind :)

 No, you're assigning it to an object, counting on being able to call
 it later on. E.g. the following is legal (though contrived in this
 example):

 sage: class A:
 :     pass
 :
 sage: a = A()
 sage: a.foo = max
 sage: a.foo([1,2,3])
 3

 If instead of len, it was one of our functions, then it would be bad
 to suddenly change the semantics, because it could still run but
 produce bad answers (e.g. if we had implemented max, suddenly a would
 be included in the comparison). This is why I proposed raising an
 explicit error as an intermediate step.

 If we don't promise anything, the contract is whatever the code does.
 That's the problem with not having a specification (which would be
 really nice, but is a lot of work).
>>>
>>> Functions on objects never get bound, they only get bound if they are
>>> on the class. So your code would still work with binding functions.
>>
>> True. It would still break "A.foo = max" though. I'm not saying we
>> should support or encourage this, but lets break it hard before we
>> break it subtly.
>
> Again, such code is highly fragile and frankly incorrect to begin
> with, as it's based on the assumption that "Cython functions" never
> get bound.

I agree, but I bet there's code out there depending on it, in
particular workarounds for our current broken semantics will
themselves break.

> Getting functions (defined outside of class bodies) to bind
> in classes is a feature, I sometimes found myself to want it. So
> basically an error would be fine, but it would prevent normal usage as
> we have it in Python.

The error would just be for a transition period.

- Robert
___
cython-devel mailing list
cython-devel@python.org
http://mail.python.org/mailman/listinfo/cython-devel


Re: [Cython] Fused types syntax

2011-06-02 Thread mark florisson
On 2 June 2011 23:31, Robert Bradshaw  wrote:
> On Thu, Jun 2, 2011 at 2:18 PM, Dag Sverre Seljebotn
>  wrote:
>> On 06/02/2011 06:39 PM, Robert Bradshaw wrote:
>>>
>>> In looking at merging fused types, it's time to nail down the syntax.
>>> The current implementation is
>>>
>>>     ctypedef cython.fused_type(list, dict, object) fused_t
>>>
>>> This requires an addition to the grammer to allow the "call" syntax in
>>> a type declaration, as well as special casing to make it allowed only
>>> in a typedef. What about
>>>
>>>     cython.fused_type[list, dict, object].
>>>
>>> One advantage is that indexing is already valid in type declarations,
>>> and its the typical syntax for parameterized types. Thoughts? Any
>>> other ideas?
>>
>> I don't really like overloading [] even more, and I think () (or, perhaps,
>> 'fused_type([list, dict, object])').
>>
>> But I don't feel very strongly about it.
>>
>> If you only want this allowed in typedefs, then, being puristic, I think
>> that really a "fused type" is really different from a ctypedef, and that it
>> would warrant something like a new keyword.
>>
>> cdef fusedtype [list, dict, object] fused_t
>>
>> That's rather horrible, but you get the gist. The thing is, once you use a
>> ctypeudef, you really should allow
>>
>> def f(fused_type(float, double) x, fused_type(float, double) y): ...
>>
>> but then, how many fused types do you have, one or two?
>
> Two, and you can't refer to them. Such anonymous types could be handy
> for one-off functions, e.g.
>
>    def f(fused_type[list, dict, object] x): ...
>
> but maybe that's not needed.
>
>> So this makes it seem to me that using ctypedef is a rather horrible hack.
>
> Yeah, this is the crux of the issue. (To be clear, Mark's
> implementation is good, it's our syntax that's hacky). It's perhaps
> less ugly than
> introducing a new keyword. A crazy idea:
>
> cdef fused floating_t:
>    float
>    double
>    long double
>
> (in analogy with how we declare types like structs and enums).

I like that syntax, the bad thing about ctypedef for me is that
everything goes on one line, at which point you have to start breaking
them if they get too long (which can happen quite easily with lenghty
names like 'long double complex'), which looks awkward.

So much for trying to reduce grammar changes, though :)

>> But, like I said, I don't feel strongly about this.
>>
>>
>>>
>>> P.S. Anyone remember buffers and C++ templated types are dissallowed
>>> as typedefs?
>>
>> As for buffers I just think I never got around to it...
>
> And in that case you can't just punt the typedef to C :).
>
> - Robert
> ___
> cython-devel mailing list
> cython-devel@python.org
> http://mail.python.org/mailman/listinfo/cython-devel
>
___
cython-devel mailing list
cython-devel@python.org
http://mail.python.org/mailman/listinfo/cython-devel


Re: [Cython] Bindings performance issue

2011-06-02 Thread mark florisson
On 2 June 2011 23:34, Robert Bradshaw  wrote:
> On Thu, Jun 2, 2011 at 2:21 PM, mark florisson
>  wrote:
>> On 2 June 2011 23:13, Robert Bradshaw  wrote:
>>> On Thu, Jun 2, 2011 at 2:03 PM, mark florisson
>>>  wrote:
>>>
>>> If anyone is assigning a Cython function to an object and then using
>>> it they're counting on the current non-binding behavior, and it will
>>> break. The speed is probably a lesser issue, which is what benchmarks
>>> are for.
>>
>> If you're binding functions to classes without expecting it to ever
>> bind, you don't really have bitching rights when stuff breaks later
>> on. You should have been using staticmethod() to begin with. And we
>> never said that our functions would never bind :)
>
> No, you're assigning it to an object, counting on being able to call
> it later on. E.g. the following is legal (though contrived in this
> example):
>
> sage: class A:
> :     pass
> :
> sage: a = A()
> sage: a.foo = max
> sage: a.foo([1,2,3])
> 3
>
> If instead of len, it was one of our functions, then it would be bad
> to suddenly change the semantics, because it could still run but
> produce bad answers (e.g. if we had implemented max, suddenly a would
> be included in the comparison). This is why I proposed raising an
> explicit error as an intermediate step.
>
> If we don't promise anything, the contract is whatever the code does.
> That's the problem with not having a specification (which would be
> really nice, but is a lot of work).

 Functions on objects never get bound, they only get bound if they are
 on the class. So your code would still work with binding functions.
>>>
>>> True. It would still break "A.foo = max" though. I'm not saying we
>>> should support or encourage this, but lets break it hard before we
>>> break it subtly.
>>
>> Again, such code is highly fragile and frankly incorrect to begin
>> with, as it's based on the assumption that "Cython functions" never
>> get bound.
>
> I agree, but I bet there's code out there depending on it, in
> particular workarounds for our current broken semantics will
> themselves break.

Workarounds wouldn't break, as they would wrap the non-binding
function in another object, and implement __get__ to return a new
object that, when called, would call the original function with 'self'
as the first argument.

>> Getting functions (defined outside of class bodies) to bind
>> in classes is a feature, I sometimes found myself to want it. So
>> basically an error would be fine, but it would prevent normal usage as
>> we have it in Python.
>
> The error would just be for a transition period.

The transition period would be for an entire release?

> - Robert
> ___
> cython-devel mailing list
> cython-devel@python.org
> http://mail.python.org/mailman/listinfo/cython-devel
>
___
cython-devel mailing list
cython-devel@python.org
http://mail.python.org/mailman/listinfo/cython-devel


Re: [Cython] Fused types syntax

2011-06-02 Thread Robert Bradshaw
On Thu, Jun 2, 2011 at 2:42 PM, mark florisson
 wrote:
> On 2 June 2011 23:31, Robert Bradshaw  wrote:
>> On Thu, Jun 2, 2011 at 2:18 PM, Dag Sverre Seljebotn
>>  wrote:
>>> On 06/02/2011 06:39 PM, Robert Bradshaw wrote:

 In looking at merging fused types, it's time to nail down the syntax.
 The current implementation is

     ctypedef cython.fused_type(list, dict, object) fused_t

 This requires an addition to the grammer to allow the "call" syntax in
 a type declaration, as well as special casing to make it allowed only
 in a typedef. What about

     cython.fused_type[list, dict, object].

 One advantage is that indexing is already valid in type declarations,
 and its the typical syntax for parameterized types. Thoughts? Any
 other ideas?
>>>
>>> I don't really like overloading [] even more, and I think () (or, perhaps,
>>> 'fused_type([list, dict, object])').
>>>
>>> But I don't feel very strongly about it.
>>>
>>> If you only want this allowed in typedefs, then, being puristic, I think
>>> that really a "fused type" is really different from a ctypedef, and that it
>>> would warrant something like a new keyword.
>>>
>>> cdef fusedtype [list, dict, object] fused_t
>>>
>>> That's rather horrible, but you get the gist. The thing is, once you use a
>>> ctypeudef, you really should allow
>>>
>>> def f(fused_type(float, double) x, fused_type(float, double) y): ...
>>>
>>> but then, how many fused types do you have, one or two?
>>
>> Two, and you can't refer to them. Such anonymous types could be handy
>> for one-off functions, e.g.
>>
>>    def f(fused_type[list, dict, object] x): ...
>>
>> but maybe that's not needed.
>>
>>> So this makes it seem to me that using ctypedef is a rather horrible hack.
>>
>> Yeah, this is the crux of the issue. (To be clear, Mark's
>> implementation is good, it's our syntax that's hacky). It's perhaps
>> less ugly than
>> introducing a new keyword. A crazy idea:
>>
>> cdef fused floating_t:
>>    float
>>    double
>>    long double
>>
>> (in analogy with how we declare types like structs and enums).
>
> I like that syntax, the bad thing about ctypedef for me is that
> everything goes on one line, at which point you have to start breaking
> them if they get too long (which can happen quite easily with lenghty
> names like 'long double complex'), which looks awkward.
>
> So much for trying to reduce grammar changes, though :)

Well, it introduces a new kind of node, rather than the kind of funny
interaction/restriction with typedef, which got me thinking about this
in the first place. Of course then you can't create an anonymous one
for use in a function (which may be viewed as a feature or a defect).

- Robert
___
cython-devel mailing list
cython-devel@python.org
http://mail.python.org/mailman/listinfo/cython-devel


Re: [Cython] Bindings performance issue

2011-06-02 Thread Robert Bradshaw
On Thu, Jun 2, 2011 at 2:45 PM, mark florisson
 wrote:
> On 2 June 2011 23:34, Robert Bradshaw  wrote:
>> On Thu, Jun 2, 2011 at 2:21 PM, mark florisson
>>  wrote:
>>> On 2 June 2011 23:13, Robert Bradshaw  wrote:
 On Thu, Jun 2, 2011 at 2:03 PM, mark florisson
  wrote:

 If anyone is assigning a Cython function to an object and then using
 it they're counting on the current non-binding behavior, and it will
 break. The speed is probably a lesser issue, which is what benchmarks
 are for.
>>>
>>> If you're binding functions to classes without expecting it to ever
>>> bind, you don't really have bitching rights when stuff breaks later
>>> on. You should have been using staticmethod() to begin with. And we
>>> never said that our functions would never bind :)
>>
>> No, you're assigning it to an object, counting on being able to call
>> it later on. E.g. the following is legal (though contrived in this
>> example):
>>
>> sage: class A:
>> :     pass
>> :
>> sage: a = A()
>> sage: a.foo = max
>> sage: a.foo([1,2,3])
>> 3
>>
>> If instead of len, it was one of our functions, then it would be bad
>> to suddenly change the semantics, because it could still run but
>> produce bad answers (e.g. if we had implemented max, suddenly a would
>> be included in the comparison). This is why I proposed raising an
>> explicit error as an intermediate step.
>>
>> If we don't promise anything, the contract is whatever the code does.
>> That's the problem with not having a specification (which would be
>> really nice, but is a lot of work).
>
> Functions on objects never get bound, they only get bound if they are
> on the class. So your code would still work with binding functions.

 True. It would still break "A.foo = max" though. I'm not saying we
 should support or encourage this, but lets break it hard before we
 break it subtly.
>>>
>>> Again, such code is highly fragile and frankly incorrect to begin
>>> with, as it's based on the assumption that "Cython functions" never
>>> get bound.
>>
>> I agree, but I bet there's code out there depending on it, in
>> particular workarounds for our current broken semantics will
>> themselves break.
>
> Workarounds wouldn't break, as they would wrap the non-binding
> function in another object, and implement __get__ to return a new
> object that, when called, would call the original function with 'self'
> as the first argument.

Depends on the workaround. I'm thinking workarounds like "oh, self
isn't getting passed, guess I'll have to pass it manually here..."

>>> Getting functions (defined outside of class bodies) to bind
>>> in classes is a feature, I sometimes found myself to want it. So
>>> basically an error would be fine, but it would prevent normal usage as
>>> we have it in Python.
>>
>> The error would just be for a transition period.
>
> The transition period would be for an entire release?

Yes, though hopefully a much shorter release cycle than this last one.
I just haven't had time to fix those remaining failing Sage tests, and
we keep merging in more and more stuff (which is good, but we're well
overdue for a release by now.)

- Robert
___
cython-devel mailing list
cython-devel@python.org
http://mail.python.org/mailman/listinfo/cython-devel


Re: [Cython] Bindings performance issue

2011-06-02 Thread mark florisson
On 2 June 2011 23:59, Robert Bradshaw  wrote:
> On Thu, Jun 2, 2011 at 2:45 PM, mark florisson
>  wrote:
>> On 2 June 2011 23:34, Robert Bradshaw  wrote:
>>> On Thu, Jun 2, 2011 at 2:21 PM, mark florisson
>>>  wrote:
 On 2 June 2011 23:13, Robert Bradshaw  wrote:
> On Thu, Jun 2, 2011 at 2:03 PM, mark florisson
>  wrote:
>
> If anyone is assigning a Cython function to an object and then using
> it they're counting on the current non-binding behavior, and it will
> break. The speed is probably a lesser issue, which is what benchmarks
> are for.

 If you're binding functions to classes without expecting it to ever
 bind, you don't really have bitching rights when stuff breaks later
 on. You should have been using staticmethod() to begin with. And we
 never said that our functions would never bind :)
>>>
>>> No, you're assigning it to an object, counting on being able to call
>>> it later on. E.g. the following is legal (though contrived in this
>>> example):
>>>
>>> sage: class A:
>>> :     pass
>>> :
>>> sage: a = A()
>>> sage: a.foo = max
>>> sage: a.foo([1,2,3])
>>> 3
>>>
>>> If instead of len, it was one of our functions, then it would be bad
>>> to suddenly change the semantics, because it could still run but
>>> produce bad answers (e.g. if we had implemented max, suddenly a would
>>> be included in the comparison). This is why I proposed raising an
>>> explicit error as an intermediate step.
>>>
>>> If we don't promise anything, the contract is whatever the code does.
>>> That's the problem with not having a specification (which would be
>>> really nice, but is a lot of work).
>>
>> Functions on objects never get bound, they only get bound if they are
>> on the class. So your code would still work with binding functions.
>
> True. It would still break "A.foo = max" though. I'm not saying we
> should support or encourage this, but lets break it hard before we
> break it subtly.

 Again, such code is highly fragile and frankly incorrect to begin
 with, as it's based on the assumption that "Cython functions" never
 get bound.
>>>
>>> I agree, but I bet there's code out there depending on it, in
>>> particular workarounds for our current broken semantics will
>>> themselves break.
>>
>> Workarounds wouldn't break, as they would wrap the non-binding
>> function in another object, and implement __get__ to return a new
>> object that, when called, would call the original function with 'self'
>> as the first argument.
>
> Depends on the workaround. I'm thinking workarounds like "oh, self
> isn't getting passed, guess I'll have to pass it manually here..."

Ah, something like functools.partial. Yeah, that'd break :)

 Getting functions (defined outside of class bodies) to bind
 in classes is a feature, I sometimes found myself to want it. So
 basically an error would be fine, but it would prevent normal usage as
 we have it in Python.
>>>
>>> The error would just be for a transition period.
>>
>> The transition period would be for an entire release?
>
> Yes, though hopefully a much shorter release cycle than this last one.
> I just haven't had time to fix those remaining failing Sage tests, and
> we keep merging in more and more stuff (which is good, but we're well
> overdue for a release by now.)

Ok. Then perhaps it would be better to merge the support for fused
types in the next release? I won't be available until the 6th of July
for coding, so until then we'd be stuck with cython.fused_type() in a
ctypedef.

> - Robert
> ___
> cython-devel mailing list
> cython-devel@python.org
> http://mail.python.org/mailman/listinfo/cython-devel
>
___
cython-devel mailing list
cython-devel@python.org
http://mail.python.org/mailman/listinfo/cython-devel


Re: [Cython] Bindings performance issue

2011-06-02 Thread mark florisson
On 3 June 2011 00:04, mark florisson  wrote:
> On 2 June 2011 23:59, Robert Bradshaw  wrote:
>> On Thu, Jun 2, 2011 at 2:45 PM, mark florisson
>>  wrote:
>>> On 2 June 2011 23:34, Robert Bradshaw  wrote:
 On Thu, Jun 2, 2011 at 2:21 PM, mark florisson
  wrote:
> On 2 June 2011 23:13, Robert Bradshaw  
> wrote:
>> On Thu, Jun 2, 2011 at 2:03 PM, mark florisson
>>  wrote:
>>
>> If anyone is assigning a Cython function to an object and then using
>> it they're counting on the current non-binding behavior, and it will
>> break. The speed is probably a lesser issue, which is what benchmarks
>> are for.
>
> If you're binding functions to classes without expecting it to ever
> bind, you don't really have bitching rights when stuff breaks later
> on. You should have been using staticmethod() to begin with. And we
> never said that our functions would never bind :)

 No, you're assigning it to an object, counting on being able to call
 it later on. E.g. the following is legal (though contrived in this
 example):

 sage: class A:
 :     pass
 :
 sage: a = A()
 sage: a.foo = max
 sage: a.foo([1,2,3])
 3

 If instead of len, it was one of our functions, then it would be bad
 to suddenly change the semantics, because it could still run but
 produce bad answers (e.g. if we had implemented max, suddenly a would
 be included in the comparison). This is why I proposed raising an
 explicit error as an intermediate step.

 If we don't promise anything, the contract is whatever the code does.
 That's the problem with not having a specification (which would be
 really nice, but is a lot of work).
>>>
>>> Functions on objects never get bound, they only get bound if they are
>>> on the class. So your code would still work with binding functions.
>>
>> True. It would still break "A.foo = max" though. I'm not saying we
>> should support or encourage this, but lets break it hard before we
>> break it subtly.
>
> Again, such code is highly fragile and frankly incorrect to begin
> with, as it's based on the assumption that "Cython functions" never
> get bound.

 I agree, but I bet there's code out there depending on it, in
 particular workarounds for our current broken semantics will
 themselves break.
>>>
>>> Workarounds wouldn't break, as they would wrap the non-binding
>>> function in another object, and implement __get__ to return a new
>>> object that, when called, would call the original function with 'self'
>>> as the first argument.
>>
>> Depends on the workaround. I'm thinking workarounds like "oh, self
>> isn't getting passed, guess I'll have to pass it manually here..."
>
> Ah, something like functools.partial. Yeah, that'd break :)
>
> Getting functions (defined outside of class bodies) to bind
> in classes is a feature, I sometimes found myself to want it. So
> basically an error would be fine, but it would prevent normal usage as
> we have it in Python.

 The error would just be for a transition period.
>>>
>>> The transition period would be for an entire release?
>>
>> Yes, though hopefully a much shorter release cycle than this last one.
>> I just haven't had time to fix those remaining failing Sage tests, and
>> we keep merging in more and more stuff (which is good, but we're well
>> overdue for a release by now.)
>
> Ok. Then perhaps it would be better to merge the support for fused
> types in the next release? I won't be available until the 6th of July
> for coding, so until then we'd be stuck with cython.fused_type() in a
> ctypedef.

... where 'next' means not the upcoming release, but the one after that.

>> - Robert
>> ___
>> cython-devel mailing list
>> cython-devel@python.org
>> http://mail.python.org/mailman/listinfo/cython-devel
>>
>
___
cython-devel mailing list
cython-devel@python.org
http://mail.python.org/mailman/listinfo/cython-devel


Re: [Cython] Bindings performance issue

2011-06-02 Thread Robert Bradshaw
On Thu, Jun 2, 2011 at 3:04 PM, mark florisson
 wrote:
> On 2 June 2011 23:59, Robert Bradshaw  wrote:
>> On Thu, Jun 2, 2011 at 2:45 PM, mark florisson
>>  wrote:
>>> On 2 June 2011 23:34, Robert Bradshaw  wrote:
 On Thu, Jun 2, 2011 at 2:21 PM, mark florisson
  wrote:
> On 2 June 2011 23:13, Robert Bradshaw  
> wrote:
>> On Thu, Jun 2, 2011 at 2:03 PM, mark florisson
>>  wrote:
>>
>> If anyone is assigning a Cython function to an object and then using
>> it they're counting on the current non-binding behavior, and it will
>> break. The speed is probably a lesser issue, which is what benchmarks
>> are for.
>
> If you're binding functions to classes without expecting it to ever
> bind, you don't really have bitching rights when stuff breaks later
> on. You should have been using staticmethod() to begin with. And we
> never said that our functions would never bind :)

 No, you're assigning it to an object, counting on being able to call
 it later on. E.g. the following is legal (though contrived in this
 example):

 sage: class A:
 :     pass
 :
 sage: a = A()
 sage: a.foo = max
 sage: a.foo([1,2,3])
 3

 If instead of len, it was one of our functions, then it would be bad
 to suddenly change the semantics, because it could still run but
 produce bad answers (e.g. if we had implemented max, suddenly a would
 be included in the comparison). This is why I proposed raising an
 explicit error as an intermediate step.

 If we don't promise anything, the contract is whatever the code does.
 That's the problem with not having a specification (which would be
 really nice, but is a lot of work).
>>>
>>> Functions on objects never get bound, they only get bound if they are
>>> on the class. So your code would still work with binding functions.
>>
>> True. It would still break "A.foo = max" though. I'm not saying we
>> should support or encourage this, but lets break it hard before we
>> break it subtly.
>
> Again, such code is highly fragile and frankly incorrect to begin
> with, as it's based on the assumption that "Cython functions" never
> get bound.

 I agree, but I bet there's code out there depending on it, in
 particular workarounds for our current broken semantics will
 themselves break.
>>>
>>> Workarounds wouldn't break, as they would wrap the non-binding
>>> function in another object, and implement __get__ to return a new
>>> object that, when called, would call the original function with 'self'
>>> as the first argument.
>>
>> Depends on the workaround. I'm thinking workarounds like "oh, self
>> isn't getting passed, guess I'll have to pass it manually here..."
>
> Ah, something like functools.partial. Yeah, that'd break :)
>
> Getting functions (defined outside of class bodies) to bind
> in classes is a feature, I sometimes found myself to want it. So
> basically an error would be fine, but it would prevent normal usage as
> we have it in Python.

 The error would just be for a transition period.
>>>
>>> The transition period would be for an entire release?
>>
>> Yes, though hopefully a much shorter release cycle than this last one.
>> I just haven't had time to fix those remaining failing Sage tests, and
>> we keep merging in more and more stuff (which is good, but we're well
>> overdue for a release by now.)
>
> Ok. Then perhaps it would be better to merge the support for fused
> types in the next release? I won't be available until the 6th of July
> for coding, so until then we'd be stuck with cython.fused_type() in a
> ctypedef.

Well, it's such a cool feature :). More to the point, it's not nearly
as invasive (i.e. compiling existing code will still pretty much work
the way it always has).

- Robert
___
cython-devel mailing list
cython-devel@python.org
http://mail.python.org/mailman/listinfo/cython-devel