[Cython] Fused Types

Robert Bradshaw robertwb at math.washington.edu
Sat Apr 30 19:06:38 CEST 2011


On Sat, Apr 30, 2011 at 7:24 AM, Stefan Behnel <stefan_ml at behnel.de> wrote:
> Robert Bradshaw, 29.04.2011 06:32:
>>
>> On Thu, Apr 28, 2011 at 7:09 PM, Stefan Behnel<stefan_ml at behnel.de>
>>  wrote:
>>>
>>> mark florisson, 28.04.2011 23:29:
>>>>
>>>> On 28 April 2011 22:31, mark florisson wrote:
>>>>>
>>>>> On 28 April 2011 22:12, Robert Bradshaw wrote:
>>>>>>
>>>>>> On Thu, Apr 28, 2011 at 12:48 PM, mark florisson wrote:
>>>>>>
>>>>>>> So I fixed all that, but I'm currently wondering about the proposed
>>>>>>> cython.typeof(). I believe it currently returns a string with the
>>>>>>> type
>>>>>>> name, and not the type itself.
>>>>>>
>>>>>> Yes. This is just because there's not really anything better to return
>>>>>> at this point. We should "fix" this at some point in the future.
>>>>>>
>>>>>>> So I think it would be inconsistent to
>>>>>>> suddenly start allowing comparison with 'is' and 'isinstance' and
>>>>>>> such.
>>>>>>
>>>>>> I'm open to other suggestions, but would like an expression that
>>>>>> resolves at compile time to true/false (and we need to do branch
>>>>>> pruning on it). Note that type() is not good enough, because it has
>>>>>> different semantics, i.e.
>>>>>>
>>>>>>    cdef object o = []
>>>>>>    typeof(o), type(o)
>>>>>>
>>>>>> so lets not touch that one.
>>>>>
>>>>> Right, so for fused types I don't mind string comparison with
>>>>> cython.typeof(), but retrieval of the actual type for casts and
>>>>> declaration remains open. I'd be fine with something like
>>>>> cython.gettype().
>>>>
>>>> It seems that this isn't optimized yet, but it looks to me like it
>>>> wouldn't be very hard to do so. At least == and != could be resolved
>>>> at compile time if the other operand is a string literal.
>>>
>>> Well, the obvious place where this would happen for free would be
>>> constant
>>> folding. But that runs *way* before type analysis, so all it sees is the
>>> typeof() call, not the string.
>>
>> Actually, to support code like
>>
>> ctypedef cython.fused_type(object, double) my_fused_type
>>
>> cdef foo(my_fused_type x):
>>     if my_fused_type is object:
>>         print x.attr
>>     else:
>>         cdef my_fused_type *ptr =&x
>>
>> we need to resolve this branch and prune "dead code" before type
>> analysis, so I'm thinking it may need to be a special phase, perhaps
>> part of the fused-type-specialization phase. Here's another idea:
>>
>> cdef foo(numeric x):
>>     if numeric in floating:
>>         ...
>>     elif numeric is long:
>>         ...
>>     else:
>>         ...
>>     print numeric is double   # after the specialization pass, this
>> would be a literal True/False node.
>>
>> Again, this would all be resolved before type analysis.
>
> Hmm, I wonder, if we ever want to start with whole program analysis, and we
> find code like this:
>
>    def func(arg):
>        ...
>
>    a = [1,2,3]
>    func(a)
>
> we could infer that "arg" is actually a "fused_type(object, list)". So, I
> think, what we eventually want is an intermingling of type analysis and
> specialisation. Meaning, we'd find a new type during type analysis or
> inference, split off a new version of the function and then analyse it. But
> maybe that's just a pie in the sky for now.

This fits into the idea of creating two (or possibly more, but
avoiding combinatorial explosion) branches, a fast one and a safe one,
and bailing from one to the other if guards fail (all within the same
function).


More information about the cython-devel mailing list