[M3devel] mixing INTEGER and LONGINT?

Rodney M. Bates rodney_bates at lcwb.coop
Fri Jan 8 20:25:50 CET 2010



Tony Hosking wrote:
> Let's have a clean language proposal before thinking about implementing it...  ;-)
> 
> I continue to oppose mixing operations on both LONGINT and INTEGER.  Just as one cannot mix REAL and LONGREAL.
> I may accept checked assignability between INTEGER and LONGINT (after all, the bits are the same, its just a matter of how many are significant -- unlike REAL/LONGREAL/EXTENDED).
> 
> Looking further at the assignability rules:
> 
> A type T is assignable to a type U if:
> 
> 	• T <: U, or
> 	• U <: T and T is an array or a reference type other than ADDRESS (This restriction is lifted in unsafe modules.), or
> 	• T and U are ordinal types with at least one member in common.
> 
> This suggests that we don't really need to say that INTEGER <: LONGINT.

I once considered adding this subtype relation as a way of not requiring the ORD/VAL coding,
but it has some additional other consequences that I considered undesirable.  I don't
remember what they were off the top of my head, but could no doubt reconstruct them,
if anybody cares.

> 
> We can simply rely on the third clause regarding their both being ordinal types with at least one member in common.  Then assignment simply needs to test that the values are in range.

Yes, this is exactly what I am saying.  To require the ORD/VAL calls, we would have
do one of:

1) Say LONGINT is not an ordinal type.

2) Say that 10 and 10L are not only expressions of different types, but
    also distinct values as well.  The low values of LONGINT and the
    corresponding values of INTEGER would not be the same.

3) Alter the definition of assignability, for example to say in the third clause,
    that T and U must have the same base type as well as a member in common.

Doing 1) Runs strongly against my intuitive sense of what "ordinal" means.  It would
also mean there would be no subranges of LONGINT and probably eliminate several
other things you might expect to come along with LONGINT.

Doing 2) Seems like a big contradiction to the way subranges work and the existing
Modula-3 philosophy of types sometimes having overlapping value sets.

Which leaves 3), which I think is the only reasonable way to do this.

If we leave this as is, it will follow that assignment statements and mixed arithmetic
are legal and work the same way as with different subranges of the same base type.
Given the liberal assignability rules we already have, I don't think this is
necessarily a bad idea, despite my general bias toward requiring more stuff to
be explicit in code.  There are about 8 or 9 places, as I recall, that would be
affected because they require only assignability.

The definitions of the arithmetic operators would have to be treated with some care
to avoid allowing or requiring that INTEGER <op> INTEGER be done in LONGINT machine
arithmetic, something we absolutely must avoid.  This points out where the analogy
to subranges does not apply to INTEGER/LONGINT.  With subranges, the only reasonable
implementation is to expand the operands to the base type and do the arithmetic
in that size.  Here, we don't want that to happen unless at least one operand is
LONGINT.

On a side note, I do not believe the analogy to the floating types applies here.
With INTEGER/LONGINT, there is a very obvious and natural equivalence between
the values of INTEGER and the lower values of LONGINT.  Not necessarily so with
different native machine floating types.  The messiness of floating representation
means you can't assume the exactly representable reals are the same for two different
floating types, even within some restricted value range.



> 
> On 8 Jan 2010, at 02:44, Jay K wrote:
> 
>> This simple diff in the front end allows the "obvious" mixing of INTEGER and LONGINT without any need for ORD or VAL.
>>  
>>   LONGINT + INTEGER => LONGINT 
>>   LONGINT - INTEGER => LONGINT 
>>   LONGINT * INTEGER => LONGINT 
>>   LONGINT DIV INTEGER => LONGINT 
>>   INTEGER DIV LONGINT => LONGINT (subtle and I think incorrect, should be INTEGER) 
>>   INTEGER MOD LONGINT => INTEGER (subtle but I believe correct)  
>>   LONGINT MOD INTEGER => INTEGER (subtle but I believe correct)  
>>   MIN(INTEGER, LONGINT) => LONGINT (This is wrong actually, should be INTEGER)  
>>   MAX(INTEGER, LONGINT) => LONGINT  
>>   LONGINT := INTEGER 
>>  
>> Other mixes are less obvious and would require runtime checks.
>>  
>> I think the backend will just work but I haven't tried that yet.
>>  (Truth be told, I can only affectively edit files on NT...)
>>  
>> Thoughts?
>>  
>



More information about the M3devel mailing list