digitalmars.D - sqrt(2) must go
- Don <nospam nospam.com> Oct 19 2011
- =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= <xtzgzorex gmail.com> Oct 19 2011
- =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= <xtzgzorex gmail.com> Oct 19 2011
- "Marco Leise" <Marco.Leise gmx.de> Oct 19 2011
- Jesse Phillips <jessekphillips+D gmail.com> Oct 19 2011
- Andrej Mitrovic <andrej.mitrovich gmail.com> Oct 19 2011
- Andrej Mitrovic <andrej.mitrovich gmail.com> Oct 19 2011
- Andrej Mitrovic <andrej.mitrovich gmail.com> Oct 19 2011
- bearophile <bearophileHUGS lycos.com> Oct 19 2011
- dsimcha <dsimcha yahoo.com> Oct 19 2011
- "Marco Leise" <Marco.Leise gmx.de> Oct 19 2011
- dsimcha <dsimcha yahoo.com> Oct 19 2011
- Russel Winder <russel russel.org.uk> Oct 19 2011
- Alvaro <alvaro_segura gmail.com> Oct 19 2011
- bearophile <bearophileHUGS lycos.com> Oct 19 2011
- dsimcha <dsimcha yahoo.com> Oct 19 2011
- dsimcha <dsimcha yahoo.com> Oct 19 2011
- Timon Gehr <timon.gehr gmx.ch> Oct 20 2011
- dsimcha <dsimcha yahoo.com> Oct 19 2011
- Don <nospam nospam.com> Oct 20 2011
- Don <nospam nospam.com> Oct 20 2011
- Don <nospam nospam.com> Oct 20 2011
- dsimcha <dsimcha yahoo.com> Oct 20 2011
- Don <nospam nospam.com> Oct 20 2011
- Don <nospam nospam.com> Oct 20 2011
- Don <nospam nospam.com> Oct 23 2011
- "Eric Poggel (JoeCoder)" <dnewsgroup2 yage3d.net> Oct 20 2011
- dsimcha <dsimcha yahoo.com> Oct 20 2011
- Don <nospam nospam.com> Oct 20 2011
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= <xtzgzorex gmail.com> Oct 20 2011
- "Robert Jacques" <sandford jhu.edu> Oct 22 2011
- "Marco Leise" <Marco.Leise gmx.de> Oct 19 2011
- "Robert Jacques" <sandford jhu.edu> Oct 19 2011
- bearophile <bearophileHUGS lycos.com> Oct 19 2011
- Don <nospam nospam.com> Oct 19 2011
- "Steven Schveighoffer" <schveiguy yahoo.com> Oct 19 2011
- "Robert Jacques" <sandford jhu.edu> Oct 19 2011
- "Marco Leise" <Marco.Leise gmx.de> Oct 19 2011
- "Robert Jacques" <sandford jhu.edu> Oct 19 2011
- Don <nospam nospam.com> Oct 19 2011
- Russel Winder <russel russel.org.uk> Oct 19 2011
- Manu <turkeyman gmail.com> Oct 20 2011
- "Steven Schveighoffer" <schveiguy yahoo.com> Oct 20 2011
- "Martin Nowak" <dawg dawgfoto.de> Oct 20 2011
- Manu <turkeyman gmail.com> Oct 20 2011
- Manu <turkeyman gmail.com> Oct 20 2011
- Manu <turkeyman gmail.com> Oct 20 2011
- "Steven Schveighoffer" <schveiguy yahoo.com> Oct 20 2011
- Manu <turkeyman gmail.com> Oct 20 2011
- "Simen Kjaeraas" <simen.kjaras gmail.com> Oct 20 2011
- Manu <turkeyman gmail.com> Oct 20 2011
- "Marco Leise" <Marco.Leise gmx.de> Oct 20 2011
- "Marco Leise" <Marco.Leise gmx.de> Oct 20 2011
- "Robert Jacques" <sandford jhu.edu> Oct 20 2011
- Manu <turkeyman gmail.com> Oct 21 2011
- Manu <turkeyman gmail.com> Oct 21 2011
- "Robert Jacques" <sandford jhu.edu> Oct 21 2011
- Manu <turkeyman gmail.com> Oct 21 2011
- "Robert Jacques" <sandford jhu.edu> Oct 21 2011
- Manu <turkeyman gmail.com> Oct 22 2011
- Manu <turkeyman gmail.com> Oct 23 2011
- Andrej Mitrovic <andrej.mitrovich gmail.com> Oct 19 2011
- "Jonathan M Davis" <jmdavisProg gmx.com> Oct 20 2011
- Jonathan M Davis <jmdavisProg gmx.com> Oct 20 2011
- Jonathan M Davis <jmdavisProg gmx.com> Oct 20 2011
- Manu <turkeyman gmail.com> Oct 20 2011
- "Marco Leise" <Marco.Leise gmx.de> Oct 20 2011
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
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
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
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
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
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
http://codepad.org/4g0hXOse Too much?
Oct 19 2011
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
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
== Quote from Don (nospam nospam.com)'s articleIn 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
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
== Quote from Marco Leise (Marco.Leise gmx.de)'s articleAm 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
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
El 19/10/2011 20:12, dsimcha escribió:== Quote from Don (nospam nospam.com)'s articleThe 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
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
On 10/19/2011 6:25 PM, Alvaro wrote:El 19/10/2011 20:12, dsimcha escribió:== Quote from Don (nospam nospam.com)'s articleThe 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
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
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
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
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 articleThe 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
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
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
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
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
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, theThinking 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
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
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
== Quote from Eric Poggel (JoeCoder) (dnewsgroup2 yage3d.net)'s articleOn 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
On 10/20/2011 1:37 PM, dsimcha wrote:== Quote from Eric Poggel (JoeCoder) (dnewsgroup2 yage3d.net)'s articleOn 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
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
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
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
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 articleThe 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
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 articleThe 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
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
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
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 articleThe 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
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 articleThe 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
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 articleThe 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
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 articleThe 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
On 19.10.2011 20:12, dsimcha wrote:== Quote from Don (nospam nospam.com)'s articleIn 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
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
--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 articleThe 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's take 5_000_000_001, it'll lose a few bits,= but that'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->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'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"><<a hre= f=3D"mailto:schveiguy yahoo.com">schveiguy yahoo.com</a>></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 <<a href=3D"mailto:sandford jhu.edu" target=3D"_blank">sandfor= d jhu.edu</a>> 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 <<a href=3D"mailto:Marco= .Leise gmx.de" target=3D"_blank">Marco.Leise gmx.de</a>> 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 <<a href=3D"mailto:dsimcha yah= oo.com" target=3D"_blank">dsimcha yahoo.com</a>>:<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>)'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'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's bigges= t<br> strengths. =C2=A0Let'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'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'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
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 articleThe 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
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 articleThe 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
--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">= <<a href=3D"mailto:nospam nospam.com">nospam nospam.com</a>></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'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 s= ay it'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 'float' 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're discussing here is parameter passing of single val= ues; if it's part of an aggregate (array or struct), the issue doesn= 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
--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 shouldalways 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 youexpected 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 singlevalues; 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">= <<a href=3D"mailto:nospam nospam.com">nospam nospam.com</a>></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 <<a href=3D"mailto:nospam nospam.com" targ= et=3D"_blank">nospam nospam.com</a><br></div><div class=3D"im"> <mailto:<a href=3D"mailto:nospam nospam.com" target=3D"_blank">nospam no= spam.com</a>>> 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't true. Consider ARM, hard to say this isn't a vitally<br> important architecture these days, and there are plenty of embedded<br> architectures that don't support doubles at all, I would say it'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't exclude anything. What we're talking about as desirable = behaviour, is exactly what C does. If you care about performance on ARM, yo= u'll type sqrt(2.0f).<br> <br> Personally, I'd rather completely eliminate implicit conversions betwee= n integers and floating point types. But that'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't believe that you'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 'float' 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're discussing here is parameter passing= of single<br> =C2=A0 =C2=A0values; if it's part of an aggregate (array or struct), t= he issue<br> =C2=A0 =C2=A0doesn'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's no problem with assignment, it'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's ambiguous, choose double. That'= ;s all.<br> </blockquote></div><div><br></div><div>Yeah sorry, I think you'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: "Ambiguous call to ov=
out... end of discussion?</div> <div><br></div><div>But you speak of "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'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'm not clear now where you int= end to draw the lines.</div> </div></div><div>If you'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're doing.</div> <div><br></div><div>Or are we only drawing the distinction for literals?</d= iv><div>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.</= div> --0016364ee67a7469f304afba6059--
Oct 20 2011
--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 "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". NOT implicit convers= ion to arbitrary type 'double' :)</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=
<<a href=3D"mailto:dsimcha yahoo.com">dsimcha yahoo.com</a>></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's no problem with assignment, it'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's ambiguous, choose double. That'= ;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
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
--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">= <<a href=3D"mailto:nospam nospam.com">nospam nospam.com</a>></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 <<a href=3D"mailto:nospam nospam.com" targ= et=3D"_blank">nospam nospam.com</a><div class=3D"im"><br> <mailto:<a href=3D"mailto:nospam nospam.com" target=3D"_blank">nospam no= spam.com</a>>> 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 <<a href=3D"ma= ilto:nospam nospam.com" target=3D"_blank">nospam nospam.com</a><br> =C2=A0 =C2=A0 =C2=A0 =C2=A0<mailto:<a href=3D"mailto:nospam nospam.com"= target=3D"_blank">nospam nospam.com</a>><br></div><div><div></div><div = class=3D"h5"> =C2=A0 =C2=A0 =C2=A0 =C2=A0<mailto:<a href=3D"mailto:nospam nospam.com"= target=3D"_blank">nospam nospam.com</a> <mailto:<a href=3D"mailto:nospa= m nospam.com" target=3D"_blank">nospam nospam.com</a>>>> 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't true. Consider ARM, hard to say = this isn'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't support doubles at= all, I would say it'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't exclude anything. What we'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'll type sqrt(2.0f).<br> <br> =C2=A0 =C2=A0Personally, I'd rather completely eliminate implicit conv= ersions<br> =C2=A0 =C2=A0between integers and floating point types. But that'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't believe that you'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 'float' 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'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'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'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's no problem with assignment, it'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's ambiguous, choose do= uble.<br> =C2=A0 =C2=A0That's all.<br> <br> <br></div></div><div class=3D"im"> Yeah sorry, I think you'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: "Ambiguous call to overloaded<div cla= ss=3D"im"><br> function", and then there is no implicit cast rule to talk about... en= d<br> of discussion?<br> <br> But you speak of "eliminating implicit casting" 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'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'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'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'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'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'm not clear now where you intend to draw the lines.<br> If you'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're doing.<br> <br> Or are we only drawing the distinction for literals?<br> I don'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'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.<br> I don'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't really like #2, it's just arbitrary, and totally subje= ctive. You'll never have agreement, and perhaps more importantly, it= 9;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 (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't HATE #4, it'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 'float', 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'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'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
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
--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 performanceversion 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"><<a href=3D"mailto:simen.kjaras gmail.com">simen.kjaras gmail= .com</a>></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 <<a href=3D"m= ailto:turkeyman gmail.com" target=3D"_blank">turkeyman gmail.com</a>> 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 'float', 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'm aware of that don'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 'correct', and therefore made eas= y.</div> <div><br></div><div>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=C2= =A0imagine some cool library that I want to make use of... some programmer = has gone and written 'x =3D sqrt(2)' in this library somewhere; the= y don't require double precision, but it was implicitly used regardless= of their intent. Now I can't use that library in my project.</div> <div>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.</div> <div><br></div><div>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?</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
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
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
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
--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, theThinking 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">= <<a href=3D"mailto:nospam nospam.com">nospam nospam.com</a>></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 <<a href=3D"mailto:nospam nospam= .com" target=3D"_blank">nospam nospam.com</a>> 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'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'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'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'= t<br> use floats on a daily basis, which introduces bias into the discussion.<br> </blockquote> <br></div> Yeah, that's a valuable perspective.<br> sqrt(2) is "I don't care what the precision is".<br> What I get from you and Manu is:<br> if you'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'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: "Integer values cannot be implicitly converted to anoth= er type that cannot represent the integer bit pattern after integral promot= ion."<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; "Integer literals and expressions should use range propagation= to use</div> the thinnest loss-less conversion"... but can you clarify what you mea= n by 'expressions'? I assume we'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'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'm bec= oming more and more convinced is a bad plan...</div></div> --0016364ee67a4c5ce004afca5d73--
Oct 21 2011
--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, theThinking 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"=<<a href=3D"mailto:turkeyman gmail.com">turkeyman gmail.com</a>></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"><<a href=3D"mailto:nospam nospam.com" = target=3D"_blank">nospam nospam.com</a>></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 <<a href=3D"mailto:nospam nospam= .com" target=3D"_blank">nospam nospam.com</a>> 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'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'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'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'= t<br> use floats on a daily basis, which introduces bias into the discussion.<br> </blockquote> <br></div> Yeah, that's a valuable perspective.<br> sqrt(2) is "I don't care what the precision is".<br> What I get from you and Manu is:<br> if you'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'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: "Integer values cannot be implicitly converted to anoth= er type that cannot represent the integer bit pattern after integral promot= ion."<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; "Integer literals and expressions should use range= propagation to use</div> the thinnest loss-less conversion"... but can you clarify what you mea= n by 'expressions'? I assume we'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'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'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't actually perform identical functionality with jus= t different precision? .. I don'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'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
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
--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's what you mean right?</p> <p>On Oct 22, 2011 1:45 AM, "Robert Jacques" <<a href="mailto:sandford jhu.edu">sandford jhu.edu</a>> wrote:<br> ><br> > On Fri, 21 Oct 2011 09:00:48 -0400, Manu <<a href="mailto:turkeyman gmail.com">turkeyman gmail.com</a>> wrote:<br> >><br> >> On 21 October 2011 10:53, Manu <<a href="mailto:turkeyman gmail.com">turkeyman gmail.com</a>> wrote:<br> >>><br> >>> On 21 October 2011 09:00, Don <<a href="mailto:nospam nospam.com">nospam nospam.com</a>> wrote:<br> ><br> > [snip]<br> ><br> >>> 1: Seems reasonable for literals; "Integer literals and expressions should<br> >>> use range propagation to use<br> >>> the thinnest loss-less conversion"... but can you clarify what you mean by<br> >>> 'expressions'? I assume we're talking strictly literal expressions?<br> ><br> ><br> > Consider sqrt(i % 10). No matter what i is, the range of i % 10 is 0-9.<br> ><br> > I was more thinking of whether plain old assignment would be allowed:<br> ><br> > float f = myshort;<br> ><br> > Of course, if we deny implicit conversion, shouldn't the following fail to compile?<br> ><br> > float position = index * resolution;<br> ><br> ><br> >>> 2b: Does runtime bounds checking actually addresses the question; which of<br> >>> an ambiguous function to choose?<br> >>> If I read you correctly, 2b suggests bounds checking the implicit cast for<br> >>> data loss at runtime, but which to choose? float/double/real? We'll still<br> >>> arguing that question even with this proposal taken into consideration... :/<br> >>> Perhaps I missed something?<br> ><br> ><br> > Yes, nut only because I didn't include it. I was thinking of<br> ><br> > float f = i;<br> ><br> > as opposed to<br> ><br> > func(i)<br> ><br> > for some reason. Bounds checking would only make sense if func(float) was the only overload.<br> ><br> >>> Naturally all this complexity assumes we go with the tie-breaker approach,<br> >>> which I'm becoming more and more convinced is a bad plan...<br> >>><br> >><br> >> Then again, with regards to 1, the function chosen will depend on the<br> >> magnitude of the int, perhaps a foreign constant, you might not clearly be<br> >> able to know which one is called... What if the ambiguous overloads don't<br> >> actually perform identical functionality with just different precision? ..<br> ><br> ><br> > 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?<br> ><br> ><br> >> I don't like the idea of it being uncertain.<br> >><br> >> And one more thing to ponder, is the return type telling here?<br> >> float x = sqrt(2);<br> >> Obviously this may only work for these pure maths functions where the<br> >> return type is matched to the args, but maybe it's an element worth<br> >> considering.<br> >> ie, if the function parameter is ambiguous, check for disambiguation via<br> >> the return type...? Sounds pretty nasty! :)<br> </p> --0016368324ec4c589d04afd7195d--
Oct 21 2011
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
--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"><<a href=3D"mailto:sandford jhu.edu= ">sandford jhu.edu</a>></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 <<a href=3D"mailto:turkeyman gmail.com" target=3D"_blank= ">turkeyman gmail.com</a>> 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'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
--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; whichof 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'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'= 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">= <<a href=3D"mailto:nospam nospam.com">nospam nospam.com</a>></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 <<a href=3D"mailto:nospam nospam.com" targ= et=3D"_blank">nospam nospam.com</a><div class=3D"im"><br> <mailto:<a href=3D"mailto:nospam nospam.com" target=3D"_blank">nospam no= spam.com</a>>> 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 <<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<mailto:<a href=3D"mailto:nospam nospam.com"= target=3D"_blank">nospam nospam.com</a>>> 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'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'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'= 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'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's a valuable perspective.<br> =C2=A0 =C2=A0sqrt(2) is "I don't care what the precision is"= .<br> =C2=A0 =C2=A0What I get from you and Manu is:<br> =C2=A0 =C2=A0if you'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'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: "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."<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; "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"... but can you clarify what you mea= n<br> by 'expressions'? I assume we'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'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'll= <br> still arguing that question even with this proposal taken into<br> consideration... :/<br> </blockquote> <br></div> It'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'm becoming more and more convinced is a bad plan...<b= r> </div></blockquote> <br> No, it doesn't. As I said, this is independent. Except that it does mea= n that some existing int->float conversions would be disallowed.<br> EG,<br> float foo(int x)<br> {<br> =C2=A0 =C2=A0return x;<br> }<br> wouldn't compile, because x might not fit into a float without loss of = accuracy.<br> </blockquote></div><br></div> --0016361e821035c53f04afff5ebe--
Oct 23 2011
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
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 performanceversion 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
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
--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 performanceversion 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've also made what = I consider to be reasonable counter arguments to those points in earlier po= sts, so I won't repeat myself.</div> <div><br></div><div>I think it's fairly safe to say though, with respec= t 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.</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"><<a href=3D= "mailto:jmdavisProg gmx.com">jmdavisProg gmx.com</a>></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> > On 20 October 2011 17:28, Simen Kjaeraas <<a href=3D"mailto:simen.k= jaras gmail.com">simen.kjaras gmail.com</a>> wrote:<br> > > On Thu, 20 Oct 2011 15:54:48 +0200, Manu <<a href=3D"mailto:tu= rkeyman gmail.com">turkeyman gmail.com</a>> wrote:<br> > > =C2=A0I could only support 2 if it chooses 'float', the h= ighest performance<br> > ><br> > >> version on all architectures AND actually available on all<br=
g<br> > >> language, and supporting as<br> > >> many architectures as possible?<br> > ><br> > > 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 simpl= e, the<br> > > fast way possible. This is clearly in favor of not using float, w= hich<br> > > *would* lead to precision loss.<br> ><br> > Correct, on all architectures I'm aware of that don't have har= dware double<br> > support, double is emulated, and that is EXTREMELY slow.<br> > I can't imagine any case where causing implicit (hidden) emulation= of<br> > unsupported hardware should be considered 'correct', and there= fore made<br> > 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> > The reason I'm so concerned about this, is not for what I may or m= ay not do<br> > in my code, I'm likely to be careful, but imagine some cool librar= y that I<br> > want to make use of... some programmer has gone and written 'x =3D= sqrt(2)'<br> > in this library somewhere; they don't require double precision, bu= t it was<br> > implicitly used regardless of their intent. Now I can't use that l= ibrary in<br> > my project.<br> > Any library that wasn't written with the intent of use in embedded= systems<br> > in mind, that happens to omit all of 2 characters from their float lit= eral,<br> > can no longer be used in my project. This makes me sad.<br> ><br> > I'd also like you to ask yourself realistically, of all the intege= rs you've<br> > EVER cast to/from a float, how many have ever been a big/huge number? = And<br> > if/when that occurred, what did you do with it? Was the precision<br> > important? Was it important enough to you to explicitly state the cast= ?<br> > The moment you use it in a mathematical operation you are likely throw= ing<br> > away a bunch of precision anyway, especially for the complex functions= like<br> > sqrt/log/etc in question.<br> <br> </div>When dealing with math functions like this, it doesn'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'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'= 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's very m= uch the D<br> way of doing things.<br> <br> Personally, I'm very leery of making an int literal implicitly convert = to a<br> double when there'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'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'm all for integers implicitly converting to double so long as the= re's no<br> ambiguity. But in any case where there'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
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









=?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= <xtzgzorex gmail.com> 