[Cython] Fused Types

mark florisson markflorisson88 at gmail.com
Fri Apr 29 17:04:28 CEST 2011


On 29 April 2011 06:32, Robert Bradshaw <robertwb at math.washington.edu> wrote:
> 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. In terms of
> syntactically supporting pointers, we could either support "fused_type
> is typeof(void*)" or require typedefs for types not representable by
> an ExprNode. (This would make declaring fused types syntactically
> simpler as well...) I prefer the latter.
>
> - Robert
>

I made both things work, you can use both typeof() on expressions and
you can compare types using 'is' and 'in'. However, with typeof() it
doesn't remove branches, so if you're doing incompatible stuff you
need to do the type matching. It could be supported, but currently it
isn't because TransformBuiltinMethods runs after
AnalyseDeclarationsTransform (for which the reason is not immediately
apparent).

With the type matching it matches on exactly 'if src_type is
dst_type:' so you can't use 'and' and such... perhaps I should turn
these expression into a node with the constant value first and then
see if the result of the entire expression is known at compile time?


More information about the cython-devel mailing list