www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - sqrt(2) must go

reply Don <nospam nospam.com> writes:
In D2 prior to 2.048, sqrt(2) does not compile. The reason is that it's 
ambiguous whether it is sqrt(2.0), sqrt(2.0L), or sqrt(2.0f). This also 
applies to _any_ function which has overloads for more than one floating 
point type.

In D2 between versions 2.049 and the present, sqrt(2) compiles due to 
the request of a small number of people (2-3, I think). But still, no 
other floating point function works with integer literals.

The "bug" being fixed was
Bugzilla 4455: Taking the sqrt of an integer shouldn't require an 
explicit cast.

This compiles only due to an awful, undocumented hack in std.math. It 
doesn't work for any function other than sqrt. I protested strongly 
against this, but accepted it only on the proviso that we would fix 
integer literal conversions to floating point in _all_ cases, so that 
the hack could be removed.

However, when I proposed the fix on the newsgroup (integer literals 
should have a preferred conversion to double), it was *unanimously* 
rejected. Those who had argued for the hack were conspicuously absent.

The hack must go.
Oct 19 2011
next sibling parent reply =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= <xtzgzorex gmail.com> writes:
On 19-10-2011 18:18, Don wrote:
 In D2 prior to 2.048, sqrt(2) does not compile. The reason is that it's
 ambiguous whether it is sqrt(2.0), sqrt(2.0L), or sqrt(2.0f). This also
 applies to _any_ function which has overloads for more than one floating
 point type.

 In D2 between versions 2.049 and the present, sqrt(2) compiles due to
 the request of a small number of people (2-3, I think). But still, no
 other floating point function works with integer literals.

 The "bug" being fixed was
 Bugzilla 4455: Taking the sqrt of an integer shouldn't require an
 explicit cast.

 This compiles only due to an awful, undocumented hack in std.math. It
 doesn't work for any function other than sqrt. I protested strongly
 against this, but accepted it only on the proviso that we would fix
 integer literal conversions to floating point in _all_ cases, so that
 the hack could be removed.

 However, when I proposed the fix on the newsgroup (integer literals
 should have a preferred conversion to double), it was *unanimously*
 rejected. Those who had argued for the hack were conspicuously absent.

 The hack must go.

What on earth does it matter? It's just a cast. And when typing out floating-point literals, it *really* does not hurt to type 2.0f instead of 2. In .NET land, people live with this just fine (see System.Math.Sqrt). Why can't we? I say kill the hack. - Alex
Oct 19 2011
next sibling parent =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= <xtzgzorex gmail.com> writes:
On 19-10-2011 18:22, Alex R°nne Petersen wrote:
 On 19-10-2011 18:18, Don wrote:
 In D2 prior to 2.048, sqrt(2) does not compile. The reason is that it's
 ambiguous whether it is sqrt(2.0), sqrt(2.0L), or sqrt(2.0f). This also
 applies to _any_ function which has overloads for more than one floating
 point type.

 In D2 between versions 2.049 and the present, sqrt(2) compiles due to
 the request of a small number of people (2-3, I think). But still, no
 other floating point function works with integer literals.

 The "bug" being fixed was
 Bugzilla 4455: Taking the sqrt of an integer shouldn't require an
 explicit cast.

 This compiles only due to an awful, undocumented hack in std.math. It
 doesn't work for any function other than sqrt. I protested strongly
 against this, but accepted it only on the proviso that we would fix
 integer literal conversions to floating point in _all_ cases, so that
 the hack could be removed.

 However, when I proposed the fix on the newsgroup (integer literals
 should have a preferred conversion to double), it was *unanimously*
 rejected. Those who had argued for the hack were conspicuously absent.

 The hack must go.

What on earth does it matter? It's just a cast. And when typing out floating-point literals, it *really* does not hurt to type 2.0f instead of 2. In .NET land, people live with this just fine (see System.Math.Sqrt). Why can't we? I say kill the hack. - Alex

PS: What's wrong with converting integer literals to double? It's a lossless conversion, no? - Alex
Oct 19 2011
prev sibling parent "Marco Leise" <Marco.Leise gmx.de> writes:
Am 19.10.2011, 18:25 Uhr, schrieb Alex R=C3=B8nne Petersen  =

<xtzgzorex gmail.com>:

 On 19-10-2011 18:22, Alex R=C3=B8nne Petersen wrote:
 On 19-10-2011 18:18, Don wrote:
 In D2 prior to 2.048, sqrt(2) does not compile. The reason is that i=



 ambiguous whether it is sqrt(2.0), sqrt(2.0L), or sqrt(2.0f). This a=



 applies to _any_ function which has overloads for more than one  =



 floating
 point type.

 In D2 between versions 2.049 and the present, sqrt(2) compiles due t=



 the request of a small number of people (2-3, I think). But still, n=



 other floating point function works with integer literals.

 The "bug" being fixed was
 Bugzilla 4455: Taking the sqrt of an integer shouldn't require an
 explicit cast.

 This compiles only due to an awful, undocumented hack in std.math. I=



 doesn't work for any function other than sqrt. I protested strongly
 against this, but accepted it only on the proviso that we would fix
 integer literal conversions to floating point in _all_ cases, so tha=



 the hack could be removed.

 However, when I proposed the fix on the newsgroup (integer literals
 should have a preferred conversion to double), it was *unanimously*
 rejected. Those who had argued for the hack were conspicuously absen=



 The hack must go.

What on earth does it matter? It's just a cast. And when typing out floating-point literals, it *really* does not hurt to type 2.0f inste=


 of 2. In .NET land, people live with this just fine (see
 System.Math.Sqrt). Why can't we?

 I say kill the hack.

 - Alex

PS: What's wrong with converting integer literals to double? It's a =

 lossless conversion, no?

 - Alex

As long as it is not a 64-bit integer, yes. More philosophical, I think integer math should be separate from FP math= , = because it has different semantics (integer division with remainder, = overflow vs. infinity, fixed steps vs. exponent, shifting, ...). So I = think .NET handles this correctly. But converting 32-bit ints to double = = shouldn't harm much either. JavaScript has no integers, only doubles. It= = works. When you come across a for loop there and think to yourself "it incremen= ts = a variant that stores a double there", you can laugh or cry. (Actually = good JS engines optimize that case, of course.)
Oct 19 2011
prev sibling next sibling parent reply Jesse Phillips <jessekphillips+D gmail.com> writes:
Don Wrote:

 However, when I proposed the fix on the newsgroup (integer literals 
 should have a preferred conversion to double), it was *unanimously* 
 rejected. Those who had argued for the hack were conspicuously absent.
 
 The hack must go.
 

I agree. If we should have a proper fix, or no fix at all. If it isn't going to compile then be sure it is documented. While it will be strange not having it compile it does make sense that when dealing with floating point you should choose its size.
Oct 19 2011
next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
That call "return sqrt(f);" should have been "return sqrt!F(f)" that
forwards to sqrt functions that take floats/doubles/reals. Again these
would be templates.. it's a shame templates still can't overload
against functions.
Oct 19 2011
prev sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
http://codepad.org/4g0hXOse

Too much?
Oct 19 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
You could maybe ease transition for people that rely on this behavior via:

import std.traits;

auto sqrt(F, T)(T x) { return sqrt(cast(F)x); }

auto sqrt(F)(F f)
    if (!isIntegral!F)
{
    return sqrt(f);
}

void main()
{
    int x = 1;
    sqrt(4);         // ng
    sqrt!float(x);   // ok
    sqrt(4.5);       // ok
}

It sure is shorter to type than cast(float). Then again it's templated
so maybe that's not too nice for std.math.
Oct 19 2011
prev sibling next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Don:

 However, when I proposed the fix on the newsgroup (integer literals 
 should have a preferred conversion to double), it was *unanimously* 
 rejected.

I don't remember the rationale of those refusals. Do you have a link to the discussion? Bye, bearophile
Oct 19 2011
prev sibling next sibling parent reply dsimcha <dsimcha yahoo.com> writes:
== Quote from Don (nospam nospam.com)'s article
 In D2 prior to 2.048, sqrt(2) does not compile. The reason is that it's
 ambiguous whether it is sqrt(2.0), sqrt(2.0L), or sqrt(2.0f). This also
 applies to _any_ function which has overloads for more than one floating
 point type.
 In D2 between versions 2.049 and the present, sqrt(2) compiles due to
 the request of a small number of people (2-3, I think). But still, no
 other floating point function works with integer literals.
 The "bug" being fixed was
 Bugzilla 4455: Taking the sqrt of an integer shouldn't require an
 explicit cast.
 This compiles only due to an awful, undocumented hack in std.math. It
 doesn't work for any function other than sqrt. I protested strongly
 against this, but accepted it only on the proviso that we would fix
 integer literal conversions to floating point in _all_ cases, so that
 the hack could be removed.
 However, when I proposed the fix on the newsgroup (integer literals
 should have a preferred conversion to double), it was *unanimously*
 rejected. Those who had argued for the hack were conspicuously absent.
 The hack must go.

No. Something as simple as sqrt(2) must work at all costs, period. A language that adds a bunch of silly complications to something this simple is fundamentally broken. I don't remember your post on implicit preferred conversions, but IMHO implicit conversions of integer to double is a no-brainer. Requiring something this simple to be explicit is Java/Pascal-like overkill on explicitness.
Oct 19 2011
next sibling parent reply "Marco Leise" <Marco.Leise gmx.de> writes:
Am 19.10.2011, 20:12 Uhr, schrieb dsimcha <dsimcha yahoo.com>:

 No.  Something as simple as sqrt(2) must work at all costs, period.  A  
 language
 that adds a bunch of silly complications to something this simple is  
 fundamentally
 broken.  I don't remember your post on implicit preferred conversions,  
 but IMHO
 implicit conversions of integer to double is a no-brainer.  Requiring  
 something
 this simple to be explicit is Java/Pascal-like overkill on explicitness.

Pascal (FreePascal 2.4.0) allows sqrt(2) just fine.
Oct 19 2011
parent dsimcha <dsimcha yahoo.com> writes:
== Quote from Marco Leise (Marco.Leise gmx.de)'s article
 Am 19.10.2011, 20:12 Uhr, schrieb dsimcha <dsimcha yahoo.com>:
 No.  Something as simple as sqrt(2) must work at all costs, period.  A
 language
 that adds a bunch of silly complications to something this simple is
 fundamentally
 broken.  I don't remember your post on implicit preferred conversions,
 but IMHO
 implicit conversions of integer to double is a no-brainer.  Requiring
 something
 this simple to be explicit is Java/Pascal-like overkill on explicitness.


LOL and Pascal was my example of a bondage-and-discipline language. All the more reason why we need to allow it in D come Hell or high water.
Oct 19 2011
prev sibling next sibling parent Russel Winder <russel russel.org.uk> writes:
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Wed, 2011-10-19 at 19:12 +0000, dsimcha wrote:
[ . . . ]
 LOL and Pascal was my example of a bondage-and-discipline language.  All =

 reason why we need to allow it in D come Hell or high water.

Bondage. Discipline. Does this mean Lady Heather will take control? =20 --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.n= et 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel russel.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Oct 19 2011
prev sibling next sibling parent reply Alvaro <alvaro_segura gmail.com> writes:
El 19/10/2011 20:12, dsimcha escribiˇ:
 == Quote from Don (nospam nospam.com)'s article
 The hack must go.

No. Something as simple as sqrt(2) must work at all costs, period. A language that adds a bunch of silly complications to something this simple is fundamentally broken. I don't remember your post on implicit preferred conversions, but IMHO implicit conversions of integer to double is a no-brainer. Requiring something this simple to be explicit is Java/Pascal-like overkill on explicitness.

Completely agree. I call that uncluttered programming. No excessive explicitness should be necessary when what you mean is obvious (under some simple conventions). Leads to clearer code.
Oct 19 2011
next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Alvaro:

 I call that uncluttered programming. No excessive explicitness should be 
 necessary when what you mean is obvious (under some simple conventions). 
 Leads to clearer code.

Explicitness usually means adding more annotations in the code, and this usually increases the visual noise in inside the code. This noise masks the code and often leads to mistakes. On the other hand too many implicit conversions are a well known source of bugs and troubles (both D and C# disallow some of them available in C. OCaML language disallow most of them). So the language designers must find some middle balancing point, that is somehow an optimum. Bye, bearophile
Oct 19 2011
prev sibling next sibling parent reply dsimcha <dsimcha yahoo.com> writes:
On 10/19/2011 6:25 PM, Alvaro wrote:
 El 19/10/2011 20:12, dsimcha escribiˇ:
 == Quote from Don (nospam nospam.com)'s article
 The hack must go.

No. Something as simple as sqrt(2) must work at all costs, period. A language that adds a bunch of silly complications to something this simple is fundamentally broken. I don't remember your post on implicit preferred conversions, but IMHO implicit conversions of integer to double is a no-brainer. Requiring something this simple to be explicit is Java/Pascal-like overkill on explicitness.

Completely agree. I call that uncluttered programming. No excessive explicitness should be necessary when what you mean is obvious (under some simple conventions). Leads to clearer code.

Yes, and for the most part uncluttered programming is one of D's biggest strengths. Let's not ruin it by complicating sqrt(2).
Oct 19 2011
next sibling parent reply dsimcha <dsimcha yahoo.com> writes:
On 10/19/2011 10:57 PM, Robert Jacques wrote:
 Also, 5_000_000_000 does not fit, exactly inside a double.

Yes it does. Doubles can hold integers exactly up to 2 ^^ 53. http://en.wikipedia.org/wiki/Double_precision_floating-point_format
Oct 19 2011
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 10/20/2011 05:34 AM, dsimcha wrote:
 On 10/19/2011 10:57 PM, Robert Jacques wrote:
 Also, 5_000_000_000 does not fit, exactly inside a double.

Yes it does. Doubles can hold integers exactly up to 2 ^^ 53. http://en.wikipedia.org/wiki/Double_precision_floating-point_format

5_000_000_000 even fits exactly into a IEEE 734 32-bit _float_.
Oct 20 2011
prev sibling next sibling parent dsimcha <dsimcha yahoo.com> writes:
On 10/19/2011 11:27 PM, Marco Leise wrote:
 And real can be used without protability problems on PowerPC or ARM?

Yes, it's just that they may only give 64 bits of precision. Floating point is inexact anyhow, though. IMHO the fact that you may lose a little precision with very large longs is not a game changer.
Oct 19 2011
prev sibling next sibling parent Don <nospam nospam.com> writes:
On 20.10.2011 05:01, Steven Schveighoffer wrote:
 On Wed, 19 Oct 2011 22:57:48 -0400, Robert Jacques <sandford jhu.edu>
 wrote:

 On Wed, 19 Oct 2011 22:52:14 -0400, Marco Leise <Marco.Leise gmx.de>
 wrote:
 Am 20.10.2011, 02:46 Uhr, schrieb dsimcha <dsimcha yahoo.com>:

 On 10/19/2011 6:25 PM, Alvaro wrote:
 El 19/10/2011 20:12, dsimcha escribi├│:
 == Quote from Don (nospam nospam.com)'s article
 The hack must go.

No. Something as simple as sqrt(2) must work at all costs, period. A language that adds a bunch of silly complications to something this simple is fundamentally broken. I don't remember your post on implicit preferred conversions, but IMHO implicit conversions of integer to double is a no-brainer. Requiring something this simple to be explicit is Java/Pascal-like overkill on explicitness.

Completely agree. I call that uncluttered programming. No excessive explicitness should be necessary when what you mean is obvious (under some simple conventions). Leads to clearer code.

Yes, and for the most part uncluttered programming is one of D's biggest strengths. Let's not ruin it by complicating sqrt(2).

What is the compiler to do with sqrt(5_000_000_000) ? It doesn't fit into an int, but it fits into a double.

Simple, is a 5_000_000_000 long, and longs convert to reals. Also, 5_000_000_000 does not fit, exactly inside a double.

It doesn't? I thought double could do 53 bits? Although I agree, long should map to real, because obviously not all longs fit into a double exactly. -Steve

But ulong.max does NOT fit into an 80-bit real. And long won't fit into real on anything other than x86, 68K, and Itanium. I don't think long and ulong should ever implicitly convert to floating point types. Note that you can just do *1.0 or *1.0L if you want to convert them. Currently long implicitly converts even to float. This seems quite bad, it loses 60% of its bits!! Suppose we also banned implicit conversions int->float and uint->float (since float only has 24 bits, these are lossy conversions, losing 25% of the bits). Now that we've disallowed lossy integral conversions, it really seems that we should disallow these ones as well. If that was all we did, it would also mean that things like short+short wouldn't convert to float either, because C converts everything to int whenever it gets an opportunity. But we could use range checking to restore this (and to allow small longs to fit into doubles: allow conversion to double if it's <= 53 bits, allow conversion to float if <= 24 bits).
Oct 20 2011
prev sibling parent reply Don <nospam nospam.com> writes:
On 20.10.2011 09:47, Manu wrote:
 Many architectures do not support real, and therefore it should never be
 used implicitly by the language.

 Precision problems aside, I would personally insist that implicit
 conversation from any sized int always be to float, not double, for
 performance reasons (the whole point of a compiled language trying
 to supersede C/C++).

On almost all platforms, float and double are the same speed. Note that what we're discussing here is parameter passing of single values; if it's part of an aggregate (array or struct), the issue doesn't arise.
Oct 20 2011
parent reply Don <nospam nospam.com> writes:
On 20.10.2011 13:12, Manu wrote:
 On 20 October 2011 11:02, Don <nospam nospam.com
 <mailto:nospam nospam.com>> wrote:

     On 20.10.2011 09:47, Manu wrote:

         Many architectures do not support real, and therefore it should
         never be
         used implicitly by the language.

         Precision problems aside, I would personally insist that implicit
         conversation from any sized int always be to float, not double, for
         performance reasons (the whole point of a compiled language trying
         to supersede C/C++).


     On almost all platforms, float and double are the same speed.


 This isn't true. Consider ARM, hard to say this isn't a vitally
 important architecture these days, and there are plenty of embedded
 architectures that don't support doubles at all, I would say it's a
 really bad idea to invent a systems programming language that excludes
 many architectures by its design... Atmel AVR is another important
 architecture.

It doesn't exclude anything. What we're talking about as desirable behaviour, is exactly what C does. If you care about performance on ARM, you'll type sqrt(2.0f). Personally, I'd rather completely eliminate implicit conversions between integers and floating point types. But that's just me.
 I maintain that implicit conversion of integers of any length should
 always target the same precision float, and that should be a compiler
 flag to specify the desired precision throughout the app (possibly
 defaulting to double).

I can't believe that you'd ever write an app without that being an upfront decision. Casually flipping it with a compiler flag?? Remember that it affects very few things (as discussed below).
 If you choose 'float' you may lose some precision obviously, but you
 expected that when you chose the options, and did the cast...

Explicit casts are not affected in any way.
     Note that what we're discussing here is parameter passing of single
     values; if it's part of an aggregate (array or struct), the issue
     doesn't arise.


 Are we? I thought we were discussing implicit conversion of ints to
 floats? This may be parameter passing, but also assignment I expect?

There's no problem with assignment, it's never ambiguous. There seems to be some confusion about what the issue is. To reiterate: void foo(float x) {} void foo(double x) {} void bar(float x) {} void baz(double x) {} void main() { bar(2); // OK -- 2 becomes 2.0f baz(2); // OK -- 2 becomes 2.0 foo(2); // fails -- ambiguous. } My proposal was effectively: if it's ambiguous, choose double. That's all.
Oct 20 2011
next sibling parent dsimcha <dsimcha yahoo.com> writes:
On 10/20/2011 8:13 AM, Don wrote:
 There's no problem with assignment, it's never ambiguous.

 There seems to be some confusion about what the issue is.
 To reiterate:

 void foo(float x) {}
 void foo(double x) {}

 void bar(float x) {}

 void baz(double x) {}

 void main()
 {
 bar(2); // OK -- 2 becomes 2.0f
 baz(2); // OK -- 2 becomes 2.0
 foo(2); // fails -- ambiguous.
 }

 My proposal was effectively: if it's ambiguous, choose double. That's all.

This proposal seems like a no-brainer to me. I sincerely apologize for not supporting it before. I looked at when it was created, and I realized that I was with my family for Christmas/New Years at the time, with little time to spend on the D newsgroup.
Oct 20 2011
prev sibling next sibling parent reply Don <nospam nospam.com> writes:
On 20.10.2011 14:48, Manu wrote:
 On 20 October 2011 15:13, Don <nospam nospam.com
 <mailto:nospam nospam.com>> wrote:

     On 20.10.2011 13:12, Manu wrote:

         On 20 October 2011 11:02, Don <nospam nospam.com
         <mailto:nospam nospam.com>
         <mailto:nospam nospam.com <mailto:nospam nospam.com>>> wrote:

             On 20.10.2011 09:47, Manu wrote:

                 Many architectures do not support real, and therefore it
         should
                 never be
                 used implicitly by the language.

                 Precision problems aside, I would personally insist that
         implicit
                 conversation from any sized int always be to float, not
         double, for
                 performance reasons (the whole point of a compiled
         language trying
                 to supersede C/C++).


             On almost all platforms, float and double are the same speed.


         This isn't true. Consider ARM, hard to say this isn't a vitally
         important architecture these days, and there are plenty of embedded
         architectures that don't support doubles at all, I would say it's a
         really bad idea to invent a systems programming language that
         excludes
         many architectures by its design... Atmel AVR is another important
         architecture.


     It doesn't exclude anything. What we're talking about as desirable
     behaviour, is exactly what C does. If you care about performance on
     ARM, you'll type sqrt(2.0f).

     Personally, I'd rather completely eliminate implicit conversions
     between integers and floating point types. But that's just me.


         I maintain that implicit conversion of integers of any length should
         always target the same precision float, and that should be a
         compiler
         flag to specify the desired precision throughout the app (possibly
         defaulting to double).


     I can't believe that you'd ever write an app without that being an
     upfront decision. Casually flipping it with a compiler flag??
     Remember that it affects very few things (as discussed below).


         If you choose 'float' you may lose some precision obviously, but you
         expected that when you chose the options, and did the cast...


     Explicit casts are not affected in any way.

             Note that what we're discussing here is parameter passing of
         single
             values; if it's part of an aggregate (array or struct), the
         issue
             doesn't arise.


         Are we? I thought we were discussing implicit conversion of ints to
         floats? This may be parameter passing, but also assignment I expect?


     There's no problem with assignment, it's never ambiguous.

     There seems to be some confusion about what the issue is.
     To reiterate:

     void foo(float x) {}
     void foo(double x) {}

     void bar(float x) {}

     void baz(double x) {}

     void main()
     {
        bar(2); // OK -- 2 becomes 2.0f
        baz(2); // OK -- 2 becomes 2.0
        foo(2); // fails -- ambiguous.
     }

     My proposal was effectively: if it's ambiguous, choose double.
     That's all.


 Yeah sorry, I think you're right, the discussion got slightly lost in
 the noise here...

 Just to clarify, where you advocate eliminating implicit casting, do you
 now refer to ALL implicit casting? Or just implicit casting to an
 ambiguous target?

 Let me reposition myself to suit what it would seem is actually being
 discussed... :)

 void sqrt(float x);
 void sqrt(double x);
 void sqrt(real x);

 {
    sqrt(2);
 }

 Surely this produces some error: "Ambiguous call to overloaded
 function", and then there is no implicit cast rule to talk about... end
 of discussion?

 But you speak of "eliminating implicit casting" as if this may also
 refer to:

 void NotOverloaded(float x);

 {
    NotOverloaded(2); // not ambiguous... so what's the problem?
 }

Actually there is a problem there, I think. If someone later on adds NotOverload(double x), that call will suddenly stop compiling. That isn't just a theoretical problem. Currently log(2) will compile, but only because in std.math there is log(real), but not yet log(double) or log(float). So once we add those overloads, peoples code will break. I'd like to get to the situation where those overloads can be added without breaking peoples code. The draconian possibility is to disallow them in all cases: integer types never match floating point function parameters. The second possibility is to introduce a tie-breaker rule: when there's an ambiguity, choose double. And a third possibility is to only apply that tie-breaker rule to literals. And the fourth possibility is to keep the language as it is now, and allow code to break when overloads get added. The one I really, really don't want, is the situation we have now: #5: whenever an overload gets added, introduce a hack for that function...
 or:

 float x = 10;

 Which I can imagine why most would feel this is undesirable...

 I'm not clear now where you intend to draw the lines.
 If you're advocating banning ALL implicit casting between float/int
 outright, I actually feel really good about that idea. I can just
 imagine the number of hours saved while optimising where junior/ignorant
 programmers cast back and fourth with no real regard to or awareness of
 what they're doing.

 Or are we only drawing the distinction for literals?
 I don't mind a compile error if I incorrectly state the literal a
 function expects. That sort of thing becomes second nature in no time.

I don't know. I think I probably prefer possibility #1 on my list, but it'd break existing code. I also like #2 and #3, and I think they'd be more generally popular. I don't like #4, but anything is better than #5.
Oct 20 2011
parent reply Don <nospam nospam.com> writes:
On 21.10.2011 05:24, Robert Jacques wrote:
 On Thu, 20 Oct 2011 09:11:27 -0400, Don <nospam nospam.com> wrote:
 [snip]
 I'd like to get to the situation where those overloads can be added
 without breaking peoples code. The draconian possibility is to disallow
 them in all cases: integer types never match floating point function
 parameters.
 The second possibility is to introduce a tie-breaker rule: when there's
 an ambiguity, choose double.
 And a third possibility is to only apply that tie-breaker rule to
 literals.
 And the fourth possibility is to keep the language as it is now, and
 allow code to break when overloads get added.

 The one I really, really don't want, is the situation we have now:
 #5: whenever an overload gets added, introduce a hack for that
 function...

I agree that #5 and #4 not acceptable longer term solutions. I do CUDA/GPU programming, so I live in a world of floats and ints. So changing the rules does worries me, but mainly because most people don't use floats on a daily basis, which introduces bias into the discussion.

Yeah, that's a valuable perspective. sqrt(2) is "I don't care what the precision is". What I get from you and Manu is: if you're working in a float world, you want float to be the tiebreaker. Otherwise, you want double (or possibly real!) to be the tiebreaker. And therefore, the
 Thinking it over, here are my suggestions, though I'm not sure if 2a or
 2b would be best:

 1) Integer literals and expressions should use range propagation to use
 the thinnest loss-less conversion. If no loss-less conversion exists,
 then an error is raised. Choosing double as a default is always the
 wrong choice for GPUs and most embedded systems.
 2a) Lossy variable conversions are disallowed.
 2b) Lossy variable conversions undergo bounds checking when asserts are
 turned on.

The spec says: "Integer values cannot be implicitly converted to another type that cannot represent the integer bit pattern after integral promotion." Now although that was intended to only apply to integers, it reads as if it should apply to floating point as well.
 The idea behind 2b) would be:

 int i = 1;
 float f = i; // assert(true);
 i = int.max;
 f = i; // assert(false);

That would be catastrophically slow. I wonder how painful disallowing lossy conversions would be.
Oct 20 2011
parent Don <nospam nospam.com> writes:
On 21.10.2011 09:53, Manu wrote:
 On 21 October 2011 09:00, Don <nospam nospam.com
 <mailto:nospam nospam.com>> wrote:

     On 21.10.2011 05:24, Robert Jacques wrote:

         On Thu, 20 Oct 2011 09:11:27 -0400, Don <nospam nospam.com
         <mailto:nospam nospam.com>> wrote:
         [snip]

             I'd like to get to the situation where those overloads can
             be added
             without breaking peoples code. The draconian possibility is
             to disallow
             them in all cases: integer types never match floating point
             function
             parameters.
             The second possibility is to introduce a tie-breaker rule:
             when there's
             an ambiguity, choose double.
             And a third possibility is to only apply that tie-breaker
             rule to
             literals.
             And the fourth possibility is to keep the language as it is
             now, and
             allow code to break when overloads get added.

             The one I really, really don't want, is the situation we
             have now:
             #5: whenever an overload gets added, introduce a hack for that
             function...


         I agree that #5 and #4 not acceptable longer term solutions. I do
         CUDA/GPU programming, so I live in a world of floats and ints. So
         changing the rules does worries me, but mainly because most
         people don't
         use floats on a daily basis, which introduces bias into the
         discussion.


     Yeah, that's a valuable perspective.
     sqrt(2) is "I don't care what the precision is".
     What I get from you and Manu is:
     if you're working in a float world, you want float to be the tiebreaker.
     Otherwise, you want double (or possibly real!) to be the tiebreaker.

     And therefore, the


         Thinking it over, here are my suggestions, though I'm not sure
         if 2a or
         2b would be best:

         1) Integer literals and expressions should use range propagation
         to use
         the thinnest loss-less conversion. If no loss-less conversion
         exists,
         then an error is raised. Choosing double as a default is always the
         wrong choice for GPUs and most embedded systems.
         2a) Lossy variable conversions are disallowed.
         2b) Lossy variable conversions undergo bounds checking when
         asserts are
         turned on.


     The spec says: "Integer values cannot be implicitly converted to
     another type that cannot represent the integer bit pattern after
     integral promotion."
     Now although that was intended to only apply to integers, it reads
     as if it should apply to floating point as well.


         The idea behind 2b) would be:

         int i = 1;
         float f = i; // assert(true);
         i = int.max;
         f = i; // assert(false);


     That would be catastrophically slow.

     I wonder how painful disallowing lossy conversions would be.


 1: Seems reasonable for literals; "Integer literals and expressions
 should use range propagation to use
 the thinnest loss-less conversion"... but can you clarify what you mean
 by 'expressions'? I assume we're talking strictly literal expressions?

Any expression. Just as right now, long converts to int only if the long expression is guaranteed to fit into 32 bits. Of course, if it's a literal, this is very easy.
 2b: Does runtime bounds checking actually addresses the question; which
 of an ambiguous function to choose?
 If I read you correctly, 2b suggests bounds checking the implicit cast
 for data loss at runtime, but which to choose? float/double/real? We'll
 still arguing that question even with this proposal taken into
 consideration... :/

It's an independent issue.
 Perhaps I missed something?

 Naturally all this complexity assumes we go with the tie-breaker
 approach, which I'm becoming more and more convinced is a bad plan...

No, it doesn't. As I said, this is independent. Except that it does mean that some existing int->float conversions would be disallowed. EG, float foo(int x) { return x; } wouldn't compile, because x might not fit into a float without loss of accuracy.
Oct 23 2011
prev sibling next sibling parent reply "Eric Poggel (JoeCoder)" <dnewsgroup2 yage3d.net> writes:
On 10/20/2011 8:13 AM, Don wrote:
 Personally, I'd rather completely eliminate implicit conversions between
 integers and floating point types. But that's just me.

vote++
Oct 20 2011
parent reply dsimcha <dsimcha yahoo.com> writes:
== Quote from Eric Poggel (JoeCoder) (dnewsgroup2 yage3d.net)'s article
 On 10/20/2011 8:13 AM, Don wrote:
 Personally, I'd rather completely eliminate implicit conversions between
 integers and floating point types. But that's just me.


I would fork the language over this because it would break too much existing code. You can't be serious.
Oct 20 2011
parent "Eric Poggel (JoeCoder)" <dnewsgroup2 yage3d.net> writes:
On 10/20/2011 1:37 PM, dsimcha wrote:
 == Quote from Eric Poggel (JoeCoder) (dnewsgroup2 yage3d.net)'s article
 On 10/20/2011 8:13 AM, Don wrote:
 Personally, I'd rather completely eliminate implicit conversions between
 integers and floating point types. But that's just me.


I would fork the language over this because it would break too much existing code. You can't be serious.

Not saying it should be immediate. Maybe D3.
Oct 20 2011
prev sibling next sibling parent Don <nospam nospam.com> writes:
On 20.10.2011 19:28, Jonathan M Davis wrote:
 On Thursday, October 20, 2011 05:13 Don wrote:
 Personally, I'd rather completely eliminate implicit conversions between
 integers and floating point types. But that's just me.

If it's a narrowing conversion, it should require a cast. If it's not, and there's no ambguity in the conversion, then I don't see any problem with allowing the conversion to be implicit. But then again, I deal with floating point values relatively rarely, so maybe there's something that I'm missing.
 My proposal was effectively: if it's ambiguous, choose double. That's all.

Are there _any_ cases in D right now where the compiler doesn't error out on ambiguity? In all of the cases that I can think of, D chooses to give an error on ambiguity rather than making a choice for you. I'm all for an int literal being implicitly converted to a double if the function call is unambiguous and there's no loss of precision.

The problem is, the existing approach will break a lot of existing code. For example, std.math.log(2) currently compiles. But, once the overload log(double) is added, which *must* happen, that code will break. Note that there is no realistic deprecation option, either. When the overload is added, code will break immediately. If we continue with this approach, we have to accept that EVERY TIME we add a floating point overload, existing code will break. So, we either make accept that; or we make everything that will ever break, break now (accepting that some stuff _will_ break, that would never have broken); or we introduce a tie-breaker rule. The question we face is really, which is the lesser evil?
 But if there's any ambiguity, then it's
 definitely against the D way to have the compiler pick for you.

Explain why this compiles: void foo(ubyte x) {} void foo(short x) {} void foo(ushort x) {} void foo(int x) {} void foo(uint x) {} void foo(long x) {} void foo(ulong x) {} void main() { byte b = -1; foo(b); // How ambiguous can you get????? }
Oct 20 2011
prev sibling parent =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= <xtzgzorex gmail.com> writes:
On 20-10-2011 14:13, Don wrote:
 On 20.10.2011 13:12, Manu wrote:
 On 20 October 2011 11:02, Don <nospam nospam.com
 <mailto:nospam nospam.com>> wrote:

 On 20.10.2011 09:47, Manu wrote:

 Many architectures do not support real, and therefore it should
 never be
 used implicitly by the language.

 Precision problems aside, I would personally insist that implicit
 conversation from any sized int always be to float, not double, for
 performance reasons (the whole point of a compiled language trying
 to supersede C/C++).


 On almost all platforms, float and double are the same speed.


 This isn't true. Consider ARM, hard to say this isn't a vitally
 important architecture these days, and there are plenty of embedded
 architectures that don't support doubles at all, I would say it's a
 really bad idea to invent a systems programming language that excludes
 many architectures by its design... Atmel AVR is another important
 architecture.

It doesn't exclude anything. What we're talking about as desirable behaviour, is exactly what C does. If you care about performance on ARM, you'll type sqrt(2.0f). Personally, I'd rather completely eliminate implicit conversions between integers and floating point types. But that's just me.

+1.
 I maintain that implicit conversion of integers of any length should
 always target the same precision float, and that should be a compiler
 flag to specify the desired precision throughout the app (possibly
 defaulting to double).

I can't believe that you'd ever write an app without that being an upfront decision. Casually flipping it with a compiler flag?? Remember that it affects very few things (as discussed below).
 If you choose 'float' you may lose some precision obviously, but you
 expected that when you chose the options, and did the cast...

Explicit casts are not affected in any way.
 Note that what we're discussing here is parameter passing of single
 values; if it's part of an aggregate (array or struct), the issue
 doesn't arise.


 Are we? I thought we were discussing implicit conversion of ints to
 floats? This may be parameter passing, but also assignment I expect?

There's no problem with assignment, it's never ambiguous. There seems to be some confusion about what the issue is. To reiterate: void foo(float x) {} void foo(double x) {} void bar(float x) {} void baz(double x) {} void main() { bar(2); // OK -- 2 becomes 2.0f baz(2); // OK -- 2 becomes 2.0 foo(2); // fails -- ambiguous. } My proposal was effectively: if it's ambiguous, choose double. That's all.

Oct 20 2011
prev sibling parent "Robert Jacques" <sandford jhu.edu> writes:
On Sat, 22 Oct 2011 05:42:10 -0400, Manu <turkeyman gmail.com> wrote:
 Sure, and hijacking is bound to happen under your proposal, no?
 How would it be detected?

 On 22 October 2011 06:51, Robert Jacques <sandford jhu.edu> wrote:

 On Fri, 21 Oct 2011 19:04:43 -0400, Manu <turkeyman gmail.com> wrote:

 It would still allow function hijacking.
 void func(double v); exists...
 func(2);
 then someone comes along and adds func(float v); .. It will now hijack the
 call.
 That's what you mean right?

Hijacking is what happends when someone adds func(float v); _in another module_. And that hijack would/should still be detected, etc. like any other hijack.


Manu, I'm not sure you understand how function hijack detection works today. Let us say you have three modules module a; float func(float v) { return v; } module b; double func(double v) { return v; } module c; int func(int v) { return v*v; } which all define a func method. Now, if you import a; import b; void main(string[] args) { assert(func(1.0f) == 1.0f); // Error } you'll get a function hijacking error because func(1.0f) matches func(float) and func(double). However, if you instead: import a; import c; void main(string[] args) { assert(func(1.0f) == 1.0f); // Error } you won't get an error, because func(1.0f) doesn't match func(int). In short, the best overload is only selected _after_ the module name has been resolved. The proposal of myself and others only affects which overload is the best match; it has no possible effect on function hijacking.
Oct 22 2011
prev sibling next sibling parent "Marco Leise" <Marco.Leise gmx.de> writes:
Am 20.10.2011, 02:46 Uhr, schrieb dsimcha <dsimcha yahoo.com>:

 On 10/19/2011 6:25 PM, Alvaro wrote:
 El 19/10/2011 20:12, dsimcha escribi=C3=B3:
 =3D=3D Quote from Don (nospam nospam.com)'s article
 The hack must go.

No. Something as simple as sqrt(2) must work at all costs, period. A=



 language
 that adds a bunch of silly complications to something this simple is=



 fundamentally
 broken. I don't remember your post on implicit preferred conversions=



 but IMHO
 implicit conversions of integer to double is a no-brainer. Requiring=



 something
 this simple to be explicit is Java/Pascal-like overkill on  =



 explicitness.

Completely agree. I call that uncluttered programming. No excessive explicitness should=


 necessary when what you mean is obvious (under some simple convention=


 Leads to clearer code.

Yes, and for the most part uncluttered programming is one of D's bigge=

 strengths.  Let's not ruin it by complicating sqrt(2).

What is the compiler to do with sqrt(5_000_000_000) ? It doesn't fit int= o = an int, but it fits into a double.
Oct 19 2011
prev sibling next sibling parent reply "Robert Jacques" <sandford jhu.edu> writes:
On Wed, 19 Oct 2011 22:52:14 -0400, Marco Leise <Marco.Leise gmx.de> wrote:
 Am 20.10.2011, 02:46 Uhr, schrieb dsimcha <dsimcha yahoo.com>:

 On 10/19/2011 6:25 PM, Alvaro wrote:
 El 19/10/2011 20:12, dsimcha escribiˇ:
 == Quote from Don (nospam nospam.com)'s article
 The hack must go.

No. Something as simple as sqrt(2) must work at all costs, period. A language that adds a bunch of silly complications to something this simple is fundamentally broken. I don't remember your post on implicit preferred conversions, but IMHO implicit conversions of integer to double is a no-brainer. Requiring something this simple to be explicit is Java/Pascal-like overkill on explicitness.

Completely agree. I call that uncluttered programming. No excessive explicitness should be necessary when what you mean is obvious (under some simple conventions). Leads to clearer code.

Yes, and for the most part uncluttered programming is one of D's biggest strengths. Let's not ruin it by complicating sqrt(2).

What is the compiler to do with sqrt(5_000_000_000) ? It doesn't fit into an int, but it fits into a double.

Simple, is a 5_000_000_000 long, and longs convert to reals. Also, 5_000_000_000 does not fit, exactly inside a double.
Oct 19 2011
parent reply bearophile <bearophileHUGS lycos.com> writes:
Robert Jacques:

 Simple, is a 5_000_000_000 long, and longs convert to reals. Also,
5_000_000_000 does not fit, exactly inside a double.

There is nothing "simple" here... Bye, bearophile
Oct 19 2011
parent Don <nospam nospam.com> writes:
On 20.10.2011 05:25, bearophile wrote:
 Robert Jacques:

 Simple, is a 5_000_000_000 long, and longs convert to reals. Also,
5_000_000_000 does not fit, exactly inside a double.

There is nothing "simple" here... Bye, bearophile

Yeah, but the problem isn't with ints, it's with integer literals, where there is no problem determining if it implicitly converts or not.
Oct 19 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Wed, 19 Oct 2011 22:57:48 -0400, Robert Jacques <sandford jhu.edu>  =

wrote:

 On Wed, 19 Oct 2011 22:52:14 -0400, Marco Leise <Marco.Leise gmx.de>  =

 wrote:
 Am 20.10.2011, 02:46 Uhr, schrieb dsimcha <dsimcha yahoo.com>:

 On 10/19/2011 6:25 PM, Alvaro wrote:
 El 19/10/2011 20:12, dsimcha escribi=C3=B3:
 =3D=3D Quote from Don (nospam nospam.com)'s article
 The hack must go.

No. Something as simple as sqrt(2) must work at all costs, period.=





 language
 that adds a bunch of silly complications to something this simple =





 fundamentally
 broken. I don't remember your post on implicit preferred conversio=





 but IMHO
 implicit conversions of integer to double is a no-brainer. Requiri=





 something
 this simple to be explicit is Java/Pascal-like overkill on
 explicitness.

Completely agree. I call that uncluttered programming. No excessive explicitness shou=




 be
 necessary when what you mean is obvious (under some simple  =




 conventions).
 Leads to clearer code.

Yes, and for the most part uncluttered programming is one of D's =



 biggest
 strengths.  Let's not ruin it by complicating sqrt(2).

What is the compiler to do with sqrt(5_000_000_000) ? It doesn't fit =


 into
 an int, but it fits into a double.

Simple, is a 5_000_000_000 long, and longs convert to reals. Also, =

 5_000_000_000 does not fit, exactly inside a double.

It doesn't? I thought double could do 53 bits? Although I agree, long should map to real, because obviously not all lon= gs = fit into a double exactly. -Steve
Oct 19 2011
prev sibling next sibling parent "Robert Jacques" <sandford jhu.edu> writes:
On Wed, 19 Oct 2011 22:57:48 -0400, Robert Jacques <sandford jhu.edu> wrote:

 On Wed, 19 Oct 2011 22:52:14 -0400, Marco Leise <Marco.Leise gmx.de> wrote:
 Am 20.10.2011, 02:46 Uhr, schrieb dsimcha <dsimcha yahoo.com>:

 On 10/19/2011 6:25 PM, Alvaro wrote:
 El 19/10/2011 20:12, dsimcha escribiˇ:
 == Quote from Don (nospam nospam.com)'s article
 The hack must go.

No. Something as simple as sqrt(2) must work at all costs, period. A language that adds a bunch of silly complications to something this simple is fundamentally broken. I don't remember your post on implicit preferred conversions, but IMHO implicit conversions of integer to double is a no-brainer. Requiring something this simple to be explicit is Java/Pascal-like overkill on explicitness.

Completely agree. I call that uncluttered programming. No excessive explicitness should be necessary when what you mean is obvious (under some simple conventions). Leads to clearer code.

Yes, and for the most part uncluttered programming is one of D's biggest strengths. Let's not ruin it by complicating sqrt(2).

What is the compiler to do with sqrt(5_000_000_000) ? It doesn't fit into an int, but it fits into a double.

Simple, is a 5_000_000_000 long, and longs convert to reals. Also, 5_000_000_000 does not fit, exactly inside a double.

Opps. That should be '5_000_000_000 is a long' not ' is a 5_000_000_000 long'
Oct 19 2011
prev sibling next sibling parent "Marco Leise" <Marco.Leise gmx.de> writes:
Am 20.10.2011, 05:01 Uhr, schrieb Steven Schveighoffer  =

<schveiguy yahoo.com>:

 On Wed, 19 Oct 2011 22:57:48 -0400, Robert Jacques <sandford jhu.edu> =

 wrote:

 On Wed, 19 Oct 2011 22:52:14 -0400, Marco Leise <Marco.Leise gmx.de> =


 wrote:
 Am 20.10.2011, 02:46 Uhr, schrieb dsimcha <dsimcha yahoo.com>:

 On 10/19/2011 6:25 PM, Alvaro wrote:
 El 19/10/2011 20:12, dsimcha escribi=C3=B3:
 =3D=3D Quote from Don (nospam nospam.com)'s article
 The hack must go.

No. Something as simple as sqrt(2) must work at all costs, period=






 language
 that adds a bunch of silly complications to something this simple=






 fundamentally
 broken. I don't remember your post on implicit preferred  =






 conversions,
 but IMHO
 implicit conversions of integer to double is a no-brainer. Requir=






 something
 this simple to be explicit is Java/Pascal-like overkill on
 explicitness.

Completely agree. I call that uncluttered programming. No excessive explicitness =





 should be
 necessary when what you mean is obvious (under some simple  =





 conventions).
 Leads to clearer code.

Yes, and for the most part uncluttered programming is one of D's =




 biggest
 strengths.  Let's not ruin it by complicating sqrt(2).

What is the compiler to do with sqrt(5_000_000_000) ? It doesn't fit=



 into
 an int, but it fits into a double.

Simple, is a 5_000_000_000 long, and longs convert to reals. Also, =


 5_000_000_000 does not fit, exactly inside a double.

It doesn't? I thought double could do 53 bits? Although I agree, long should map to real, because obviously not all =

 longs fit into a double exactly.

 -Steve

And real can be used without protability problems on PowerPC or ARM?
Oct 19 2011
prev sibling next sibling parent "Robert Jacques" <sandford jhu.edu> writes:
On Wed, 19 Oct 2011 23:01:34 -0400, Steven Schveighoffer <schveiguy yahoo.com>
wrote:
 On Wed, 19 Oct 2011 22:57:48 -0400, Robert Jacques <sandford jhu.edu>
 wrote:

 On Wed, 19 Oct 2011 22:52:14 -0400, Marco Leise <Marco.Leise gmx.de>
 wrote:
 Am 20.10.2011, 02:46 Uhr, schrieb dsimcha <dsimcha yahoo.com>:

 On 10/19/2011 6:25 PM, Alvaro wrote:
 El 19/10/2011 20:12, dsimcha escribiˇ:
 == Quote from Don (nospam nospam.com)'s article
 The hack must go.

No. Something as simple as sqrt(2) must work at all costs, period. A language that adds a bunch of silly complications to something this simple is fundamentally broken. I don't remember your post on implicit preferred conversions, but IMHO implicit conversions of integer to double is a no-brainer. Requiring something this simple to be explicit is Java/Pascal-like overkill on explicitness.

Completely agree. I call that uncluttered programming. No excessive explicitness should be necessary when what you mean is obvious (under some simple conventions). Leads to clearer code.

Yes, and for the most part uncluttered programming is one of D's biggest strengths. Let's not ruin it by complicating sqrt(2).

What is the compiler to do with sqrt(5_000_000_000) ? It doesn't fit into an int, but it fits into a double.

Simple, is a 5_000_000_000 long, and longs convert to reals. Also, 5_000_000_000 does not fit, exactly inside a double.

It doesn't? I thought double could do 53 bits?

Yes. You're right. Sorry, my brain automatically skipped forward to 5_000_000_000 => long => real.
 Although I agree, long should map to real, because obviously not all longs
 fit into a double exactly.

 -Steve

Oct 19 2011
prev sibling next sibling parent Don <nospam nospam.com> writes:
On 19.10.2011 20:12, dsimcha wrote:
 == Quote from Don (nospam nospam.com)'s article
 In D2 prior to 2.048, sqrt(2) does not compile. The reason is that it's
 ambiguous whether it is sqrt(2.0), sqrt(2.0L), or sqrt(2.0f). This also
 applies to _any_ function which has overloads for more than one floating
 point type.
 In D2 between versions 2.049 and the present, sqrt(2) compiles due to
 the request of a small number of people (2-3, I think). But still, no
 other floating point function works with integer literals.
 The "bug" being fixed was
 Bugzilla 4455: Taking the sqrt of an integer shouldn't require an
 explicit cast.
 This compiles only due to an awful, undocumented hack in std.math. It
 doesn't work for any function other than sqrt. I protested strongly
 against this, but accepted it only on the proviso that we would fix
 integer literal conversions to floating point in _all_ cases, so that
 the hack could be removed.
 However, when I proposed the fix on the newsgroup (integer literals
 should have a preferred conversion to double), it was *unanimously*
 rejected. Those who had argued for the hack were conspicuously absent.
 The hack must go.

No. Something as simple as sqrt(2) must work at all costs, period.

Where the hell were you when I made that proposal before? Frankly, I'm pissed off that you guys bullied me into putting an *awful* temporary hack into std.math, and then gave me no support when the idea got shouted down on the ng.
 A language
 that adds a bunch of silly complications to something this simple is
fundamentally
 broken.  I don't remember your post on implicit preferred conversions, but IMHO
 implicit conversions of integer to double is a no-brainer.  Requiring something
 this simple to be explicit is Java/Pascal-like overkill on explicitness.

The bottom line: the hack MUST go. Either we fix this properly, as I suggested, or else it must not compile.
Oct 19 2011
prev sibling next sibling parent Russel Winder <russel russel.org.uk> writes:
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Wed, 2011-10-19 at 23:36 -0400, dsimcha wrote:
 On 10/19/2011 11:27 PM, Marco Leise wrote:
 And real can be used without protability problems on PowerPC or ARM?

Yes, it's just that they may only give 64 bits of precision. Floating=

 point is inexact anyhow, though.  IMHO the fact that you may lose a=20
 little precision with very large longs is not a game changer.

This is not convincing. One of the biggest problem is software development is that computers have two systems of hardware arithmetic that are mutually incompatible and have very different properties. Humans are taught that there are abstract numbers that can be put into different sets: reals, integers, naturals, etc. There are already far too many programmers out there who do not understand that computer numbers have representation problems and rounding errors. Another issue: sqrt ( 2 ) sqrt ( 2.0 ) sqrt ( 2.0000000000000000000000000000000000000000 ) actually mean very different things. The number of zeros carries information. Summary, losing precision is a game changer. This stuff matters. This is a hard problem. --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.n= et 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel russel.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Oct 19 2011
prev sibling next sibling parent Manu <turkeyman gmail.com> writes:
--0016364ed99e7178e804afb62b83
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Many architectures do not support real, and therefore it should never be
used implicitly by the language.

Precision problems aside, I would personally insist that implicit
conversation from any sized int always be to float, not double, for
performance reasons (the whole point of a compiled language trying
to supersede C/C++).
Amusingly, 5_000_000_000 IS actually precisely representable with a float
;) .. Bet let's take 5_000_000_001, it'll lose a few bits, but that's more
than precise enough for me.

Naturally the majority would make solid arguments against this preference,
and I would agree with them in their argument, therefore should it not just
be a compiler flag/option to explicitly specify the implicit int->float
conversion precision?

Though that leads to a problem with standard library, since it links a
pre-compiled binary... I can't afford to have the standard library messing
around with doubles because that was the flag it was compiled with...
This leads inevitably to my pointlessly rewriting the standard library
functions in my own code, just as in C where the CRT uses doubles, for the
same reasons...


On 20 October 2011 06:01, Steven Schveighoffer <schveiguy yahoo.com> wrote:

 On Wed, 19 Oct 2011 22:57:48 -0400, Robert Jacques <sandford jhu.edu>
 wrote:

  On Wed, 19 Oct 2011 22:52:14 -0400, Marco Leise <Marco.Leise gmx.de>
 wrote:

 Am 20.10.2011, 02:46 Uhr, schrieb dsimcha <dsimcha yahoo.com>:

  On 10/19/2011 6:25 PM, Alvaro wrote:
 El 19/10/2011 20:12, dsimcha escribi=C3=B3:

 =3D=3D Quote from Don (nospam nospam.com)'s article

 The hack must go.

No. Something as simple as sqrt(2) must work at all costs, period. A language that adds a bunch of silly complications to something this simple is fundamentally broken. I don't remember your post on implicit preferred conversions=






 but IMHO
 implicit conversions of integer to double is a no-brainer. Requiring
 something
 this simple to be explicit is Java/Pascal-like overkill on
 explicitness.

Completely agree. I call that uncluttered programming. No excessive explicitness should be necessary when what you mean is obvious (under some simple conventions). Leads to clearer code.





 strengths.  Let's not ruin it by complicating sqrt(2).

What is the compiler to do with sqrt(5_000_000_000) ? It doesn't fit in=



 an int, but it fits into a double.

Simple, is a 5_000_000_000 long, and longs convert to reals. Also, 5_000_000_000 does not fit, exactly inside a double.

It doesn't? I thought double could do 53 bits? Although I agree, long should map to real, because obviously not all long=

 fit into a double exactly.

 -Steve

--0016364ed99e7178e804afb62b83 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Many architectures do not support real, and therefore it should never be us= ed implicitly by the language.<div><br></div><div>Precision problems aside,= I would personally insist that implicit conversation from any sized int al= ways be to float, not double, for performance reasons (the whole point of a= compiled language trying to=C2=A0supersede=C2=A0C/C++).</div> <div>Amusingly,=C2=A05_000_000_000 IS actually precisely representable with= a float ;) .. Bet let&#39;s take 5_000_000_001, it&#39;ll lose a few bits,= but that&#39;s more than precise enough for me.</div><div><br></div><div>N= aturally the majority would make solid arguments against this preference, a= nd I would agree with them in their argument, therefore should it not just = be a compiler flag/option to explicitly specify the implicit int-&gt;float = conversion precision?</div> <div><br></div><div>Though that leads to a problem with standard library, s= ince it links a pre-compiled binary... I can&#39;t afford to have the stand= ard library messing around with doubles because that was the flag it was co= mpiled with...</div> <div>This leads inevitably to my pointlessly rewriting the standard library= functions in my own code, just as in C where the CRT uses doubles, for the= same reasons...</div><div><br></div><div><br></div><div><div class=3D"gmai= l_quote"> On 20 October 2011 06:01, Steven Schveighoffer <span dir=3D"ltr">&lt;<a hre= f=3D"mailto:schveiguy yahoo.com">schveiguy yahoo.com</a>&gt;</span> wrote:<= br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left= :1px #ccc solid;padding-left:1ex;"> <div><div></div><div class=3D"h5">On Wed, 19 Oct 2011 22:57:48 -0400, Rober= t Jacques &lt;<a href=3D"mailto:sandford jhu.edu" target=3D"_blank">sandfor= d jhu.edu</a>&gt; wrote:<br> <br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> On Wed, 19 Oct 2011 22:52:14 -0400, Marco Leise &lt;<a href=3D"mailto:Marco= .Leise gmx.de" target=3D"_blank">Marco.Leise gmx.de</a>&gt; wrote:<br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> Am 20.10.2011, 02:46 Uhr, schrieb dsimcha &lt;<a href=3D"mailto:dsimcha yah= oo.com" target=3D"_blank">dsimcha yahoo.com</a>&gt;:<br> <br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> On 10/19/2011 6:25 PM, Alvaro wrote:<br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> El 19/10/2011 20:12, dsimcha escribi=C3=B3:<br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> =3D=3D Quote from Don (<a href=3D"mailto:nospam nospam.com" target=3D"_blan= k">nospam nospam.com</a>)&#39;s article<br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> The hack must go.<br> </blockquote> <br> No. Something as simple as sqrt(2) must work at all costs, period. A<br> language<br> that adds a bunch of silly complications to something this simple is<br> fundamentally<br> broken. I don&#39;t remember your post on implicit preferred conversions,<b= r> but IMHO<br> implicit conversions of integer to double is a no-brainer. Requiring<br> something<br> this simple to be explicit is Java/Pascal-like overkill on<br> explicitness.<br> </blockquote> <br> Completely agree.<br> <br> I call that uncluttered programming. No excessive explicitness should be<br=


<br> </blockquote> <br> Yes, and for the most part uncluttered programming is one of D&#39;s bigges= t<br> strengths. =C2=A0Let&#39;s not ruin it by complicating sqrt(2).<br> </blockquote> <br> What is the compiler to do with sqrt(5_000_000_000) ? It doesn&#39;t fit in= to<br> an int, but it fits into a double.<br> </blockquote> <br> Simple, is a 5_000_000_000 long, and longs convert to reals. Also, 5_000_00= 0_000 does not fit, exactly inside a double.<br> </blockquote> <br></div></div> It doesn&#39;t? =C2=A0I thought double could do 53 bits?<br> <br> Although I agree, long should map to real, because obviously not all longs = fit into a double exactly.<br> <br> -Steve<br> </blockquote></div><br></div> --0016364ed99e7178e804afb62b83--
Oct 20 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 20 Oct 2011 03:55:51 -0400, Don <nospam nospam.com> wrote:

 On 20.10.2011 05:01, Steven Schveighoffer wrote:
 On Wed, 19 Oct 2011 22:57:48 -0400, Robert Jacques <sandford jhu.edu>=


 wrote:

 On Wed, 19 Oct 2011 22:52:14 -0400, Marco Leise <Marco.Leise gmx.de>=



 wrote:
 Am 20.10.2011, 02:46 Uhr, schrieb dsimcha <dsimcha yahoo.com>:

 On 10/19/2011 6:25 PM, Alvaro wrote:
 El 19/10/2011 20:12, dsimcha escribi=C3=B3:
 =3D=3D Quote from Don (nospam nospam.com)'s article
 The hack must go.

No. Something as simple as sqrt(2) must work at all costs, perio=







 A
 language
 that adds a bunch of silly complications to something this simpl=







 is
 fundamentally
 broken. I don't remember your post on implicit preferred  =







 conversions,
 but IMHO
 implicit conversions of integer to double is a no-brainer.  =







 Requiring
 something
 this simple to be explicit is Java/Pascal-like overkill on
 explicitness.

Completely agree. I call that uncluttered programming. No excessive explicitness should be necessary when what you mean is obvious (under some simple conventions). Leads to clearer code.

Yes, and for the most part uncluttered programming is one of D's biggest strengths. Let's not ruin it by complicating sqrt(2).

What is the compiler to do with sqrt(5_000_000_000) ? It doesn't fi=




 into
 an int, but it fits into a double.

Simple, is a 5_000_000_000 long, and longs convert to reals. Also, 5_000_000_000 does not fit, exactly inside a double.

It doesn't? I thought double could do 53 bits? Although I agree, long should map to real, because obviously not all longs fit into a double exactly. -Steve

But ulong.max does NOT fit into an 80-bit real. And long won't fit int=

 real on anything other than x86, 68K, and Itanium.

 I don't think long and ulong should ever implicitly convert to floatin=

 point types. Note that you can just do *1.0 or *1.0L if you want to  =

 convert them.

 Currently long implicitly converts even to float. This seems quite bad=

 it loses 60% of its bits!!

 Suppose we also banned implicit conversions int->float and uint->float=

 (since float only has 24 bits, these are lossy conversions, losing 25%=

 of the bits).

 Now that we've disallowed lossy integral conversions, it really seems =

 that we should disallow these ones as well.

 If that was all we did, it would also mean that things like short+shor=

 wouldn't convert to float either, because C converts everything to int=

 whenever it gets an opportunity. But we could use range checking to  =

 restore this (and to allow small longs to fit into doubles: allow  =

 conversion to double if it's <=3D 53 bits, allow conversion to float i=

 24 bits).

Would you disagree though, that if a literal can be accurately represent= ed = as a real or double, it should be allowed? -Steve
Oct 20 2011
prev sibling next sibling parent "Martin Nowak" <dawg dawgfoto.de> writes:
On Thu, 20 Oct 2011 09:55:51 +0200, Don <nospam nospam.com> wrote:

 On 20.10.2011 05:01, Steven Schveighoffer wrote:
 On Wed, 19 Oct 2011 22:57:48 -0400, Robert Jacques <sandford jhu.edu>=


 wrote:

 On Wed, 19 Oct 2011 22:52:14 -0400, Marco Leise <Marco.Leise gmx.de>=



 wrote:
 Am 20.10.2011, 02:46 Uhr, schrieb dsimcha <dsimcha yahoo.com>:

 On 10/19/2011 6:25 PM, Alvaro wrote:
 El 19/10/2011 20:12, dsimcha escribi=C3=B3:
 =3D=3D Quote from Don (nospam nospam.com)'s article
 The hack must go.

No. Something as simple as sqrt(2) must work at all costs, perio=







 A
 language
 that adds a bunch of silly complications to something this simpl=







 is
 fundamentally
 broken. I don't remember your post on implicit preferred  =







 conversions,
 but IMHO
 implicit conversions of integer to double is a no-brainer.  =







 Requiring
 something
 this simple to be explicit is Java/Pascal-like overkill on
 explicitness.

Completely agree. I call that uncluttered programming. No excessive explicitness should be necessary when what you mean is obvious (under some simple conventions). Leads to clearer code.

Yes, and for the most part uncluttered programming is one of D's biggest strengths. Let's not ruin it by complicating sqrt(2).

What is the compiler to do with sqrt(5_000_000_000) ? It doesn't fi=




 into
 an int, but it fits into a double.

Simple, is a 5_000_000_000 long, and longs convert to reals. Also, 5_000_000_000 does not fit, exactly inside a double.

It doesn't? I thought double could do 53 bits? Although I agree, long should map to real, because obviously not all longs fit into a double exactly. -Steve

But ulong.max does NOT fit into an 80-bit real. And long won't fit int=

 real on anything other than x86, 68K, and Itanium.

 I don't think long and ulong should ever implicitly convert to floatin=

 point types. Note that you can just do *1.0 or *1.0L if you want to  =

 convert them.

 Currently long implicitly converts even to float. This seems quite bad=

 it loses 60% of its bits!!

 Suppose we also banned implicit conversions int->float and uint->float=

 (since float only has 24 bits, these are lossy conversions, losing 25%=

 of the bits).

 Now that we've disallowed lossy integral conversions, it really seems =

 that we should disallow these ones as well.

 If that was all we did, it would also mean that things like short+shor=

 wouldn't convert to float either, because C converts everything to int=

 whenever it gets an opportunity. But we could use range checking to  =

 restore this (and to allow small longs to fit into doubles: allow  =

 conversion to double if it's <=3D 53 bits, allow conversion to float i=

 24 bits).

propagation instead of the strange C rules. Thankfully this discussion reminded reminded me of an ugly header file b= ug http://d.puremagic.com/issues/show_bug.cgi?id=3D6833. martin
Oct 20 2011
prev sibling next sibling parent Manu <turkeyman gmail.com> writes:
--00163646bfc638aaef04afb907b1
Content-Type: text/plain; charset=UTF-8

On 20 October 2011 11:02, Don <nospam nospam.com> wrote:

 On 20.10.2011 09:47, Manu wrote:

 Many architectures do not support real, and therefore it should never be
 used implicitly by the language.

 Precision problems aside, I would personally insist that implicit
 conversation from any sized int always be to float, not double, for
 performance reasons (the whole point of a compiled language trying
 to supersede C/C++).

On almost all platforms, float and double are the same speed.

This isn't true. Consider ARM, hard to say this isn't a vitally important architecture these days, and there are plenty of embedded architectures that don't support doubles at all, I would say it's a really bad idea to invent a systems programming language that excludes many architectures by its design... Atmel AVR is another important architecture. I maintain that implicit conversion of integers of any length should always target the same precision float, and that should be a compiler flag to specify the desired precision throughout the app (possibly defaulting to double). If you choose 'float' you may lose some precision obviously, but you expected that when you chose the options, and did the cast...
 Note that what we're discussing here is parameter passing of single
 values; if it's part of an aggregate (array or struct), the issue doesn't
 arise.

Are we? I thought we were discussing implicit conversion of ints to floats? This may be parameter passing, but also assignment I expect? --00163646bfc638aaef04afb907b1 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <div class=3D"gmail_quote">On 20 October 2011 11:02, Don <span dir=3D"ltr">= &lt;<a href=3D"mailto:nospam nospam.com">nospam nospam.com</a>&gt;</span> w= rote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;borde= r-left:1px #ccc solid;padding-left:1ex;"> <div class=3D"im">On 20.10.2011 09:47, Manu wrote:<br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> Many architectures do not support real, and therefore it should never be<br=

<br> Precision problems aside, I would personally insist that implicit<br> conversation from any sized int always be to float, not double, for<br> performance reasons (the whole point of a compiled language trying<br> to supersede C/C++).<br> </blockquote> <br></div> On almost all platforms, float and double are the same speed.<br></blockquo= te><div><br></div><div>This isn&#39;t true. Consider ARM, hard to say this = isn&#39;t a vitally important architecture these days, and there are plenty= of embedded architectures that don&#39;t support doubles at all, I would s= ay it&#39;s a really bad idea to invent a systems programming language that= excludes many architectures by its design... Atmel AVR is another importan= t architecture.</div> <div><br></div><div>I maintain that implicit conversion of integers of any = length should always target the same precision float, and that should be a = compiler flag to specify the desired precision throughout the app (possibly= defaulting to double).</div> <div>If you choose &#39;float&#39; you may lose some precision obviously, b= ut you expected that when you chose the options, and did the cast...</div><= div><br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"m= argin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"> Note that what we&#39;re discussing here is parameter passing of single val= ues; if it&#39;s part of an aggregate (array or struct), the issue doesn&#3= 9;t arise.<br> </blockquote></div><div><br></div><div>Are we? I thought we were discussing= implicit conversion of ints to floats? This may be parameter passing, but = also assignment I expect?</div> --00163646bfc638aaef04afb907b1--
Oct 20 2011
prev sibling next sibling parent Manu <turkeyman gmail.com> writes:
--0016364ee67a7469f304afba6059
Content-Type: text/plain; charset=UTF-8

On 20 October 2011 15:13, Don <nospam nospam.com> wrote:

 On 20.10.2011 13:12, Manu wrote:

 On 20 October 2011 11:02, Don <nospam nospam.com
 <mailto:nospam nospam.com>> wrote:

    On 20.10.2011 09:47, Manu wrote:

        Many architectures do not support real, and therefore it should
        never be
        used implicitly by the language.

        Precision problems aside, I would personally insist that implicit
        conversation from any sized int always be to float, not double, for
        performance reasons (the whole point of a compiled language trying
        to supersede C/C++).


    On almost all platforms, float and double are the same speed.


 This isn't true. Consider ARM, hard to say this isn't a vitally
 important architecture these days, and there are plenty of embedded
 architectures that don't support doubles at all, I would say it's a
 really bad idea to invent a systems programming language that excludes
 many architectures by its design... Atmel AVR is another important
 architecture.

It doesn't exclude anything. What we're talking about as desirable behaviour, is exactly what C does. If you care about performance on ARM, you'll type sqrt(2.0f). Personally, I'd rather completely eliminate implicit conversions between integers and floating point types. But that's just me. I maintain that implicit conversion of integers of any length should
 always target the same precision float, and that should be a compiler
 flag to specify the desired precision throughout the app (possibly
 defaulting to double).

I can't believe that you'd ever write an app without that being an upfront decision. Casually flipping it with a compiler flag?? Remember that it affects very few things (as discussed below). If you choose 'float' you may lose some precision obviously, but you
 expected that when you chose the options, and did the cast...

Explicit casts are not affected in any way. Note that what we're discussing here is parameter passing of single
    values; if it's part of an aggregate (array or struct), the issue
    doesn't arise.


 Are we? I thought we were discussing implicit conversion of ints to
 floats? This may be parameter passing, but also assignment I expect?

There's no problem with assignment, it's never ambiguous. There seems to be some confusion about what the issue is. To reiterate: void foo(float x) {} void foo(double x) {} void bar(float x) {} void baz(double x) {} void main() { bar(2); // OK -- 2 becomes 2.0f baz(2); // OK -- 2 becomes 2.0 foo(2); // fails -- ambiguous. } My proposal was effectively: if it's ambiguous, choose double. That's all.

Yeah sorry, I think you're right, the discussion got slightly lost in the noise here... Just to clarify, where you advocate eliminating implicit casting, do you now refer to ALL implicit casting? Or just implicit casting to an ambiguous target? Let me reposition myself to suit what it would seem is actually being discussed... :) void sqrt(float x); void sqrt(double x); void sqrt(real x); { sqrt(2); } Surely this produces some error: "Ambiguous call to overloaded function", and then there is no implicit cast rule to talk about... end of discussion? But you speak of "eliminating implicit casting" as if this may also refer to: void NotOverloaded(float x); { NotOverloaded(2); // not ambiguous... so what's the problem? } or: float x = 10; Which I can imagine why most would feel this is undesirable... I'm not clear now where you intend to draw the lines. If you're advocating banning ALL implicit casting between float/int outright, I actually feel really good about that idea. I can just imagine the number of hours saved while optimising where junior/ignorant programmers cast back and fourth with no real regard to or awareness of what they're doing. Or are we only drawing the distinction for literals? I don't mind a compile error if I incorrectly state the literal a function expects. That sort of thing becomes second nature in no time. --0016364ee67a7469f304afba6059 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <div class=3D"gmail_quote">On 20 October 2011 15:13, Don <span dir=3D"ltr">= &lt;<a href=3D"mailto:nospam nospam.com">nospam nospam.com</a>&gt;</span> w= rote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;borde= r-left:1px #ccc solid;padding-left:1ex;"> <div class=3D"im">On 20.10.2011 13:12, Manu wrote:<br> </div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-l= eft:1px #ccc solid;padding-left:1ex"><div class=3D"im"> On 20 October 2011 11:02, Don &lt;<a href=3D"mailto:nospam nospam.com" targ= et=3D"_blank">nospam nospam.com</a><br></div><div class=3D"im"> &lt;mailto:<a href=3D"mailto:nospam nospam.com" target=3D"_blank">nospam no= spam.com</a>&gt;&gt; wrote:<br> <br> =C2=A0 =C2=A0On 20.10.2011 09:47, Manu wrote:<br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0Many architectures do not support real, and the= refore it should<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0never be<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0used implicitly by the language.<br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0Precision problems aside, I would personally in= sist that implicit<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0conversation from any sized int always be to fl= oat, not double, for<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0performance reasons (the whole point of a compi= led language trying<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0to supersede C/C++).<br> <br> <br> =C2=A0 =C2=A0On almost all platforms, float and double are the same speed.= <br> <br> <br></div><div class=3D"im"> This isn&#39;t true. Consider ARM, hard to say this isn&#39;t a vitally<br> important architecture these days, and there are plenty of embedded<br> architectures that don&#39;t support doubles at all, I would say it&#39;s a= <br> really bad idea to invent a systems programming language that excludes<br> many architectures by its design... Atmel AVR is another important<br> architecture.<br> </div></blockquote> <br> It doesn&#39;t exclude anything. What we&#39;re talking about as desirable = behaviour, is exactly what C does. If you care about performance on ARM, yo= u&#39;ll type sqrt(2.0f).<br> <br> Personally, I&#39;d rather completely eliminate implicit conversions betwee= n integers and floating point types. But that&#39;s just me.<div class=3D"i= m"><br> <br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> I maintain that implicit conversion of integers of any length should<br> always target the same precision float, and that should be a compiler<br> flag to specify the desired precision throughout the app (possibly<br> defaulting to double).<br> </blockquote> <br></div> I can&#39;t believe that you&#39;d ever write an app without that being an = upfront decision. Casually flipping it with a compiler flag??<br> Remember that it affects very few things (as discussed below).<div class=3D= "im"><br> <br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> If you choose &#39;float&#39; you may lose some precision obviously, but yo= u<br> expected that when you chose the options, and did the cast...<br> </blockquote> <br></div> Explicit casts are not affected in any way.<br> <br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"><div class=3D"im"> =C2=A0 =C2=A0Note that what we&#39;re discussing here is parameter passing= of single<br> =C2=A0 =C2=A0values; if it&#39;s part of an aggregate (array or struct), t= he issue<br> =C2=A0 =C2=A0doesn&#39;t arise.<br> <br> <br></div><div class=3D"im"> Are we? I thought we were discussing implicit conversion of ints to<br> floats? This may be parameter passing, but also assignment I expect?<br> </div></blockquote> <br> There&#39;s no problem with assignment, it&#39;s never ambiguous.<br> <br> There seems to be some confusion about what the issue is.<br> To reiterate:<br> <br> void foo(float x) {}<br> void foo(double x) {}<br> <br> void bar(float x) {}<br> <br> void baz(double x) {}<br> <br> void main()<br> {<br> =C2=A0 bar(2); // OK -- 2 becomes 2.0f<br> =C2=A0 baz(2); // OK -- 2 becomes 2.0<br> =C2=A0 foo(2); // fails -- ambiguous.<br> }<br> <br> My proposal was effectively: if it&#39;s ambiguous, choose double. That&#39= ;s all.<br> </blockquote></div><div><br></div><div>Yeah sorry, I think you&#39;re right= , the discussion got slightly lost in the noise here...</div><div><div><div=
<br></div><div>Just to clarify, where you advocate eliminating implicit ca=

o an ambiguous target?</div> <div><br></div><div>Let me reposition myself to suit what it would seem is = actually being discussed... :)</div><div><br></div><div>void sqrt(float x);= </div><div><div>void=C2=A0sqrt(double x);</div></div><div><div>void=C2=A0sq= rt(real x);</div> </div><div><br></div><div>{</div><div>=C2=A0 sqrt(2);</div><div>}</div><div=
<br></div><div>Surely this produces some error: &quot;Ambiguous call to ov=

out... end of discussion?</div> <div><br></div><div>But you speak of &quot;eliminating implicit casting&quo= t; as if this may also refer to:</div><div><br></div><div>void NotOverloade= d(float x);</div><div><br></div><div>{</div><div>=C2=A0=C2=A0NotOverloaded(= 2); // not ambiguous... so what&#39;s the problem?</div> <div>}</div><div><br></div><div>or:</div><div><br></div><div>float x =3D 10= ;</div><div><br></div><div>Which I can imagine why most would feel this is = undesirable...</div><div><br></div><div>I&#39;m not clear now where you int= end to draw the lines.</div> </div></div><div>If you&#39;re advocating banning ALL implicit casting betw= een float/int outright, I actually feel really good about that idea. I can = just imagine the number of hours saved while optimising where junior/ignora= nt programmers cast back and fourth with no real regard to or awareness of = what they&#39;re doing.</div> <div><br></div><div>Or are we only drawing the distinction for literals?</d= iv><div>I don&#39;t mind a compile error if I incorrectly state the literal= a function expects. That sort of thing becomes second nature in no time.</= div> --0016364ee67a7469f304afba6059--
Oct 20 2011
prev sibling next sibling parent Manu <turkeyman gmail.com> writes:
--00163646bfc669a2d204afba9b22
Content-Type: text/plain; charset=UTF-8

I vote for "Error: Ambiguous call to overloaded function". NOT implicit
conversion to arbitrary type 'double' :)


On 20 October 2011 15:49, dsimcha <dsimcha yahoo.com> wrote:

 On 10/20/2011 8:13 AM, Don wrote:

 There's no problem with assignment, it's never ambiguous.

 There seems to be some confusion about what the issue is.
 To reiterate:

 void foo(float x) {}
 void foo(double x) {}

 void bar(float x) {}

 void baz(double x) {}

 void main()
 {
 bar(2); // OK -- 2 becomes 2.0f
 baz(2); // OK -- 2 becomes 2.0
 foo(2); // fails -- ambiguous.
 }

 My proposal was effectively: if it's ambiguous, choose double. That's all.

This proposal seems like a no-brainer to me. I sincerely apologize for not supporting it before. I looked at when it was created, and I realized that I was with my family for Christmas/New Years at the time, with little time to spend on the D newsgroup.

--00163646bfc669a2d204afba9b22 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable I vote for &quot;Error:=C2=A0<span class=3D"Apple-style-span" style=3D"font= -family: arial, sans-serif; font-size: 13px; background-color: rgb(255, 255= , 255); ">Ambiguous call to overloaded function&quot;. NOT implicit convers= ion to arbitrary type &#39;double&#39; :)</span><div> <font class=3D"Apple-style-span" face=3D"arial, sans-serif"><br></font><div=
<font class=3D"Apple-style-span" face=3D"arial, sans-serif"><br></font><di=

&lt;<a href=3D"mailto:dsimcha yahoo.com">dsimcha yahoo.com</a>&gt;</span> =

<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex;"><div class=3D"im">On 10/20/2011 8:13 AM, Do= n wrote:<br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> There&#39;s no problem with assignment, it&#39;s never ambiguous.<br> <br> There seems to be some confusion about what the issue is.<br> To reiterate:<br> <br> void foo(float x) {}<br> void foo(double x) {}<br> <br> void bar(float x) {}<br> <br> void baz(double x) {}<br> <br> void main()<br> {<br> bar(2); // OK -- 2 becomes 2.0f<br> baz(2); // OK -- 2 becomes 2.0<br> foo(2); // fails -- ambiguous.<br> }<br> <br> My proposal was effectively: if it&#39;s ambiguous, choose double. That&#39= ;s all.<br> </blockquote> <br></div> This proposal seems like a no-brainer to me. =C2=A0I sincerely apologize fo= r not supporting it before. =C2=A0I looked at when it was created, and I re= alized that I was with my family for Christmas/New Years at the time, with = little time to spend on the D newsgroup.<br> </blockquote></div><br></div></div> --00163646bfc669a2d204afba9b22--
Oct 20 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 20 Oct 2011 09:11:27 -0400, Don <nospam nospam.com> wrote:

 Actually there is a problem there, I think. If someone later on adds  
 NotOverload(double x), that call will suddenly stop compiling.

 That isn't just a theoretical problem.
 Currently log(2) will compile, but only because in std.math there is  
 log(real), but not yet log(double) or log(float).
 So once we add those overloads, peoples code will break.

Should there be a concern over silently changing the code path? For instance, log(2) currently binds to log(real), but with the addition of log(double) will bind to that. I'm not saying I found any problems with this, but I'm wondering if it can possibly harm anything. I don't have enough experience with floating point types to come up with a use case that would be affected. -Steve
Oct 20 2011
prev sibling next sibling parent Manu <turkeyman gmail.com> writes:
--0016e648adcac0a95404afbb4c0e
Content-Type: text/plain; charset=UTF-8

On 20 October 2011 16:11, Don <nospam nospam.com> wrote:

 On 20.10.2011 14:48, Manu wrote:

 On 20 October 2011 15:13, Don <nospam nospam.com

 <mailto:nospam nospam.com>> wrote:

    On 20.10.2011 13:12, Manu wrote:

        On 20 October 2011 11:02, Don <nospam nospam.com
        <mailto:nospam nospam.com>
        <mailto:nospam nospam.com <mailto:nospam nospam.com>>> wrote:

            On 20.10.2011 09:47, Manu wrote:

                Many architectures do not support real, and therefore it
        should
                never be
                used implicitly by the language.

                Precision problems aside, I would personally insist that
        implicit
                conversation from any sized int always be to float, not
        double, for
                performance reasons (the whole point of a compiled
        language trying
                to supersede C/C++).


            On almost all platforms, float and double are the same speed.


        This isn't true. Consider ARM, hard to say this isn't a vitally
        important architecture these days, and there are plenty of embedded
        architectures that don't support doubles at all, I would say it's a
        really bad idea to invent a systems programming language that
        excludes
        many architectures by its design... Atmel AVR is another important
        architecture.


    It doesn't exclude anything. What we're talking about as desirable
    behaviour, is exactly what C does. If you care about performance on
    ARM, you'll type sqrt(2.0f).

    Personally, I'd rather completely eliminate implicit conversions
    between integers and floating point types. But that's just me.


        I maintain that implicit conversion of integers of any length
 should
        always target the same precision float, and that should be a
        compiler
        flag to specify the desired precision throughout the app (possibly
        defaulting to double).


    I can't believe that you'd ever write an app without that being an
    upfront decision. Casually flipping it with a compiler flag??
    Remember that it affects very few things (as discussed below).


        If you choose 'float' you may lose some precision obviously, but
 you
        expected that when you chose the options, and did the cast...


    Explicit casts are not affected in any way.

            Note that what we're discussing here is parameter passing of
        single
            values; if it's part of an aggregate (array or struct), the
        issue
            doesn't arise.


        Are we? I thought we were discussing implicit conversion of ints to
        floats? This may be parameter passing, but also assignment I
 expect?


    There's no problem with assignment, it's never ambiguous.

    There seems to be some confusion about what the issue is.
    To reiterate:

    void foo(float x) {}
    void foo(double x) {}

    void bar(float x) {}

    void baz(double x) {}

    void main()
    {
       bar(2); // OK -- 2 becomes 2.0f
       baz(2); // OK -- 2 becomes 2.0
       foo(2); // fails -- ambiguous.
    }

    My proposal was effectively: if it's ambiguous, choose double.
    That's all.


 Yeah sorry, I think you're right, the discussion got slightly lost in
 the noise here...

 Just to clarify, where you advocate eliminating implicit casting, do you
 now refer to ALL implicit casting? Or just implicit casting to an
 ambiguous target?

 Let me reposition myself to suit what it would seem is actually being
 discussed... :)

 void sqrt(float x);
 void sqrt(double x);
 void sqrt(real x);

 {
   sqrt(2);
 }

 Surely this produces some error: "Ambiguous call to overloaded

 function", and then there is no implicit cast rule to talk about... end
 of discussion?

 But you speak of "eliminating implicit casting" as if this may also
 refer to:

 void NotOverloaded(float x);

 {
   NotOverloaded(2); // not ambiguous... so what's the problem?
 }

Actually there is a problem there, I think. If someone later on adds NotOverload(double x), that call will suddenly stop compiling. That isn't just a theoretical problem. Currently log(2) will compile, but only because in std.math there is log(real), but not yet log(double) or log(float). So once we add those overloads, peoples code will break. I'd like to get to the situation where those overloads can be added without breaking peoples code. The draconian possibility is to disallow them in all cases: integer types never match floating point function parameters. The second possibility is to introduce a tie-breaker rule: when there's an ambiguity, choose double. And a third possibility is to only apply that tie-breaker rule to literals. And the fourth possibility is to keep the language as it is now, and allow code to break when overloads get added. The one I really, really don't want, is the situation we have now: #5: whenever an overload gets added, introduce a hack for that function... or:
 float x = 10;

 Which I can imagine why most would feel this is undesirable...

 I'm not clear now where you intend to draw the lines.
 If you're advocating banning ALL implicit casting between float/int
 outright, I actually feel really good about that idea. I can just
 imagine the number of hours saved while optimising where junior/ignorant
 programmers cast back and fourth with no real regard to or awareness of
 what they're doing.

 Or are we only drawing the distinction for literals?
 I don't mind a compile error if I incorrectly state the literal a
 function expects. That sort of thing becomes second nature in no time.

I don't know. I think I probably prefer possibility #1 on my list, but it'd break existing code. I also like #2 and #3, and I think they'd be more generally popular. I don't like #4, but anything is better than #5.

Hmmm. I generally like #1, it encourages awareness of the clear distinction between integer and floating types (something that far too many programmers lack) I don't really like #2, it's just arbitrary, and totally subjective. You'll never have agreement, and perhaps more importantly, it's not instinctively obvious which it will choose and why... you just have to know, and most people won't know, they'll just use it blind (see my point about finding+fixing code by junior/ignorant programmers) #3 is just a less consistent version of #2... and less easy to catch the culprit committing the crime, and less obvious to the culprit that they are committing a crime. I don't HATE #4, it's not capable of causing any real problem in the code, it just requires placement of a cast, which anyone can do. But I prefer #1, solving that problem. #5 is obviously silly. In order of preference: 1, 4, 2, 3, 5 I could only support 2 if it chooses 'float', the highest performance version on all architectures AND actually available on all architectures; given this is meant to be a systems programming language, and supporting as many architectures as possible? If the argument is made to favour precision, then it should surely be real, not double... the counter argument is obviously that real is not supported on many architectures, true, but the same is true for double... so I think it's a hollow argument. double just seem like a weak compromise; more precise than float, and more likely to work on more architectures than real (but still not guaranteed), but it doesn't really satisfy either criteria neatly. The logic transposed: double is less precise than real, and potentially slower than float. Is the justification purely that it IS a compromise, since the choice at the end of the day is totally subjective :) --0016e648adcac0a95404afbb4c0e Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <div class=3D"gmail_quote">On 20 October 2011 16:11, Don <span dir=3D"ltr">= &lt;<a href=3D"mailto:nospam nospam.com">nospam nospam.com</a>&gt;</span> w= rote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;borde= r-left:1px #ccc solid;padding-left:1ex;"> On 20.10.2011 14:48, Manu wrote:<br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> On 20 October 2011 15:13, Don &lt;<a href=3D"mailto:nospam nospam.com" targ= et=3D"_blank">nospam nospam.com</a><div class=3D"im"><br> &lt;mailto:<a href=3D"mailto:nospam nospam.com" target=3D"_blank">nospam no= spam.com</a>&gt;&gt; wrote:<br> <br> =C2=A0 =C2=A0On 20.10.2011 13:12, Manu wrote:<br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0On 20 October 2011 11:02, Don &lt;<a href=3D"ma= ilto:nospam nospam.com" target=3D"_blank">nospam nospam.com</a><br> =C2=A0 =C2=A0 =C2=A0 =C2=A0&lt;mailto:<a href=3D"mailto:nospam nospam.com"= target=3D"_blank">nospam nospam.com</a>&gt;<br></div><div><div></div><div = class=3D"h5"> =C2=A0 =C2=A0 =C2=A0 =C2=A0&lt;mailto:<a href=3D"mailto:nospam nospam.com"= target=3D"_blank">nospam nospam.com</a> &lt;mailto:<a href=3D"mailto:nospa= m nospam.com" target=3D"_blank">nospam nospam.com</a>&gt;&gt;&gt; wrote:<br=

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0On 20.10.2011 09:47, Manu wrote:<= br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Many architectures = do not support real, and therefore it<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0should<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0never be<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0used implicitly by = the language.<br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Precision problems = aside, I would personally insist that<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0implicit<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0conversation from a= ny sized int always be to float, not<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0double, for<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0performance reasons= (the whole point of a compiled<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0language trying<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0to supersede C/C++)= .<br> <br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0On almost all platforms, float an= d double are the same speed.<br> <br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0This isn&#39;t true. Consider ARM, hard to say = this isn&#39;t a vitally<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0important architecture these days, and there ar= e plenty of embedded<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0architectures that don&#39;t support doubles at= all, I would say it&#39;s a<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0really bad idea to invent a systems programming= language that<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0excludes<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0many architectures by its design... Atmel AVR i= s another important<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0architecture.<br> <br> <br> =C2=A0 =C2=A0It doesn&#39;t exclude anything. What we&#39;re talking about= as desirable<br> =C2=A0 =C2=A0behaviour, is exactly what C does. If you care about performa= nce on<br> =C2=A0 =C2=A0ARM, you&#39;ll type sqrt(2.0f).<br> <br> =C2=A0 =C2=A0Personally, I&#39;d rather completely eliminate implicit conv= ersions<br> =C2=A0 =C2=A0between integers and floating point types. But that&#39;s jus= t me.<br> <br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0I maintain that implicit conversion of integers= of any length should<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0always target the same precision float, and tha= t should be a<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0compiler<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0flag to specify the desired precision throughou= t the app (possibly<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0defaulting to double).<br> <br> <br> =C2=A0 =C2=A0I can&#39;t believe that you&#39;d ever write an app without = that being an<br> =C2=A0 =C2=A0upfront decision. Casually flipping it with a compiler flag??= <br> =C2=A0 =C2=A0Remember that it affects very few things (as discussed below)= .<br> <br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0If you choose &#39;float&#39; you may lose some= precision obviously, but you<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0expected that when you chose the options, and d= id the cast...<br> <br> <br> =C2=A0 =C2=A0Explicit casts are not affected in any way.<br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Note that what we&#39;re discussi= ng here is parameter passing of<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0single<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0values; if it&#39;s part of an ag= gregate (array or struct), the<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0issue<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0doesn&#39;t arise.<br> <br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0Are we? I thought we were discussing implicit c= onversion of ints to<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0floats? This may be parameter passing, but also= assignment I expect?<br> <br> <br> =C2=A0 =C2=A0There&#39;s no problem with assignment, it&#39;s never ambigu= ous.<br> <br> =C2=A0 =C2=A0There seems to be some confusion about what the issue is.<br> =C2=A0 =C2=A0To reiterate:<br> <br> =C2=A0 =C2=A0void foo(float x) {}<br> =C2=A0 =C2=A0void foo(double x) {}<br> <br> =C2=A0 =C2=A0void bar(float x) {}<br> <br> =C2=A0 =C2=A0void baz(double x) {}<br> <br> =C2=A0 =C2=A0void main()<br> =C2=A0 =C2=A0{<br> =C2=A0 =C2=A0 =C2=A0 bar(2); // OK -- 2 becomes 2.0f<br> =C2=A0 =C2=A0 =C2=A0 baz(2); // OK -- 2 becomes 2.0<br> =C2=A0 =C2=A0 =C2=A0 foo(2); // fails -- ambiguous.<br> =C2=A0 =C2=A0}<br> <br> =C2=A0 =C2=A0My proposal was effectively: if it&#39;s ambiguous, choose do= uble.<br> =C2=A0 =C2=A0That&#39;s all.<br> <br> <br></div></div><div class=3D"im"> Yeah sorry, I think you&#39;re right, the discussion got slightly lost in<b= r> the noise here...<br> <br> Just to clarify, where you advocate eliminating implicit casting, do you<br=

ambiguous target?<br> <br> Let me reposition myself to suit what it would seem is actually being<br> discussed... :)<br> <br> void sqrt(float x);<br> void sqrt(double x);<br> void sqrt(real x);<br> <br> {<br> =C2=A0 sqrt(2);<br> }<br> <br></div> Surely this produces some error: &quot;Ambiguous call to overloaded<div cla= ss=3D"im"><br> function&quot;, and then there is no implicit cast rule to talk about... en= d<br> of discussion?<br> <br> But you speak of &quot;eliminating implicit casting&quot; as if this may al= so<br> refer to:<br> <br> void NotOverloaded(float x);<br> <br> {<br> =C2=A0 NotOverloaded(2); // not ambiguous... so what&#39;s the problem?<br=

</div></blockquote> <br> Actually there is a problem there, I think. If someone later on adds NotOve= rload(double x), that call will suddenly stop compiling.<br> <br> That isn&#39;t just a theoretical problem.<br> Currently log(2) will compile, but only because in std.math there is log(re= al), but not yet log(double) or log(float).<br> So once we add those overloads, peoples code will break.<br> <br> I&#39;d like to get to the situation where those overloads can be added wit= hout breaking peoples code. The draconian possibility is to disallow them i= n all cases: integer types never match floating point function parameters.<= br> The second possibility is to introduce a tie-breaker rule: when there&#39;s= an ambiguity, choose double.<br> And a third possibility is to only apply that tie-breaker rule to literals.= <br> And the fourth possibility is to keep the language as it is now, and allow = code to break when overloads get added.<br> <br> The one I really, really don&#39;t want, is the situation we have now:<br> #5: whenever an overload gets added, introduce a hack for that function...<= div class=3D"im"><br> <br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> or:<br> <br> float x =3D 10;<br> <br> Which I can imagine why most would feel this is undesirable...<br> <br> I&#39;m not clear now where you intend to draw the lines.<br> If you&#39;re advocating banning ALL implicit casting between float/int<br> outright, I actually feel really good about that idea. I can just<br> imagine the number of hours saved while optimising where junior/ignorant<br=

what they&#39;re doing.<br> <br> Or are we only drawing the distinction for literals?<br> I don&#39;t mind a compile error if I incorrectly state the literal a<br> function expects. That sort of thing becomes second nature in no time.<br> </blockquote> <br></div> I don&#39;t know. I think I probably prefer possibility #1 on my list, but = it&#39;d break existing code. I also like #2 and #3, and I think they&#39;d= be more generally popular.<br> I don&#39;t like #4, but anything is better than #5.<br> </blockquote></div><div><br></div><div>Hmmm.</div><div><br></div>I generall= y like #1, it encourages awareness of the clear distinction between integer= and floating types (something that far too many programmers lack)<div> <div>I don&#39;t really like #2, it&#39;s just arbitrary, and totally subje= ctive. You&#39;ll never have agreement, and perhaps more importantly, it&#3= 9;s not instinctively obvious which it will choose and why... you just have= to know, and most people won&#39;t know, they&#39;ll just use it blind (se= e my point about finding+fixing code by junior/ignorant programmers)</div> <div>#3 is just a less consistent version of #2... and less easy to catch t= he=C2=A0culprit=C2=A0committing the crime, and less obvious to the culprit = that they are committing a crime.</div><div>I don&#39;t HATE #4, it&#39;s n= ot capable of causing any real problem in the code, it just requires placem= ent of a cast, which anyone can do. But I prefer #1, solving that problem.<= /div> </div><div>#5 is obviously silly.</div><div><br></div><div>In order of pref= erence: 1, 4, 2, 3, 5</div><div><br></div><div>I could only support 2 if it= chooses &#39;float&#39;, the highest performance version on all architectu= res AND actually available on all architectures; given this is meant to be = a systems programming language, and supporting as many architectures as pos= sible?</div> <div>If the argument is made to favour precision, then it should surely be = real, not double... the counter argument is obviously that real is not supp= orted on many architectures, true, but the same is true for double... so I = think it&#39;s a hollow argument.</div> <div>double just seem like a weak compromise; more precise than float, and = more likely to work on more architectures than real (but still not guarante= ed), but it doesn&#39;t really satisfy either criteria neatly.</div><div> The logic transposed: double is less precise than real, and potentially slo= wer than float. Is the justification purely that it IS a compromise, since = the choice at the end of the day is totally subjective :)</div> --0016e648adcac0a95404afbb4c0e--
Oct 20 2011
prev sibling next sibling parent "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
On Thu, 20 Oct 2011 15:54:48 +0200, Manu <turkeyman gmail.com> wrote:

 I could only support 2 if it chooses 'float', the highest performance
 version on all architectures AND actually available on all architectures;
 given this is meant to be a systems programming language, and supporting  
 as
 many architectures as possible?

D specifically supports double (as a 64-bit float), regardless of the actual hardware. Also, the D way is to make the correct way simple, the fast way possible. This is clearly in favor of not using float, which *would* lead to precision loss. As for double vs real, a 32-bit int neatly fits in any double, making it good enough. short and byte should convert to float, and I'm not sure about long/ulong, since real may not have enough bits to accurately represent it. -- Simen
Oct 20 2011
prev sibling next sibling parent Manu <turkeyman gmail.com> writes:
--0016364ee67a89627e04afbf7558
Content-Type: text/plain; charset=UTF-8

On 20 October 2011 17:28, Simen Kjaeraas <simen.kjaras gmail.com> wrote:

 On Thu, 20 Oct 2011 15:54:48 +0200, Manu <turkeyman gmail.com> wrote:

  I could only support 2 if it chooses 'float', the highest performance
 version on all architectures AND actually available on all architectures;
 given this is meant to be a systems programming language, and supporting
 as
 many architectures as possible?

D specifically supports double (as a 64-bit float), regardless of the actual hardware. Also, the D way is to make the correct way simple, the fast way possible. This is clearly in favor of not using float, which *would* lead to precision loss.

Correct, on all architectures I'm aware of that don't have hardware double support, double is emulated, and that is EXTREMELY slow. I can't imagine any case where causing implicit (hidden) emulation of unsupported hardware should be considered 'correct', and therefore made easy. The reason I'm so concerned about this, is not for what I may or may not do in my code, I'm likely to be careful, but imagine some cool library that I want to make use of... some programmer has gone and written 'x = sqrt(2)' in this library somewhere; they don't require double precision, but it was implicitly used regardless of their intent. Now I can't use that library in my project. Any library that wasn't written with the intent of use in embedded systems in mind, that happens to omit all of 2 characters from their float literal, can no longer be used in my project. This makes me sad. I'd also like you to ask yourself realistically, of all the integers you've EVER cast to/from a float, how many have ever been a big/huge number? And if/when that occurred, what did you do with it? Was the precision important? Was it important enough to you to explicitly state the cast? The moment you use it in a mathematical operation you are likely throwing away a bunch of precision anyway, especially for the complex functions like sqrt/log/etc in question. --0016364ee67a89627e04afbf7558 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <div class=3D"gmail_quote">On 20 October 2011 17:28, Simen Kjaeraas <span d= ir=3D"ltr">&lt;<a href=3D"mailto:simen.kjaras gmail.com">simen.kjaras gmail= .com</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"ma= rgin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"> <div class=3D"im">On Thu, 20 Oct 2011 15:54:48 +0200, Manu &lt;<a href=3D"m= ailto:turkeyman gmail.com" target=3D"_blank">turkeyman gmail.com</a>&gt; wr= ote:<br> <br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> I could only support 2 if it chooses &#39;float&#39;, the highest performan= ce<br> version on all architectures AND actually available on all architectures;<b= r> given this is meant to be a systems programming language, and supporting as= <br> many architectures as possible?<br> </blockquote> <br></div> D specifically supports double (as a 64-bit float), regardless of the<br> actual hardware. Also, the D way is to make the correct way simple, the<br> fast way possible. This is clearly in favor of not using float, which<br> *would* lead to precision loss.<br></blockquote><div><br></div><div>Correct= , on all architectures I&#39;m aware of that don&#39;t have hardware double= support, double is emulated, and that is EXTREMELY slow.</div><div>I can&#= 39;t imagine any case where causing implicit (hidden) emulation of unsuppor= ted hardware should be considered &#39;correct&#39;, and therefore made eas= y.</div> <div><br></div><div>The reason I&#39;m so concerned about this, is not for = what I may or may not do in my code, I&#39;m likely to be careful, but=C2= =A0imagine some cool library that I want to make use of... some programmer = has gone and written &#39;x =3D sqrt(2)&#39; in this library somewhere; the= y don&#39;t require double precision, but it was implicitly used regardless= of their intent. Now I can&#39;t use that library in my project.</div> <div>Any library that wasn&#39;t written with the intent of use in embedded= systems in mind, that happens to omit all of 2 characters from their float= literal, can no longer be used in my project. This makes me sad.</div> <div><br></div><div>I&#39;d also like you to ask yourself realistically, of= all the integers you&#39;ve EVER cast to/from a float, how many have ever = been a big/huge number? And if/when that occurred, what did you do with it?= Was the precision important? Was it important enough to you to explicitly = state the cast?</div> <div>The moment you use it in a mathematical operation you are likely throw= ing away a bunch of precision anyway, especially for the complex functions = like sqrt/log/etc in question.</div></div> --0016364ee67a89627e04afbf7558--
Oct 20 2011
prev sibling next sibling parent "Marco Leise" <Marco.Leise gmx.de> writes:
Am 20.10.2011, 08:02 Uhr, schrieb Russel Winder <russel russel.org.uk>:

 On Wed, 2011-10-19 at 23:36 -0400, dsimcha wrote:
 On 10/19/2011 11:27 PM, Marco Leise wrote:
 And real can be used without protability problems on PowerPC or ARM?

Yes, it's just that they may only give 64 bits of precision. Floating point is inexact anyhow, though. IMHO the fact that you may lose a little precision with very large longs is not a game changer.

This is not convincing. One of the biggest problem is software development is that computers have two systems of hardware arithmetic that are mutually incompatible and have very different properties. Humans are taught that there are abstract numbers that can be put into different sets: reals, integers, naturals, etc. There are already far too many programmers out there who do not understand that computer numbers have representation problems and rounding errors. Another issue: sqrt ( 2 ) sqrt ( 2.0 ) sqrt ( 2.0000000000000000000000000000000000000000 ) actually mean very different things. The number of zeros carries information. Summary, losing precision is a game changer. This stuff matters. This is a hard problem.

Sure it matters, but performance also matters. If I needed the precision of a real, I would make sure that I give the compile the right hint. And adding zeros doesn't help. The representation is mantissa and exponent and your three examples would all come out the same in that representation. :) Is this really a real life problem, or can we just go with any solution for sqrt(2) that works (int->double, long->real) and leave the details to the ones who care and would write sqrt(2.0f) ?
Oct 20 2011
prev sibling next sibling parent "Marco Leise" <Marco.Leise gmx.de> writes:
Am 20.10.2011, 22:37 Uhr, schrieb Marco Leise <Marco.Leise gmx.de>:

 Am 20.10.2011, 08:02 Uhr, schrieb Russel Winder <russel russel.org.uk>:

 On Wed, 2011-10-19 at 23:36 -0400, dsimcha wrote:
 On 10/19/2011 11:27 PM, Marco Leise wrote:
 And real can be used without protability problems on PowerPC or ARM?

Yes, it's just that they may only give 64 bits of precision. Floating point is inexact anyhow, though. IMHO the fact that you may lose a little precision with very large longs is not a game changer.

This is not convincing. One of the biggest problem is software development is that computers have two systems of hardware arithmetic that are mutually incompatible and have very different properties. Humans are taught that there are abstract numbers that can be put into different sets: reals, integers, naturals, etc. There are already far too many programmers out there who do not understand that computer numbers have representation problems and rounding errors. Another issue: sqrt ( 2 ) sqrt ( 2.0 ) sqrt ( 2.0000000000000000000000000000000000000000 ) actually mean very different things. The number of zeros carries information. Summary, losing precision is a game changer. This stuff matters. This is a hard problem.

Sure it matters, but performance also matters. If I needed the precision of a real, I would make sure that I give the compile the right hint. And adding zeros doesn't help. The representation is mantissa and exponent and your three examples would all come out the same in that representation. :) Is this really a real life problem, or can we just go with any solution for sqrt(2) that works (int->double, long->real) and leave the details to the ones who care and would write sqrt(2.0f) ?

Forget what I said. If a 64-bit mantissa floating point type doesn't exist on all systems this doesn't work.
Oct 20 2011
prev sibling next sibling parent "Robert Jacques" <sandford jhu.edu> writes:
On Thu, 20 Oct 2011 09:11:27 -0400, Don <nospam nospam.com> wrote:
[snip]
 I'd like to get to the situation where those overloads can be added
 without breaking peoples code. The draconian possibility is to disallow
 them in all cases: integer types never match floating point function
 parameters.
 The second possibility is to introduce a tie-breaker rule: when there's
 an ambiguity, choose double.
 And a third possibility is to only apply that tie-breaker rule to literals.
 And the fourth possibility is to keep the language as it is now, and
 allow code to break when overloads get added.

 The one I really, really don't want, is the situation we have now:
 #5: whenever an overload gets added, introduce a hack for that function...

I agree that #5 and #4 not acceptable longer term solutions. I do CUDA/GPU programming, so I live in a world of floats and ints. So changing the rules does worries me, but mainly because most people don't use floats on a daily basis, which introduces bias into the discussion. Thinking it over, here are my suggestions, though I'm not sure if 2a or 2b would be best: 1) Integer literals and expressions should use range propagation to use the thinnest loss-less conversion. If no loss-less conversion exists, then an error is raised. Choosing double as a default is always the wrong choice for GPUs and most embedded systems. 2a) Lossy variable conversions are disallowed. 2b) Lossy variable conversions undergo bounds checking when asserts are turned on. The idea behind 2b) would be: int i = 1; float f = i; // assert(true); i = int.max; f = i; // assert(false);
Oct 20 2011
prev sibling next sibling parent Manu <turkeyman gmail.com> writes:
--0016364ee67a4c5ce004afca5d73
Content-Type: text/plain; charset=UTF-8

On 21 October 2011 09:00, Don <nospam nospam.com> wrote:

 On 21.10.2011 05:24, Robert Jacques wrote:

 On Thu, 20 Oct 2011 09:11:27 -0400, Don <nospam nospam.com> wrote:
 [snip]

 I'd like to get to the situation where those overloads can be added
 without breaking peoples code. The draconian possibility is to disallow
 them in all cases: integer types never match floating point function
 parameters.
 The second possibility is to introduce a tie-breaker rule: when there's
 an ambiguity, choose double.
 And a third possibility is to only apply that tie-breaker rule to
 literals.
 And the fourth possibility is to keep the language as it is now, and
 allow code to break when overloads get added.

 The one I really, really don't want, is the situation we have now:
 #5: whenever an overload gets added, introduce a hack for that
 function...

I agree that #5 and #4 not acceptable longer term solutions. I do CUDA/GPU programming, so I live in a world of floats and ints. So changing the rules does worries me, but mainly because most people don't use floats on a daily basis, which introduces bias into the discussion.

Yeah, that's a valuable perspective. sqrt(2) is "I don't care what the precision is". What I get from you and Manu is: if you're working in a float world, you want float to be the tiebreaker. Otherwise, you want double (or possibly real!) to be the tiebreaker. And therefore, the
 Thinking it over, here are my suggestions, though I'm not sure if 2a or
 2b would be best:

 1) Integer literals and expressions should use range propagation to use
 the thinnest loss-less conversion. If no loss-less conversion exists,
 then an error is raised. Choosing double as a default is always the
 wrong choice for GPUs and most embedded systems.
 2a) Lossy variable conversions are disallowed.
 2b) Lossy variable conversions undergo bounds checking when asserts are
 turned on.

The spec says: "Integer values cannot be implicitly converted to another type that cannot represent the integer bit pattern after integral promotion." Now although that was intended to only apply to integers, it reads as if it should apply to floating point as well. The idea behind 2b) would be:
 int i = 1;
 float f = i; // assert(true);
 i = int.max;
 f = i; // assert(false);

That would be catastrophically slow. I wonder how painful disallowing lossy conversions would be.

1: Seems reasonable for literals; "Integer literals and expressions should use range propagation to use the thinnest loss-less conversion"... but can you clarify what you mean by 'expressions'? I assume we're talking strictly literal expressions? 2b: Does runtime bounds checking actually addresses the question; which of an ambiguous function to choose? If I read you correctly, 2b suggests bounds checking the implicit cast for data loss at runtime, but which to choose? float/double/real? We'll still arguing that question even with this proposal taken into consideration... :/ Perhaps I missed something? Naturally all this complexity assumes we go with the tie-breaker approach, which I'm becoming more and more convinced is a bad plan... --0016364ee67a4c5ce004afca5d73 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <div class=3D"gmail_quote">On 21 October 2011 09:00, Don <span dir=3D"ltr">= &lt;<a href=3D"mailto:nospam nospam.com">nospam nospam.com</a>&gt;</span> w= rote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;borde= r-left:1px #ccc solid;padding-left:1ex;"> <div class=3D"im">On 21.10.2011 05:24, Robert Jacques wrote:<br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> On Thu, 20 Oct 2011 09:11:27 -0400, Don &lt;<a href=3D"mailto:nospam nospam= .com" target=3D"_blank">nospam nospam.com</a>&gt; wrote:<br> [snip]<br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> I&#39;d like to get to the situation where those overloads can be added<br> without breaking peoples code. The draconian possibility is to disallow<br> them in all cases: integer types never match floating point function<br> parameters.<br> The second possibility is to introduce a tie-breaker rule: when there&#39;s= <br> an ambiguity, choose double.<br> And a third possibility is to only apply that tie-breaker rule to<br> literals.<br> And the fourth possibility is to keep the language as it is now, and<br> allow code to break when overloads get added.<br> <br> The one I really, really don&#39;t want, is the situation we have now:<br> #5: whenever an overload gets added, introduce a hack for that<br> function...<br> </blockquote> <br> I agree that #5 and #4 not acceptable longer term solutions. I do<br> CUDA/GPU programming, so I live in a world of floats and ints. So<br> changing the rules does worries me, but mainly because most people don&#39;= t<br> use floats on a daily basis, which introduces bias into the discussion.<br> </blockquote> <br></div> Yeah, that&#39;s a valuable perspective.<br> sqrt(2) is &quot;I don&#39;t care what the precision is&quot;.<br> What I get from you and Manu is:<br> if you&#39;re working in a float world, you want float to be the tiebreaker= .<br> Otherwise, you want double (or possibly real!) to be the tiebreaker.<br> <br> And therefore, the<div class=3D"im"><br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> <br> Thinking it over, here are my suggestions, though I&#39;m not sure if 2a or= <br> 2b would be best:<br> <br> 1) Integer literals and expressions should use range propagation to use<br> the thinnest loss-less conversion. If no loss-less conversion exists,<br> then an error is raised. Choosing double as a default is always the<br> wrong choice for GPUs and most embedded systems.<br> 2a) Lossy variable conversions are disallowed.<br> 2b) Lossy variable conversions undergo bounds checking when asserts are<br> turned on.<br> </blockquote> <br></div> The spec says: &quot;Integer values cannot be implicitly converted to anoth= er type that cannot represent the integer bit pattern after integral promot= ion.&quot;<br> Now although that was intended to only apply to integers, it reads as if it= should apply to floating point as well.<div class=3D"im"><br> <br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> The idea behind 2b) would be:<br> <br> int i =3D 1;<br> float f =3D i; // assert(true);<br> i =3D int.max;<br> f =3D i; // assert(false);<br> </blockquote> <br></div> That would be catastrophically slow.<br> <br> I wonder how painful disallowing lossy conversions would be.<br></blockquot= e><div><br></div><div class=3D"gmail_quote"><div>1: Seems reasonable for li= terals; &quot;Integer literals and expressions should use range propagation= to use</div> the thinnest loss-less conversion&quot;... but can you clarify what you mea= n by &#39;expressions&#39;? I assume we&#39;re talking strictly literal exp= ressions?</div><div><br></div><div>2b: Does runtime bounds checking actuall= y=C2=A0addresses the question; which of an ambiguous function to choose?</d= iv> <div>If I read you correctly, 2b suggests bounds checking the implicit cast= for data loss at runtime, but which to choose? float/double/real? We&#39;l= l still arguing that question even with this proposal taken into considerat= ion... :/</div> <div>Perhaps I missed something?</div><div><br></div><div>Naturally all thi= s complexity assumes we go with the tie-breaker approach, which I&#39;m bec= oming more and more convinced is a bad plan...</div></div> --0016364ee67a4c5ce004afca5d73--
Oct 21 2011
prev sibling next sibling parent Manu <turkeyman gmail.com> writes:
--0016364ee67a7b43c204afcea982
Content-Type: text/plain; charset=UTF-8

On 21 October 2011 10:53, Manu <turkeyman gmail.com> wrote:

 On 21 October 2011 09:00, Don <nospam nospam.com> wrote:

 On 21.10.2011 05:24, Robert Jacques wrote:

 On Thu, 20 Oct 2011 09:11:27 -0400, Don <nospam nospam.com> wrote:
 [snip]

 I'd like to get to the situation where those overloads can be added
 without breaking peoples code. The draconian possibility is to disallow
 them in all cases: integer types never match floating point function
 parameters.
 The second possibility is to introduce a tie-breaker rule: when there's
 an ambiguity, choose double.
 And a third possibility is to only apply that tie-breaker rule to
 literals.
 And the fourth possibility is to keep the language as it is now, and
 allow code to break when overloads get added.

 The one I really, really don't want, is the situation we have now:
 #5: whenever an overload gets added, introduce a hack for that
 function...

I agree that #5 and #4 not acceptable longer term solutions. I do CUDA/GPU programming, so I live in a world of floats and ints. So changing the rules does worries me, but mainly because most people don't use floats on a daily basis, which introduces bias into the discussion.

Yeah, that's a valuable perspective. sqrt(2) is "I don't care what the precision is". What I get from you and Manu is: if you're working in a float world, you want float to be the tiebreaker. Otherwise, you want double (or possibly real!) to be the tiebreaker. And therefore, the
 Thinking it over, here are my suggestions, though I'm not sure if 2a or
 2b would be best:

 1) Integer literals and expressions should use range propagation to use
 the thinnest loss-less conversion. If no loss-less conversion exists,
 then an error is raised. Choosing double as a default is always the
 wrong choice for GPUs and most embedded systems.
 2a) Lossy variable conversions are disallowed.
 2b) Lossy variable conversions undergo bounds checking when asserts are
 turned on.

The spec says: "Integer values cannot be implicitly converted to another type that cannot represent the integer bit pattern after integral promotion." Now although that was intended to only apply to integers, it reads as if it should apply to floating point as well. The idea behind 2b) would be:
 int i = 1;
 float f = i; // assert(true);
 i = int.max;
 f = i; // assert(false);

That would be catastrophically slow. I wonder how painful disallowing lossy conversions would be.

1: Seems reasonable for literals; "Integer literals and expressions should use range propagation to use the thinnest loss-less conversion"... but can you clarify what you mean by 'expressions'? I assume we're talking strictly literal expressions? 2b: Does runtime bounds checking actually addresses the question; which of an ambiguous function to choose? If I read you correctly, 2b suggests bounds checking the implicit cast for data loss at runtime, but which to choose? float/double/real? We'll still arguing that question even with this proposal taken into consideration... :/ Perhaps I missed something? Naturally all this complexity assumes we go with the tie-breaker approach, which I'm becoming more and more convinced is a bad plan...

Then again, with regards to 1, the function chosen will depend on the magnitude of the int, perhaps a foreign constant, you might not clearly be able to know which one is called... What if the ambiguous overloads don't actually perform identical functionality with just different precision? .. I don't like the idea of it being uncertain. And one more thing to ponder, is the return type telling here? float x = sqrt(2); Obviously this may only work for these pure maths functions where the return type is matched to the args, but maybe it's an element worth considering. ie, if the function parameter is ambiguous, check for disambiguation via the return type...? Sounds pretty nasty! :) --0016364ee67a7b43c204afcea982 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <div class=3D"gmail_quote">On 21 October 2011 10:53, Manu <span dir=3D"ltr"=
&lt;<a href=3D"mailto:turkeyman gmail.com">turkeyman gmail.com</a>&gt;</sp=

border-left:1px #ccc solid;padding-left:1ex;"> <div class=3D"gmail_quote"><div><div></div><div class=3D"h5">On 21 October = 2011 09:00, Don <span dir=3D"ltr">&lt;<a href=3D"mailto:nospam nospam.com" = target=3D"_blank">nospam nospam.com</a>&gt;</span> wrote:<br><blockquote cl= ass=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;p= adding-left:1ex"> <div>On 21.10.2011 05:24, Robert Jacques wrote:<br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> On Thu, 20 Oct 2011 09:11:27 -0400, Don &lt;<a href=3D"mailto:nospam nospam= .com" target=3D"_blank">nospam nospam.com</a>&gt; wrote:<br> [snip]<br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> I&#39;d like to get to the situation where those overloads can be added<br> without breaking peoples code. The draconian possibility is to disallow<br> them in all cases: integer types never match floating point function<br> parameters.<br> The second possibility is to introduce a tie-breaker rule: when there&#39;s= <br> an ambiguity, choose double.<br> And a third possibility is to only apply that tie-breaker rule to<br> literals.<br> And the fourth possibility is to keep the language as it is now, and<br> allow code to break when overloads get added.<br> <br> The one I really, really don&#39;t want, is the situation we have now:<br> #5: whenever an overload gets added, introduce a hack for that<br> function...<br> </blockquote> <br> I agree that #5 and #4 not acceptable longer term solutions. I do<br> CUDA/GPU programming, so I live in a world of floats and ints. So<br> changing the rules does worries me, but mainly because most people don&#39;= t<br> use floats on a daily basis, which introduces bias into the discussion.<br> </blockquote> <br></div> Yeah, that&#39;s a valuable perspective.<br> sqrt(2) is &quot;I don&#39;t care what the precision is&quot;.<br> What I get from you and Manu is:<br> if you&#39;re working in a float world, you want float to be the tiebreaker= .<br> Otherwise, you want double (or possibly real!) to be the tiebreaker.<br> <br> And therefore, the<div><br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> <br> Thinking it over, here are my suggestions, though I&#39;m not sure if 2a or= <br> 2b would be best:<br> <br> 1) Integer literals and expressions should use range propagation to use<br> the thinnest loss-less conversion. If no loss-less conversion exists,<br> then an error is raised. Choosing double as a default is always the<br> wrong choice for GPUs and most embedded systems.<br> 2a) Lossy variable conversions are disallowed.<br> 2b) Lossy variable conversions undergo bounds checking when asserts are<br> turned on.<br> </blockquote> <br></div> The spec says: &quot;Integer values cannot be implicitly converted to anoth= er type that cannot represent the integer bit pattern after integral promot= ion.&quot;<br> Now although that was intended to only apply to integers, it reads as if it= should apply to floating point as well.<div><br> <br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> The idea behind 2b) would be:<br> <br> int i =3D 1;<br> float f =3D i; // assert(true);<br> i =3D int.max;<br> f =3D i; // assert(false);<br> </blockquote> <br></div> That would be catastrophically slow.<br> <br> I wonder how painful disallowing lossy conversions would be.<br></blockquot= e><div><br></div></div></div><div class=3D"gmail_quote"><div>1: Seems reaso= nable for literals; &quot;Integer literals and expressions should use range= propagation to use</div> the thinnest loss-less conversion&quot;... but can you clarify what you mea= n by &#39;expressions&#39;? I assume we&#39;re talking strictly literal exp= ressions?</div><div><br></div><div>2b: Does runtime bounds checking actuall= y=C2=A0addresses the question; which of an ambiguous function to choose?</d= iv> <div>If I read you correctly, 2b suggests bounds checking the implicit cast= for data loss at runtime, but which to choose? float/double/real? We&#39;l= l still arguing that question even with this proposal taken into considerat= ion... :/</div> <div>Perhaps I missed something?</div><div><br></div><div>Naturally all thi= s complexity assumes we go with the tie-breaker approach, which I&#39;m bec= oming more and more convinced is a bad plan...</div></div> </blockquote></div><br><div>Then again, with regards to 1, the function cho= sen will depend on the magnitude of the int, perhaps a foreign constant, yo= u might not clearly be able to know which one is called... What if the ambi= guous overloads don&#39;t actually perform identical functionality with jus= t different precision? .. I don&#39;t like the idea of it being uncertain.<= /div> <div><br></div><div>And one more thing to ponder, is the return type tellin= g here?</div><div>float x =3D sqrt(2);</div><div>Obviously this may only wo= rk for these pure maths functions where the return type is matched to the a= rgs, but maybe it&#39;s an element worth considering.</div> <div>ie, if the function parameter is ambiguous, check for disambiguation v= ia the return type...? Sounds pretty nasty! :)</div> --0016364ee67a7b43c204afcea982--
Oct 21 2011
prev sibling next sibling parent "Robert Jacques" <sandford jhu.edu> writes:
On Fri, 21 Oct 2011 09:00:48 -0400, Manu <turkeyman gmail.com> wrote:
 On 21 October 2011 10:53, Manu <turkeyman gmail.com> wrote:
 On 21 October 2011 09:00, Don <nospam nospam.com> wrote:


 1: Seems reasonable for literals; "Integer literals and expressions should
 use range propagation to use
 the thinnest loss-less conversion"... but can you clarify what you mean by
 'expressions'? I assume we're talking strictly literal expressions?


Consider sqrt(i % 10). No matter what i is, the range of i % 10 is 0-9. I was more thinking of whether plain old assignment would be allowed: float f = myshort; Of course, if we deny implicit conversion, shouldn't the following fail to compile? float position = index * resolution;
 2b: Does runtime bounds checking actually addresses the question; which of
 an ambiguous function to choose?
 If I read you correctly, 2b suggests bounds checking the implicit cast for
 data loss at runtime, but which to choose? float/double/real? We'll still
 arguing that question even with this proposal taken into consideration... :/
 Perhaps I missed something?


Yes, nut only because I didn't include it. I was thinking of float f = i; as opposed to func(i) for some reason. Bounds checking would only make sense if func(float) was the only overload.
 Naturally all this complexity assumes we go with the tie-breaker approach,
 which I'm becoming more and more convinced is a bad plan...

Then again, with regards to 1, the function chosen will depend on the magnitude of the int, perhaps a foreign constant, you might not clearly be able to know which one is called... What if the ambiguous overloads don't actually perform identical functionality with just different precision? ..

Then whoever wrote the library was Evil(tm). Given that these rules wouldn't interfere with function hijacking, I'm not sure of the practicality of this concern. Do you have an example?
 I don't like the idea of it being uncertain.

 And one more thing to ponder, is the return type telling here?
 float x = sqrt(2);
 Obviously this may only work for these pure maths functions where the
 return type is matched to the args, but maybe it's an element worth
 considering.
 ie, if the function parameter is ambiguous, check for disambiguation via
 the return type...? Sounds pretty nasty! :)

Oct 21 2011
prev sibling next sibling parent Manu <turkeyman gmail.com> writes:
--0016368324ec4c589d04afd7195d
Content-Type: text/plain; charset=UTF-8

It would still allow function hijacking.
void func(double v); exists...
func(2);
then someone comes along and adds func(float v); .. It will now hijack the
call.
That's what you mean right?

On Oct 22, 2011 1:45 AM, "Robert Jacques" <sandford jhu.edu> wrote:
 On Fri, 21 Oct 2011 09:00:48 -0400, Manu <turkeyman gmail.com> wrote:
 On 21 October 2011 10:53, Manu <turkeyman gmail.com> wrote:
 On 21 October 2011 09:00, Don <nospam nospam.com> wrote:


[snip]
 1: Seems reasonable for literals; "Integer literals and expressions



 use range propagation to use
 the thinnest loss-less conversion"... but can you clarify what you mean



 'expressions'? I assume we're talking strictly literal expressions?


Consider sqrt(i % 10). No matter what i is, the range of i % 10 is 0-9. I was more thinking of whether plain old assignment would be allowed: float f = myshort; Of course, if we deny implicit conversion, shouldn't the following fail

 float position = index * resolution;


 2b: Does runtime bounds checking actually addresses the question; which



 an ambiguous function to choose?
 If I read you correctly, 2b suggests bounds checking the implicit cast



 data loss at runtime, but which to choose? float/double/real? We'll



 arguing that question even with this proposal taken into



 Perhaps I missed something?


Yes, nut only because I didn't include it. I was thinking of float f = i; as opposed to func(i) for some reason. Bounds checking would only make sense if func(float) was

 Naturally all this complexity assumes we go with the tie-breaker



 which I'm becoming more and more convinced is a bad plan...

Then again, with regards to 1, the function chosen will depend on the magnitude of the int, perhaps a foreign constant, you might not clearly


 able to know which one is called... What if the ambiguous overloads don't
 actually perform identical functionality with just different precision?


 Then whoever wrote the library was Evil(tm). Given that these rules

practicality of this concern. Do you have an example?
 I don't like the idea of it being uncertain.

 And one more thing to ponder, is the return type telling here?
 float x = sqrt(2);
 Obviously this may only work for these pure maths functions where the
 return type is matched to the args, but maybe it's an element worth
 considering.
 ie, if the function parameter is ambiguous, check for disambiguation via
 the return type...? Sounds pretty nasty! :)


--0016368324ec4c589d04afd7195d Content-Type: text/html; charset=UTF-8 <p>It would still allow function hijacking.<br> void func(double v); exists...<br> func(2);<br> then someone comes along and adds func(float v); .. It will now hijack the call.<br> That&#39;s what you mean right?</p> <p>On Oct 22, 2011 1:45 AM, &quot;Robert Jacques&quot; &lt;<a href="mailto:sandford jhu.edu">sandford jhu.edu</a>&gt; wrote:<br> &gt;<br> &gt; On Fri, 21 Oct 2011 09:00:48 -0400, Manu &lt;<a href="mailto:turkeyman gmail.com">turkeyman gmail.com</a>&gt; wrote:<br> &gt;&gt;<br> &gt;&gt; On 21 October 2011 10:53, Manu &lt;<a href="mailto:turkeyman gmail.com">turkeyman gmail.com</a>&gt; wrote:<br> &gt;&gt;&gt;<br> &gt;&gt;&gt; On 21 October 2011 09:00, Don &lt;<a href="mailto:nospam nospam.com">nospam nospam.com</a>&gt; wrote:<br> &gt;<br> &gt; [snip]<br> &gt;<br> &gt;&gt;&gt; 1: Seems reasonable for literals; &quot;Integer literals and expressions should<br> &gt;&gt;&gt; use range propagation to use<br> &gt;&gt;&gt; the thinnest loss-less conversion&quot;... but can you clarify what you mean by<br> &gt;&gt;&gt; &#39;expressions&#39;? I assume we&#39;re talking strictly literal expressions?<br> &gt;<br> &gt;<br> &gt; Consider sqrt(i % 10). No matter what i is, the range of i % 10 is 0-9.<br> &gt;<br> &gt; I was more thinking of whether plain old assignment would be allowed:<br> &gt;<br> &gt; float f = myshort;<br> &gt;<br> &gt; Of course, if we deny implicit conversion, shouldn&#39;t the following fail to compile?<br> &gt;<br> &gt; float position = index * resolution;<br> &gt;<br> &gt;<br> &gt;&gt;&gt; 2b: Does runtime bounds checking actually addresses the question; which of<br> &gt;&gt;&gt; an ambiguous function to choose?<br> &gt;&gt;&gt; If I read you correctly, 2b suggests bounds checking the implicit cast for<br> &gt;&gt;&gt; data loss at runtime, but which to choose? float/double/real? We&#39;ll still<br> &gt;&gt;&gt; arguing that question even with this proposal taken into consideration... :/<br> &gt;&gt;&gt; Perhaps I missed something?<br> &gt;<br> &gt;<br> &gt; Yes, nut only because I didn&#39;t include it. I was thinking of<br> &gt;<br> &gt; float f = i;<br> &gt;<br> &gt; as opposed to<br> &gt;<br> &gt; func(i)<br> &gt;<br> &gt; for some reason. Bounds checking would only make sense if func(float) was the only overload.<br> &gt;<br> &gt;&gt;&gt; Naturally all this complexity assumes we go with the tie-breaker approach,<br> &gt;&gt;&gt; which I&#39;m becoming more and more convinced is a bad plan...<br> &gt;&gt;&gt;<br> &gt;&gt;<br> &gt;&gt; Then again, with regards to 1, the function chosen will depend on the<br> &gt;&gt; magnitude of the int, perhaps a foreign constant, you might not clearly be<br> &gt;&gt; able to know which one is called... What if the ambiguous overloads don&#39;t<br> &gt;&gt; actually perform identical functionality with just different precision? ..<br> &gt;<br> &gt;<br> &gt; Then whoever wrote the library was Evil(tm). Given that these rules wouldn&#39;t interfere with function hijacking, I&#39;m not sure of the practicality of this concern. Do you have an example?<br> &gt;<br> &gt;<br> &gt;&gt; I don&#39;t like the idea of it being uncertain.<br> &gt;&gt;<br> &gt;&gt; And one more thing to ponder, is the return type telling here?<br> &gt;&gt; float x = sqrt(2);<br> &gt;&gt; Obviously this may only work for these pure maths functions where the<br> &gt;&gt; return type is matched to the args, but maybe it&#39;s an element worth<br> &gt;&gt; considering.<br> &gt;&gt; ie, if the function parameter is ambiguous, check for disambiguation via<br> &gt;&gt; the return type...? Sounds pretty nasty! :)<br> </p> --0016368324ec4c589d04afd7195d--
Oct 21 2011
prev sibling next sibling parent "Robert Jacques" <sandford jhu.edu> writes:
On Fri, 21 Oct 2011 19:04:43 -0400, Manu <turkeyman gmail.com> wrote:
 It would still allow function hijacking.
 void func(double v); exists...
 func(2);
 then someone comes along and adds func(float v); .. It will now hijack the
 call.
 That's what you mean right?

Hijacking is what happends when someone adds func(float v); _in another module_. And that hijack would/should still be detected, etc. like any other hijack.
Oct 21 2011
prev sibling next sibling parent Manu <turkeyman gmail.com> writes:
--0016364ee67af1727f04afe000f7
Content-Type: text/plain; charset=UTF-8

Sure, and hijacking is bound to happen under your proposal, no?
How would it be detected?

On 22 October 2011 06:51, Robert Jacques <sandford jhu.edu> wrote:

 On Fri, 21 Oct 2011 19:04:43 -0400, Manu <turkeyman gmail.com> wrote:

 It would still allow function hijacking.
 void func(double v); exists...
 func(2);
 then someone comes along and adds func(float v); .. It will now hijack the
 call.
 That's what you mean right?

Hijacking is what happends when someone adds func(float v); _in another module_. And that hijack would/should still be detected, etc. like any other hijack.

--0016364ee67af1727f04afe000f7 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Sure, and hijacking is bound to happen under your proposal, no?<div>How wou= ld it be detected?<br><br><div class=3D"gmail_quote">On 22 October 2011 06:= 51, Robert Jacques <span dir=3D"ltr">&lt;<a href=3D"mailto:sandford jhu.edu= ">sandford jhu.edu</a>&gt;</span> wrote:<br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex;"><div class=3D"im">On Fri, 21 Oct 2011 19:04= :43 -0400, Manu &lt;<a href=3D"mailto:turkeyman gmail.com" target=3D"_blank= ">turkeyman gmail.com</a>&gt; wrote:<br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> It would still allow function hijacking.<br> void func(double v); exists...<br> func(2);<br> then someone comes along and adds func(float v); .. It will now hijack the<= br> call.<br> That&#39;s what you mean right?<br> </blockquote> <br></div> Hijacking is what happends when someone adds func(float v); _in another mod= ule_. And that hijack would/should still be detected, etc. like any other h= ijack.<br> </blockquote></div><br></div> --0016364ee67af1727f04afe000f7--
Oct 22 2011
prev sibling parent Manu <turkeyman gmail.com> writes:
--0016361e821035c53f04afff5ebe
Content-Type: text/plain; charset=UTF-8

Okay so we're thinking of allowing implicit casting now ONLY if it can be
guaranteed that the cast is lossless?

I don't see how this addresses the original question though, which was how
to resolve an ambiguous function selection? It selects the smallest one it
will fit into?
Does that mean it will always choose the double version if you pass an
int32 without any extra info narrowing its possible bounds?

On 23 October 2011 22:36, Don <nospam nospam.com> wrote:

 On 21.10.2011 09:53, Manu wrote:

 On 21 October 2011 09:00, Don <nospam nospam.com

 <mailto:nospam nospam.com>> wrote:

    On 21.10.2011 05:24, Robert Jacques wrote:

        On Thu, 20 Oct 2011 09:11:27 -0400, Don <nospam nospam.com
        <mailto:nospam nospam.com>> wrote:
        [snip]

            I'd like to get to the situation where those overloads can
            be added
            without breaking peoples code. The draconian possibility is
            to disallow
            them in all cases: integer types never match floating point
            function
            parameters.
            The second possibility is to introduce a tie-breaker rule:
            when there's
            an ambiguity, choose double.
            And a third possibility is to only apply that tie-breaker
            rule to
            literals.
            And the fourth possibility is to keep the language as it is
            now, and
            allow code to break when overloads get added.

            The one I really, really don't want, is the situation we
            have now:
            #5: whenever an overload gets added, introduce a hack for that
            function...


        I agree that #5 and #4 not acceptable longer term solutions. I do
        CUDA/GPU programming, so I live in a world of floats and ints. So
        changing the rules does worries me, but mainly because most
        people don't
        use floats on a daily basis, which introduces bias into the
        discussion.


    Yeah, that's a valuable perspective.
    sqrt(2) is "I don't care what the precision is".
    What I get from you and Manu is:
    if you're working in a float world, you want float to be the
 tiebreaker.
    Otherwise, you want double (or possibly real!) to be the tiebreaker.

    And therefore, the


        Thinking it over, here are my suggestions, though I'm not sure
        if 2a or
        2b would be best:

        1) Integer literals and expressions should use range propagation
        to use
        the thinnest loss-less conversion. If no loss-less conversion
        exists,
        then an error is raised. Choosing double as a default is always the
        wrong choice for GPUs and most embedded systems.
        2a) Lossy variable conversions are disallowed.
        2b) Lossy variable conversions undergo bounds checking when
        asserts are
        turned on.


    The spec says: "Integer values cannot be implicitly converted to
    another type that cannot represent the integer bit pattern after
    integral promotion."
    Now although that was intended to only apply to integers, it reads
    as if it should apply to floating point as well.


        The idea behind 2b) would be:

        int i = 1;
        float f = i; // assert(true);
        i = int.max;
        f = i; // assert(false);


    That would be catastrophically slow.

    I wonder how painful disallowing lossy conversions would be.


 1: Seems reasonable for literals; "Integer literals and expressions

 should use range propagation to use
 the thinnest loss-less conversion"... but can you clarify what you mean
 by 'expressions'? I assume we're talking strictly literal expressions?

Any expression. Just as right now, long converts to int only if the long expression is guaranteed to fit into 32 bits. Of course, if it's a literal, this is very easy. 2b: Does runtime bounds checking actually addresses the question; which
 of an ambiguous function to choose?
 If I read you correctly, 2b suggests bounds checking the implicit cast
 for data loss at runtime, but which to choose? float/double/real? We'll
 still arguing that question even with this proposal taken into
 consideration... :/

It's an independent issue. Perhaps I missed something?
 Naturally all this complexity assumes we go with the tie-breaker
 approach, which I'm becoming more and more convinced is a bad plan...

No, it doesn't. As I said, this is independent. Except that it does mean that some existing int->float conversions would be disallowed. EG, float foo(int x) { return x; } wouldn't compile, because x might not fit into a float without loss of accuracy.

--0016361e821035c53f04afff5ebe Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Okay so we&#39;re thinking of allowing implicit casting now ONLY=C2=A0if it= can be guaranteed that the cast is lossless?<div><br></div><div>I don&#39;= t see how this addresses the original question though, which was how to res= olve an ambiguous function selection? It selects the smallest one it will f= it into?</div> <div>Does that mean it will always choose the double version if you pass an= int32 without any extra info narrowing its possible bounds?</div><div><br>= <div class=3D"gmail_quote">On 23 October 2011 22:36, Don <span dir=3D"ltr">= &lt;<a href=3D"mailto:nospam nospam.com">nospam nospam.com</a>&gt;</span> w= rote:<br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex;">On 21.10.2011 09:53, Manu wrote:<br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> On 21 October 2011 09:00, Don &lt;<a href=3D"mailto:nospam nospam.com" targ= et=3D"_blank">nospam nospam.com</a><div class=3D"im"><br> &lt;mailto:<a href=3D"mailto:nospam nospam.com" target=3D"_blank">nospam no= spam.com</a>&gt;&gt; wrote:<br> <br> =C2=A0 =C2=A0On 21.10.2011 05:24, Robert Jacques wrote:<br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0On Thu, 20 Oct 2011 09:11:27 -0400, Don &lt;<a = href=3D"mailto:nospam nospam.com" target=3D"_blank">nospam nospam.com</a><b= r></div><div><div></div><div class=3D"h5"> =C2=A0 =C2=A0 =C2=A0 =C2=A0&lt;mailto:<a href=3D"mailto:nospam nospam.com"= target=3D"_blank">nospam nospam.com</a>&gt;&gt; wrote:<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0[snip]<br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0I&#39;d like to get to the situat= ion where those overloads can<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0be added<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0without breaking peoples code. Th= e draconian possibility is<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0to disallow<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0them in all cases: integer types = never match floating point<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0function<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0parameters.<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0The second possibility is to intr= oduce a tie-breaker rule:<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0when there&#39;s<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0an ambiguity, choose double.<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0And a third possibility is to onl= y apply that tie-breaker<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0rule to<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0literals.<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0And the fourth possibility is to = keep the language as it is<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0now, and<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0allow code to break when overload= s get added.<br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0The one I really, really don&#39;= t want, is the situation we<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0have now:<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0#5: whenever an overload gets add= ed, introduce a hack for that<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0function...<br> <br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0I agree that #5 and #4 not acceptable longer te= rm solutions. I do<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0CUDA/GPU programming, so I live in a world of f= loats and ints. So<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0changing the rules does worries me, but mainly = because most<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0people don&#39;t<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0use floats on a daily basis, which introduces b= ias into the<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0discussion.<br> <br> <br> =C2=A0 =C2=A0Yeah, that&#39;s a valuable perspective.<br> =C2=A0 =C2=A0sqrt(2) is &quot;I don&#39;t care what the precision is&quot;= .<br> =C2=A0 =C2=A0What I get from you and Manu is:<br> =C2=A0 =C2=A0if you&#39;re working in a float world, you want float to be = the tiebreaker.<br> =C2=A0 =C2=A0Otherwise, you want double (or possibly real!) to be the tieb= reaker.<br> <br> =C2=A0 =C2=A0And therefore, the<br> <br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0Thinking it over, here are my suggestions, thou= gh I&#39;m not sure<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0if 2a or<br> =C2=A0 =C2=A0 =C2=A0 =C2=A02b would be best:<br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A01) Integer literals and expressions should use = range propagation<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0to use<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0the thinnest loss-less conversion. If no loss-l= ess conversion<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0exists,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0then an error is raised. Choosing double as a d= efault is always the<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0wrong choice for GPUs and most embedded systems= .<br> =C2=A0 =C2=A0 =C2=A0 =C2=A02a) Lossy variable conversions are disallowed.<= br> =C2=A0 =C2=A0 =C2=A0 =C2=A02b) Lossy variable conversions undergo bounds c= hecking when<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0asserts are<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0turned on.<br> <br> <br> =C2=A0 =C2=A0The spec says: &quot;Integer values cannot be implicitly conv= erted to<br> =C2=A0 =C2=A0another type that cannot represent the integer bit pattern af= ter<br> =C2=A0 =C2=A0integral promotion.&quot;<br> =C2=A0 =C2=A0Now although that was intended to only apply to integers, it = reads<br> =C2=A0 =C2=A0as if it should apply to floating point as well.<br> <br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0The idea behind 2b) would be:<br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0int i =3D 1;<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0float f =3D i; // assert(true);<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0i =3D int.max;<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0f =3D i; // assert(false);<br> <br> <br> =C2=A0 =C2=A0That would be catastrophically slow.<br> <br> =C2=A0 =C2=A0I wonder how painful disallowing lossy conversions would be.<= br> <br> <br></div></div> 1: Seems reasonable for literals; &quot;Integer literals and expressions<di= v class=3D"im"><br> should use range propagation to use<br></div><div class=3D"im"> the thinnest loss-less conversion&quot;... but can you clarify what you mea= n<br> by &#39;expressions&#39;? I assume we&#39;re talking strictly literal expre= ssions?<br> </div></blockquote> <br> Any expression. Just as right now, long converts to int only if the long ex= pression is guaranteed to fit into 32 bits.<br> Of course, if it&#39;s a literal, this is very easy.<div class=3D"im"><br> <br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> 2b: Does runtime bounds checking actually addresses the question; which<br> of an ambiguous function to choose?<br> If I read you correctly, 2b suggests bounds checking the implicit cast<br> for data loss at runtime, but which to choose? float/double/real? We&#39;ll= <br> still arguing that question even with this proposal taken into<br> consideration... :/<br> </blockquote> <br></div> It&#39;s an independent issue.<br> <br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> Perhaps I missed something?<div class=3D"im"><br> <br> Naturally all this complexity assumes we go with the tie-breaker<br> approach, which I&#39;m becoming more and more convinced is a bad plan...<b= r> </div></blockquote> <br> No, it doesn&#39;t. As I said, this is independent. Except that it does mea= n that some existing int-&gt;float conversions would be disallowed.<br> EG,<br> float foo(int x)<br> {<br> =C2=A0 =C2=A0return x;<br> }<br> wouldn&#39;t compile, because x might not fit into a float without loss of = accuracy.<br> </blockquote></div><br></div> --0016361e821035c53f04afff5ebe--
Oct 23 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
http://www.digitalmars.com/d/archives/digitalmars/D/PROPOSAL_Implicit_conversions_of_integer_literals_to_floating_point_125539.html#N125539
Oct 19 2011
prev sibling next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Thursday, October 20, 2011 05:13 Don wrote:
 Personally, I'd rather completely eliminate implicit conversions between
 integers and floating point types. But that's just me.

If it's a narrowing conversion, it should require a cast. If it's not, and there's no ambguity in the conversion, then I don't see any problem with allowing the conversion to be implicit. But then again, I deal with floating point values relatively rarely, so maybe there's something that I'm missing.
 My proposal was effectively: if it's ambiguous, choose double. That's all.

Are there _any_ cases in D right now where the compiler doesn't error out on ambiguity? In all of the cases that I can think of, D chooses to give an error on ambiguity rather than making a choice for you. I'm all for an int literal being implicitly converted to a double if the function call is unambiguous and there's no loss of precision. But if there's any ambiguity, then it's definitely against the D way to have the compiler pick for you. - Jonathan M Davis
Oct 20 2011
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Thursday, October 20, 2011 21:52:32 Manu wrote:
 On 20 October 2011 17:28, Simen Kjaeraas <simen.kjaras gmail.com> wrote:
 On Thu, 20 Oct 2011 15:54:48 +0200, Manu <turkeyman gmail.com> wrote:
  I could only support 2 if it chooses 'float', the highest performance
  
 version on all architectures AND actually available on all
 architectures; given this is meant to be a systems programming
 language, and supporting as
 many architectures as possible?

D specifically supports double (as a 64-bit float), regardless of the actual hardware. Also, the D way is to make the correct way simple, the fast way possible. This is clearly in favor of not using float, which *would* lead to precision loss.

Correct, on all architectures I'm aware of that don't have hardware double support, double is emulated, and that is EXTREMELY slow. I can't imagine any case where causing implicit (hidden) emulation of unsupported hardware should be considered 'correct', and therefore made easy.

Correctness has _nothing_ to do with efficiency. It has to do with the result that you get. Losing precision means that your code is less correct.
 The reason I'm so concerned about this, is not for what I may or may not do
 in my code, I'm likely to be careful, but imagine some cool library that I
 want to make use of... some programmer has gone and written 'x = sqrt(2)'
 in this library somewhere; they don't require double precision, but it was
 implicitly used regardless of their intent. Now I can't use that library in
 my project.
 Any library that wasn't written with the intent of use in embedded systems
 in mind, that happens to omit all of 2 characters from their float literal,
 can no longer be used in my project. This makes me sad.
 
 I'd also like you to ask yourself realistically, of all the integers you've
 EVER cast to/from a float, how many have ever been a big/huge number? And
 if/when that occurred, what did you do with it? Was the precision
 important? Was it important enough to you to explicitly state the cast?
 The moment you use it in a mathematical operation you are likely throwing
 away a bunch of precision anyway, especially for the complex functions like
 sqrt/log/etc in question.

When dealing with math functions like this, it doesn't really matter whether the number being passed in is a large one or not. It matters what you want for the return type. And the higher the precision, the more correct the result, so there are a lot of people who would want the result to be real, rather than float or double. It's when your concern is efficiency that you start worrying about whether a float would be better. And yes, efficiency matters, but if efficiency matters, then you can always tell it 2.0f instead of 2. Don's suggestion results in the code being more correct in the general case and yet still lets you easily make it more efficient if you want. That's very much the D way of doing things. Personally, I'm very leery of making an int literal implicitly convert to a double when there's ambiguity (e.g. if the function could also take a float), because then the compiler is resolving ambiguity for you rather than letting you do it. It risks function hijacking (at least in the sense that you don't necessarily end up calling the function that you mean to; it's not an issue for sqrt, but it could matter a lot for a function that has different behavior for float and double). And that sort of thing is very much _not_ the D way. So, I'm all for integers implicitly converting to double so long as there's no ambiguity. But in any case where there's ambiguity or a narrowing conversion, a cast should be required. - Jonathan M Davis
Oct 20 2011
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Thursday, October 20, 2011 21:44:05 Don wrote:
 On 20.10.2011 19:28, Jonathan M Davis wrote:
 On Thursday, October 20, 2011 05:13 Don wrote:
 Personally, I'd rather completely eliminate implicit conversions
 between
 integers and floating point types. But that's just me.

If it's a narrowing conversion, it should require a cast. If it's not, and there's no ambguity in the conversion, then I don't see any problem with allowing the conversion to be implicit. But then again, I deal with floating point values relatively rarely, so maybe there's something that I'm missing.>
 My proposal was effectively: if it's ambiguous, choose double. That's
 all.> 

out on ambiguity? In all of the cases that I can think of, D chooses to give an error on ambiguity rather than making a choice for you. I'm all for an int literal being implicitly converted to a double if the function call is unambiguous and there's no loss of precision.

The problem is, the existing approach will break a lot of existing code. For example, std.math.log(2) currently compiles. But, once the overload log(double) is added, which *must* happen, that code will break. Note that there is no realistic deprecation option, either. When the overload is added, code will break immediately. If we continue with this approach, we have to accept that EVERY TIME we add a floating point overload, existing code will break. So, we either make accept that; or we make everything that will ever break, break now (accepting that some stuff _will_ break, that would never have broken); or we introduce a tie-breaker rule. The question we face is really, which is the lesser evil? > But if there's any ambiguity, then it's > definitely against the D way to have the compiler pick for you. Explain why this compiles: void foo(ubyte x) {} void foo(short x) {} void foo(ushort x) {} void foo(int x) {} void foo(uint x) {} void foo(long x) {} void foo(ulong x) {} void main() { byte b = -1; foo(b); // How ambiguous can you get????? }

I wouldn't have expected that to compile. If we're already doing ambiguous implicit casts like this, then implicitly casting an int to a double isn't really going to make this much worse. On the bright side, it's almost certainly bad practice to have a function which takes a float and a double do something drastically different, so the ambiguity isn't likely to cause problems. But since D usually doesn't compile with ambiguities (particularly with classes), I'm surprised that it's as lax as it is with integral values. - Jonathan M Davis
Oct 20 2011
prev sibling next sibling parent Manu <turkeyman gmail.com> writes:
--0016364ed99e358a6404afc089d3
Content-Type: text/plain; charset=UTF-8

I think you just brushed over my entire concern with respect to libraries,
and very likely the standard library its self.
I've also made what I consider to be reasonable counter arguments to those
points in earlier posts, so I won't repeat myself.

I think it's fairly safe to say though, with respect to Don's question,
using a tie-breaker is extremely controversial. I can't see any way that
could be unanimously considered a good idea.
I stand by the call to ban implicit conversion between float/int. Some
might consider that a minor annoyance, but it also has so many potential
advantages and time savers down the line too.

On 20 October 2011 22:21, Jonathan M Davis <jmdavisProg gmx.com> wrote:

 On Thursday, October 20, 2011 21:52:32 Manu wrote:
 On 20 October 2011 17:28, Simen Kjaeraas <simen.kjaras gmail.com> wrote:
 On Thu, 20 Oct 2011 15:54:48 +0200, Manu <turkeyman gmail.com> wrote:
  I could only support 2 if it chooses 'float', the highest performance

 version on all architectures AND actually available on all
 architectures; given this is meant to be a systems programming
 language, and supporting as
 many architectures as possible?

D specifically supports double (as a 64-bit float), regardless of the actual hardware. Also, the D way is to make the correct way simple, the fast way possible. This is clearly in favor of not using float, which *would* lead to precision loss.

Correct, on all architectures I'm aware of that don't have hardware

 support, double is emulated, and that is EXTREMELY slow.
 I can't imagine any case where causing implicit (hidden) emulation of
 unsupported hardware should be considered 'correct', and therefore made
 easy.

Correctness has _nothing_ to do with efficiency. It has to do with the result that you get. Losing precision means that your code is less correct.
 The reason I'm so concerned about this, is not for what I may or may not

 in my code, I'm likely to be careful, but imagine some cool library that

 want to make use of... some programmer has gone and written 'x = sqrt(2)'
 in this library somewhere; they don't require double precision, but it

 implicitly used regardless of their intent. Now I can't use that library

 my project.
 Any library that wasn't written with the intent of use in embedded

 in mind, that happens to omit all of 2 characters from their float

 can no longer be used in my project. This makes me sad.

 I'd also like you to ask yourself realistically, of all the integers

 EVER cast to/from a float, how many have ever been a big/huge number? And
 if/when that occurred, what did you do with it? Was the precision
 important? Was it important enough to you to explicitly state the cast?
 The moment you use it in a mathematical operation you are likely throwing
 away a bunch of precision anyway, especially for the complex functions

 sqrt/log/etc in question.

When dealing with math functions like this, it doesn't really matter whether the number being passed in is a large one or not. It matters what you want for the return type. And the higher the precision, the more correct the result, so there are a lot of people who would want the result to be real, rather than float or double. It's when your concern is efficiency that you start worrying about whether a float would be better. And yes, efficiency matters, but if efficiency matters, then you can always tell it 2.0f instead of 2. Don's suggestion results in the code being more correct in the general case and yet still lets you easily make it more efficient if you want. That's very much the D way of doing things. Personally, I'm very leery of making an int literal implicitly convert to a double when there's ambiguity (e.g. if the function could also take a float), because then the compiler is resolving ambiguity for you rather than letting you do it. It risks function hijacking (at least in the sense that you don't necessarily end up calling the function that you mean to; it's not an issue for sqrt, but it could matter a lot for a function that has different behavior for float and double). And that sort of thing is very much _not_ the D way. So, I'm all for integers implicitly converting to double so long as there's no ambiguity. But in any case where there's ambiguity or a narrowing conversion, a cast should be required. - Jonathan M Davis

--0016364ed99e358a6404afc089d3 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable I think you just brushed over my entire concern with respect to libraries, = and very likely the standard library its self.<div>I&#39;ve also made what = I consider to be reasonable counter arguments to those points in earlier po= sts, so I won&#39;t repeat myself.</div> <div><br></div><div>I think it&#39;s fairly safe to say though, with respec= t to Don&#39;s question, using a tie-breaker is extremely controversial. I = can&#39;t see any way that could be unanimously considered a good idea.</di= v> <div>I stand by the call to ban implicit conversion between float/int. Some= might consider that a minor annoyance, but it also has so many potential a= dvantages and time savers down the line too.</div><div><br><div class=3D"gm= ail_quote"> On 20 October 2011 22:21, Jonathan M Davis <span dir=3D"ltr">&lt;<a href=3D= "mailto:jmdavisProg gmx.com">jmdavisProg gmx.com</a>&gt;</span> wrote:<br><= blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px= #ccc solid;padding-left:1ex;"> <div class=3D"im">On Thursday, October 20, 2011 21:52:32 Manu wrote:<br> &gt; On 20 October 2011 17:28, Simen Kjaeraas &lt;<a href=3D"mailto:simen.k= jaras gmail.com">simen.kjaras gmail.com</a>&gt; wrote:<br> &gt; &gt; On Thu, 20 Oct 2011 15:54:48 +0200, Manu &lt;<a href=3D"mailto:tu= rkeyman gmail.com">turkeyman gmail.com</a>&gt; wrote:<br> &gt; &gt; =C2=A0I could only support 2 if it chooses &#39;float&#39;, the h= ighest performance<br> &gt; &gt;<br> &gt; &gt;&gt; version on all architectures AND actually available on all<br=

g<br> &gt; &gt;&gt; language, and supporting as<br> &gt; &gt;&gt; many architectures as possible?<br> &gt; &gt;<br> &gt; &gt; D specifically supports double (as a 64-bit float), regardless of= the<br> &gt; &gt; actual hardware. Also, the D way is to make the correct way simpl= e, the<br> &gt; &gt; fast way possible. This is clearly in favor of not using float, w= hich<br> &gt; &gt; *would* lead to precision loss.<br> &gt;<br> &gt; Correct, on all architectures I&#39;m aware of that don&#39;t have har= dware double<br> &gt; support, double is emulated, and that is EXTREMELY slow.<br> &gt; I can&#39;t imagine any case where causing implicit (hidden) emulation= of<br> &gt; unsupported hardware should be considered &#39;correct&#39;, and there= fore made<br> &gt; easy.<br> <br> </div>Correctness has _nothing_ to do with efficiency. It has to do with th= e result<br> that you get. Losing precision means that your code is less correct.<br> <div class=3D"im"><br> &gt; The reason I&#39;m so concerned about this, is not for what I may or m= ay not do<br> &gt; in my code, I&#39;m likely to be careful, but imagine some cool librar= y that I<br> &gt; want to make use of... some programmer has gone and written &#39;x =3D= sqrt(2)&#39;<br> &gt; in this library somewhere; they don&#39;t require double precision, bu= t it was<br> &gt; implicitly used regardless of their intent. Now I can&#39;t use that l= ibrary in<br> &gt; my project.<br> &gt; Any library that wasn&#39;t written with the intent of use in embedded= systems<br> &gt; in mind, that happens to omit all of 2 characters from their float lit= eral,<br> &gt; can no longer be used in my project. This makes me sad.<br> &gt;<br> &gt; I&#39;d also like you to ask yourself realistically, of all the intege= rs you&#39;ve<br> &gt; EVER cast to/from a float, how many have ever been a big/huge number? = And<br> &gt; if/when that occurred, what did you do with it? Was the precision<br> &gt; important? Was it important enough to you to explicitly state the cast= ?<br> &gt; The moment you use it in a mathematical operation you are likely throw= ing<br> &gt; away a bunch of precision anyway, especially for the complex functions= like<br> &gt; sqrt/log/etc in question.<br> <br> </div>When dealing with math functions like this, it doesn&#39;t really mat= ter whether<br> the number being passed in is a large one or not. It matters what you want = for<br> the return type. And the higher the precision, the more correct the result,= so<br> there are a lot of people who would want the result to be real, rather than= <br> float or double. It&#39;s when your concern is efficiency that you start wo= rrying<br> about whether a float would be better. And yes, efficiency matters, but if<= br> efficiency matters, then you can always tell it 2.0f instead of 2. Don&#39;= s<br> suggestion results in the code being more correct in the general case and y= et<br> still lets you easily make it more efficient if you want. That&#39;s very m= uch the D<br> way of doing things.<br> <br> Personally, I&#39;m very leery of making an int literal implicitly convert = to a<br> double when there&#39;s ambiguity (e.g. if the function could also take a f= loat),<br> because then the compiler is resolving ambiguity for you rather than lettin= g<br> you do it. It risks function hijacking (at least in the sense that you don&= #39;t<br> necessarily end up calling the function that you mean to; it&#39;s not an i= ssue<br> for sqrt, but it could matter a lot for a function that has different behav= ior<br> for float and double). And that sort of thing is very much _not_ the D way.= <br> <br> So, I&#39;m all for integers implicitly converting to double so long as the= re&#39;s no<br> ambiguity. But in any case where there&#39;s ambiguity or a narrowing conve= rsion,<br> a cast should be required.<br> <font color=3D"#888888"><br> - Jonathan M Davis<br> </font></blockquote></div><br></div> --0016364ed99e358a6404afc089d3--
Oct 20 2011
prev sibling parent "Marco Leise" <Marco.Leise gmx.de> writes:
Am 20.10.2011, 22:09 Uhr, schrieb Manu <turkeyman gmail.com>:

 I think you just brushed over my entire concern with respect to  
 libraries,
 and very likely the standard library its self.
 I've also made what I consider to be reasonable counter arguments to  
 those
 points in earlier posts, so I won't repeat myself.

 I think it's fairly safe to say though, with respect to Don's question,
 using a tie-breaker is extremely controversial. I can't see any way that
 could be unanimously considered a good idea.
 I stand by the call to ban implicit conversion between float/int. Some
 might consider that a minor annoyance, but it also has so many potential
 advantages and time savers down the line too.

I start to understand the problems with implicit conversions and I think now that the size of the integer has no relation at all to size of the float in a conversion. For a large integer you may loose precision immediately when it is stored to a float instead of a double, but when you run sqrt() on it you introduce some more error anyway. So I'd vote for no implicit conversion unless the situation is unambiguous and the precision is sufficient, like in an assignment or calling a method with no overload. At least code would not break silently if overloads for sqrt would be provided later.
Oct 20 2011