[m-dev.] integer conversions

Zoltan Somogyi zoltan.somogyi at runbox.com
Tue May 26 08:20:59 AEST 2020


2020-05-25 17:35 GMT+10:00 Peter Wang<novalazy at gmail.com>:
> I made a table of the predicates and functions for converting between
> integer types (attached).

Thanks for that.

> Should we add any of the following, or others?

I think we should start by deciding what principles should govern
what conversion predicates or functions should exist; the identities
of those predicates/functions will then follow.

There are several dimensions on which the conversions differ.

Dimension 1 is whether the conversion can fail for some values
of the FromType, and if so, how to we handle it. The possibilities are

1a the conversion cannot fail, e.g. int8.to_int,

1b the conversion can fail, and so can the predicate, e.g. int8.from_int,

1c  the conversion can fail, but the predicate throws an exception when
   this happens, e.g. int8.det_from_int, and

1d the conversion can fail, but the predicate returns a mathematically
   unsound result instead of failing or throwing, e.g. int8.cast_from_int.

Since all four variants exist, and since I don't recall anyone objecting
to their addition, we seem to agree that all four kinds are justified in
some cases. But we haven't discussed exactly *which* cases.

It seems clear that we shouldn't have the 1a variant for conversions
that can fail. But should we have some or all of the 1b, 1c and 1d
variants for conversion that cannot fail? I think the answer should be "no"
for 1b and 1c, but there is a case for 1d, i.e. cast operations that
happen to always produce a mathematically correct result.

Dimension 2 is whether the conversion is done by a predicate or
function. This depends on Dimension 1. 1a, 1c and 1d are det and therefore
can be done by a function, but 1b is semidet, and therefore should be done
by a predicate. But should there be predicate versions of 1a, 1c and 1d
as well? I vote no, since the presence of predicate versions complicates
error messages, especially when higher order code is involved.

Dimension 3 is whether we convert from FromType to ToType
using a predicate/function in the FromType module, such as int8.to_int,
or one in the ToType module, such as int.from_int8. In this dimension,
I think what we should strive for is consistency. I see three reasonable
choices:

3a  all conversion predicates/functions are in FromType's module ONLY

3b all conversion predicates/functions are in ToType's module ONLY

3c all conversion predicates/functions are in BOTH FromType's module AND
    ToType's module.

I think option 3c has too many predicates, but reaching either 3a or 3b
would require deleting existing predicates, including predicates
in the 2020 stable release, which would require obsoleting them first.
In this dimension, I have no preference.

Dimension 4 is symmetry: is we support conversion from type A to type B,
should we support conversion from type B to type A? I vote yes.

Dimension 5 is what type pairs we should support.

5a conversions between int and uint

5b conversions between int and intN, and between uint and uintN

5c conversions between intN and uintN

5d conversions between int and uintN, and between uint and intN

5e conversions between intN and uintM where N != M

Dimensions 5a and 5b are done, and I think 5c is as well. I don't see
a burning need for 5d and 5e, and they can be done in two steps
(one to change signedness, and one to change size), so I would
vote against these.

Comments?

Zoltan.


More information about the developers mailing list