Hi Jeff and Michael --

I'm realizing that my example code didn't quite capture the question that 
I'd intended to be asking, though the additional question is interesting 
as well...


Michael wrote:

> ...[won't] information lost if i is too large for even transforming it 
> into a real(32)? An int(32) will need these 32 Bit completely for the 
> integer part but a real(32) needs them for both the integer/exponent and 
> the fraction parts.

This was the crux of what I was getting at: Given that int(32) -> real(32) 
coercions are lossy, should they be supported by default?

In attempting to ask this in a way that wouldn't lead the reader in a 
specific direction, I ended up asking a slightly different question that 
Jeff's response highlighted:

> This should throw a compile-time error about ambiguous type promotion. 
> ...
> Forcing the programmer to be explicit requires more work up front but 
> mitigates a variety of nasty surprises later.
> ...
> I can't remember what C++ does with this sort of thing...

Based on my experimentation, C++ seems to flag the ambiguity, as you 
suggest here.


The question that I thought I was asking was meant to be less about 
preference when given both 'real(32)' and 'real(64)' choices, and more 
about whether 'int(32)' should coerce to 'real(32)' at all.  Yet because I 
was trying to avoid tipping my hand as to what we did today, I obfuscated 
the question enough that I ended up with the issue that you address here.

So maybe the more direct question should've been:  What should happen in 
this case:

        var i: int(32) = 42;

        foo(i);

        proc foo(x: real(32)) { writeln("In 'real(32)' foo()"); }


Where some options are:

a) The compiler should complain that there isn't an appropriate overload
    of foo().  I.e., coercions from int(32) to real(32) are lossy, so
    should not happen automatically.

b) The int(32) is coerced to a real(32) and foo() is called

c) Same as (b), but a compile-time warning is also generated warning of
    the potential for loss of data.

Again, we're curious for thoughts on this question.


--------------------------------------------------------------------
---- If you want to think about this on your own without being  ----
---- influenced by other solutions, stop reading here.          ----
--------------------------------------------------------------------


Cutting to the chase a bit:

* today Chapel does (a)
* my C++ compiler does (b)
* StackOverflow suggests that some C++ compilers do (c)

Note that because of what Chapel does today, the implication is that in 
yesterday's question, the 64-bit version would be called since the 32-bit 
version isn't an option.

One of the places where this can potentially cause a surprise (depending 
on what you expect) is:

        var x = 42: int(32);
        var y = 4.2: real(32);

        var z = x + y;
        writeln(typeToString(z.type));

Which generates 'real(64)' as its answer.  I.e., math on two 32-bit values 
(albeit 32-bit values of different types) results in a 64-bit value.

The reason this happens is that the relevent overloads of + are:

        proc +(x: int(?t), y: int(t)): int(t) ...
        proc +(x: real(32), y: real(32)): real(32) ...
        proc +(x: real(64), y: real(64)): real(64) ...

* The first isn't valid since real's don't coerce to int's.
* The second isn't valid since int(32)s don't coerce to real(32)s.
* That leaves the third option, producing a real(64).

-Brad


------------------------------------------------------------------------------
_______________________________________________
Chapel-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/chapel-users

Reply via email to