On Nov 3, 2009, at 10:15 AM, Lisandro Dalcin wrote:

> On Tue, Nov 3, 2009 at 3:06 PM, Dag Sverre Seljebotn
> <[email protected]> wrote:
>> Lisandro Dalcin wrote:
>>
>>>
>>> Do you remember that I advocated for "ctypedef some int MyInt" or
>>> something similar? If right now we had that, Cython could reject  
>>> some
>>> things, like binops on different "ctypedef some .." types, requiring
>>> users to introduce casts to resolve the ambiguity... A said it  
>>> before,
>>> and I say it again: second-guessing is a bad thing (or, in Python's
>>> Zen words: "In the face of ambiguity, refuse the temptation to
>>> guess.")
>>>
>> I remember very well, and I've been thinking about it the whole  
>> day. I
>> wholeheartedly agree with you that the situation is not good.

I think in generally this is an unsoveable problem as the Cython stage  
completes before the C stage starts (and generating code for all  
possible permutations isn't feasible in general). This means also that  
the author of the code doesn't (necessarily) know the size of the  
external types before C compile time, and they may change from  
platform to platform.

We're still going to have to deal with this for function overloading  
(and there it's even nastier, as sizeof(a) >= sizeof(b) has different  
semantics from sizeof(a) == sizeof(b)).

>> Another, perhaps more "backwards-compatible" approach is
>> (backwards-compatible in the following sense: It will break code that
>> should be broken and fixed, and not suddenly introduce bugs that are
>> hard to find):
>>
>>  a) Tighten down everything so that explicit casts are needed even  
>> for
>> stuff like this:
>>
>> cdef long i
>> cdef external_typedef_int j
>> print i / j # not allowed, must do i / <long>j
>>
>
> OK, +1 on this...

I think this may be too much of a backwards incompatible change. Would  
one then have to do

cdef external_typedef_int j
print j / <external_typedef_int>2
print <long>j / 2

?

The phrase "should be broken and fixed" is somewhat subjective. Care  
should be taken when marking something that is potentially broken as  
something that is definitely broken.

At the very least we should start with a directive that emits warnings  
or errors to see how much stuff it breaks and how constraining it is  
to work with first.

Note that if we require casts, I can see people putting them in just  
to get their code to compile (without thinking of the full  
ramifications--or even if they do they might not know which of the two  
is actually wider, or it may be different on their system rather than  
their users). If this causes bugs down the line, it will be harder to  
track down than if it simply emitted an (optional or not) warning at  
that point.

>>  b) Add "exact" instead of "some"
>> cdef extern ...:
>>    ctypedef long!  mylong
>>
>
> Well, I'm still thinking that "ctypedef int MyInt" should actually
> mean exact... However, I realize that this is going to be a source of
> code breakage.

Lots of code breakage in Sage I could imagine. (And I don't think any  
of that code is actually broken, its stuff like flags (boolean ops  
count as arithmatic) or the mpfr precision type, etc. where size may  
be platform dependent but doesn't really need to be known).

>> Code is then inserted during module loading which ensures  
>> sizeof(long)
>> == sizeof(mylong).
>>
>
> Mmm... Do "ensure" means a import failure? Perhaps a warning would
> better? Perhaps a mismatch does not necessarily means the code is
> broken...

If you really want this (and it would seem to create highly non- 
portable code if you did, which mostly defeats the purpose of using  
external types in the first place) then you could stick an

assert sizeof(long) == sizeof(mylong)

right at the top of your module. Much more explicit, and needs no  
extra syntax.

>> However I seem to remember that this was rejected as well by Robert
>> (who, for some reason I can't understand, seems to think the current
>> situation is OK.)
>
> Perhaps we were not clear enough at that time, and Robert rejected the
> idea because it introduced new syntax?


If I recall, my two primary concerns were that it was too large of a  
backwards incompatible change (at least to make it so by default right  
off), and that we hadn't come up with the right syntax yet. In  
particular, I really liked the idea of partially ranked types, so one  
could have

short <= int <= long <= long long
int16 < int32 < int64
int16 <= short
...

which I think would make things much less painful, but we have yet to  
come up with a good way of specifying that. I think we're to the point  
that only ranking matters, not exact size. I'm more in favor of being  
able to specify a type as unranked, than have all extern types be  
unranked by default and having a keyword to specify types as exact.

- Robert

_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev

Reply via email to