January 04, 2021
On Monday, 4 January 2021 at 04:37:22 UTC, 9il wrote:
> I suppose the answer would be that D doesn't pretend to support all C++ template features and the bug is not a bug because we live with this somehow for years.

But it is a bug even if there was no C++... An alias should work by simple substitution, if it does not, then it is no alias...

> I didn't believe it when I got a similar answer about IEEE floating-point numbers: D doesn't pertinent to be IEEE 754 compatible language and the extended precision bug is declared to be a language feature. I suppose we shouldn't expect D to pretend to be a robust language for large business projects.

I think this is up to the compiler?

January 03, 2021
On 1/3/2021 8:37 PM, 9il wrote:
> I didn't believe it when I got a similar answer about IEEE floating-point numbers: D doesn't pertinent to be IEEE 754 compatible language and the extended precision bug is declared to be a language feature.

The "extended precision bug" is how all x87 code works, C to C++ to Java. The reason is simple - to remove the problem requires all intermediate results to be written to memory and read back in, which is a terrible performance problem. Early Java implementations did this write/read, and were forced to change it.

The advent of the XMM registers resolved this issue, and all the x86 D compilers now use XMM for 32 and 64 bit floating point math, when compiled for a CPU that has XMM registers. Extended precision only happens when the `real` 80 bit type is used, and that is IEEE conformant.

If you are aware of an FP bug in the XMM code generation, please file an issue on bugzilla, and I'll be happy to take care of it. The SIMD buglist is now down to one issue (32 byte stack alignment) which is something else.

The conversion to and from strings is a different problem.
January 04, 2021
On Monday, 4 January 2021 at 05:55:37 UTC, Ola Fosheim Grostad wrote:
> On Monday, 4 January 2021 at 04:37:22 UTC, 9il wrote:
>> I suppose the answer would be that D doesn't pretend to support all C++ template features and the bug is not a bug because we live with this somehow for years.
>
> But it is a bug even if there was no C++... An alias should work by simple substitution, if it does not, then it is no alias...

Here is an even simpler example that does not work:

struct Foo(T){}
void foo(T)(T!int x) {}

alias FooInt = Foo!int;

void main() {
    foo(FooInt());
}

January 04, 2021
On Monday, 4 January 2021 at 09:18:50 UTC, Ola Fosheim Grøstad wrote:
> On Monday, 4 January 2021 at 05:55:37 UTC, Ola Fosheim Grostad wrote:
>> On Monday, 4 January 2021 at 04:37:22 UTC, 9il wrote:
>>> I suppose the answer would be that D doesn't pretend to support all C++ template features and the bug is not a bug because we live with this somehow for years.
>>
>> But it is a bug even if there was no C++... An alias should work by simple substitution, if it does not, then it is no alias...
>
> Here is an even simpler example that does not work:
>
> struct Foo(T){}
> void foo(T)(T!int x) {}
>
> alias FooInt = Foo!int;
>
> void main() {
>     foo(FooInt());
> }

Oh, now wait, it does:

struct Foo(T){}
void foo(alias T)(T!int x) {}
alias FooInt = Foo!int;

void main() {
    foo(FooInt());
}

My mistake.






January 04, 2021
On Monday, 4 January 2021 at 05:58:09 UTC, Walter Bright wrote:
> On 1/3/2021 8:37 PM, 9il wrote:
>> I didn't believe it when I got a similar answer about IEEE floating-point numbers: D doesn't pertinent to be IEEE 754 compatible language and the extended precision bug is declared to be a language feature.
>
> The "extended precision bug" is how all x87 code works, C to C++ to Java. The reason is simple - to remove the problem requires all intermediate results to be written to memory and read back in, which is a terrible performance problem. Early Java implementations did this write/read, and were forced to change it.
>
> The advent of the XMM registers resolved this issue, and all the x86 D compilers now use XMM for 32 and 64 bit floating point math, when compiled for a CPU that has XMM registers. Extended precision only happens when the `real` 80 bit type is used, and that is IEEE conformant.


But you still have to deal with things like ARM, so maybe the better option is to figure out what the differences are between various hardware and define "floating point conformance levels" that library can test for, including what SIMD instructions are available. For instance, the accuracy of functions like log/exp/sin/cos/arcsin/… can vary between implementations. It would be useful for libraries to know.



January 04, 2021
On Monday, 4 January 2021 at 05:58:09 UTC, Walter Bright wrote:
> On 1/3/2021 8:37 PM, 9il wrote:
>> I didn't believe it when I got a similar answer about IEEE floating-point numbers: D doesn't pertinent to be IEEE 754 compatible language and the extended precision bug is declared to be a language feature.
>
> The "extended precision bug" is how all x87 code works, C to C++ to Java. The reason is simple - to remove the problem requires all intermediate results to be written to memory and read back in, which is a terrible performance problem. Early Java implementations did this write/read, and were forced to change it.

Since C99 the default x87 behavior is precise.
https://cpp.godbolt.org/z/7sa8dP

For older C versions GCC provides -fexcess-precision=standard flag.

Java is going to restore the original behavior.
https://bugs.openjdk.java.net/browse/JDK-8175916

C# has an option to control virtual machine behavior
https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/control87-controlfp-control87-2?view=msvc-160

Finally, x87 is a deprecated architecture. It likely will be supported for a few decades. From the business's point of view, no one expects the best performance from the code compiled for x87. Instead of speed, numeric correctness is much more important here. I wouldn't explain why extended precision is inaccurate, because Kahan and Darcy already wrote an 80-page essay about it:

"How Java’s Floating-Point Hurts Everyone Everywhere"
https://people.eecs.berkeley.edu/~wkahan/JAVAhurt.pdf


January 04, 2021
On Monday, 4 January 2021 at 09:21:02 UTC, Ola Fosheim Grøstad wrote:
> On Monday, 4 January 2021 at 09:18:50 UTC, Ola Fosheim Grøstad wrote:
>> On Monday, 4 January 2021 at 05:55:37 UTC, Ola Fosheim Grostad wrote:
>>> On Monday, 4 January 2021 at 04:37:22 UTC, 9il wrote:
>>>> I suppose the answer would be that D doesn't pretend to support all C++ template features and the bug is not a bug because we live with this somehow for years.
>>>
>>> But it is a bug even if there was no C++... An alias should work by simple substitution, if it does not, then it is no alias...
>>
>> Here is an even simpler example that does not work:
>>
>> struct Foo(T){}
>> void foo(T)(T!int x) {}
>>
>> alias FooInt = Foo!int;
>>
>> void main() {
>>     foo(FooInt());
>> }
>
> Oh, now wait, it does:
>
> struct Foo(T){}
> void foo(alias T)(T!int x) {}
> alias FooInt = Foo!int;
>
> void main() {
>     foo(FooInt());
> }
>
> My mistake.

What's the simplest example that doesn't work and is that simple example just indirection through an alias or is it actually indirection through a template that *when instantiated* turns out to be just an alias?

I have a suspicion that what you're asking for here is the type-inference to have x-ray vision in to uninstantiated templates that works for a few simple cases. Am I wrong?

To be clear, a really useful special case can be really useful and worthwhile, but I'm not convinced this is the principled "type system bug" you are saying it is.
January 04, 2021
On Monday, 4 January 2021 at 12:35:12 UTC, John Colvin wrote:
> On Monday, 4 January 2021 at 09:21:02 UTC, Ola Fosheim Grøstad wrote:
>> On Monday, 4 January 2021 at 09:18:50 UTC, Ola Fosheim Grøstad wrote:
>>> On Monday, 4 January 2021 at 05:55:37 UTC, Ola Fosheim Grostad wrote:
>>>> On Monday, 4 January 2021 at 04:37:22 UTC, 9il wrote:
>>>>> [...]
>>>>
>>>> But it is a bug even if there was no C++... An alias should work by simple substitution, if it does not, then it is no alias...
>>>
>>> Here is an even simpler example that does not work:
>>>
>>> struct Foo(T){}
>>> void foo(T)(T!int x) {}
>>>
>>> alias FooInt = Foo!int;
>>>
>>> void main() {
>>>     foo(FooInt());
>>> }
>>
>> Oh, now wait, it does:
>>
>> struct Foo(T){}
>> void foo(alias T)(T!int x) {}
>> alias FooInt = Foo!int;
>>
>> void main() {
>>     foo(FooInt());
>> }
>>
>> My mistake.
>
> What's the simplest example that doesn't work and is that simple example just indirection through an alias or is it actually indirection through a template that *when instantiated* turns out to be just an alias?
>
> I have a suspicion that what you're asking for here is the type-inference to have x-ray vision in to uninstantiated templates that works for a few simple cases. Am I wrong?
>
> To be clear, a really useful special case can be really useful and worthwhile, but I'm not convinced this is the principled "type system bug" you are saying it is.

I don't have time to post an example, but x-ray vision is far from what is asked for, just following basic rules established in type system theory decades ago.
In practice I've had many instances where TypeScript would correctly perform generic type unification while dmd gives up at the first bump in the road.
January 04, 2021
On Monday, 4 January 2021 at 12:35:12 UTC, John Colvin wrote:
> What's the simplest example that doesn't work and is that simple example just indirection through an alias or is it actually indirection through a template that *when instantiated* turns out to be just an alias?

Indirection through a parametric alias. This is the simplest I have come up with so far:


  struct Foo(T) {}

  alias Bar(T) = Foo!T;

  void f(T)(Bar!T x) {}

  void main() {
    f(Bar!int());
  }


I created a thread for it:

https://forum.dlang.org/post/nxrfrizqdmhzhivxptsb@forum.dlang.org


> I have a suspicion that what you're asking for here is the type-inference to have x-ray vision in to uninstantiated templates that works for a few simple cases. Am I wrong?

No, just substitute: "Bar!int" with "Foo!int".


> To be clear, a really useful special case can be really useful and worthwhile, but I'm not convinced this is the principled "type system bug" you are saying it is.

Why are you not convinced?

An alias is a short hand. If it is possible to discriminate by the alias and the actual object then that it a semantic problem.


January 04, 2021
On Monday, 4 January 2021 at 13:47:17 UTC, Ola Fosheim Grøstad wrote:
> An alias is a short hand. If it is possible to discriminate by the alias and the actual object then that it a semantic problem.

Typo: "discriminate between". An alias should be indistinguishable from the object, you are only naming something. You should be able to use whatever names you fancy without that having semantic implications, that's the core PL design principle.

(The stupid example that didn't work out was just me forgetting that I had played around with in higher kinded template parameters in run.dlang.io, I thought it was the code above... forgot. :-)