September 14, 2021

On Monday, 13 September 2021 at 22:27:11 UTC, Alexey wrote:

>

On Monday, 13 September 2021 at 21:03:41 UTC, Guillaume Piolat wrote:

>

On Sunday, 12 September 2021 at 14:14:03 UTC, Steven Schveighoffer wrote:

It's also not exactly clear why:

  1. D should be backward compatible with C, which is 50 years old soon.
  2. why exactly somebody should copy / paste (how many? thousands?) many lines of code without thinking and rechecking. Probably D can't be and shouldn't be compatible with C / C++ to that distinct.
  3. Is really backward comparability with C/C++ so important?
  1. It's fairly clear why. Because a lot of the D ecosystem depends on C such as libraries etc. a lot of C code is/will be ported to D and it's impossible to do so if there are unclear/major behavior differences. D promotes itself with "betterC" which means it needs to behave like C to be a better C.

  2. It's not necessarily copy-pasting but when you port code you don't go through it line-for-line and verify because that will take a very long time. There are even tools for D that allows porting C to D code and when using those tools you will not be able to verify the code that easy. Since a lot of the ecosystem depends on those tools then the behavior should be consistent with C.

  3. Yes, see the first point about the ecosystem heavily relying on C.

September 14, 2021

On Tuesday, 14 September 2021 at 06:03:24 UTC, bauss wrote:

>

On Monday, 13 September 2021 at 22:27:11 UTC, Alexey wrote:

>

On Monday, 13 September 2021 at 21:03:41 UTC, Guillaume Piolat wrote:

>

On Sunday, 12 September 2021 at 14:14:03 UTC, Steven Schveighoffer wrote:

It's also not exactly clear why:

>
  1. It's fairly clear why. Because a lot of the D ecosystem depends on C such as libraries etc.

The ability of D to parse C code, doesn't mean it necessarily should use same rules in it's own D code.

>

a lot of C code is/will be
ported to D

mythical possibility

>

and it's impossible to do so if there are unclear/major behavior differences.

how is it unclear? - because C coders doesn't want to learn D? - this is the reason D should be like C?

there's also many other languages, which can (to some distinct) understand C/C++ (like Go, Rust, Java, Python and so on). But they are not necessarily gain same promotion rules (and they shouldn't, because those are separate languages)

>

D promotes itself with "betterC" which means it needs to behave like C to be a better C.

to my understanding, betterC - is an option. if user selects this option, maybe then D should work like C. but many people also going to D because it isn't C/C++ - how about them, them who doesn't like C/C++?

>
  1. It's not necessarily copy-pasting but when you port code you don't go through it line-for-line and verify because that will take a very long time.

In any case, such port will require also types transition and many more things. In any case such a porter will should recheck code

>

There are even tools for D that allows porting C to D code

this just says what such tools could rewrite code to D's conformations

>

and when using those tools you will not be able to verify the code that easy.

why is this?

>

Since a lot of the ecosystem depends on those tools then the behavior should be consistent with C.

what you just said, is "D depends on C, because D should depend on C"

>
  1. Yes, see the first point about the ecosystem heavily relying on C.

all this doesn't answer why D should be like C. or is it like:

  • C++ is C with classes
  • D is C++ with GC
    , yes?

so if C++ will gain GC - D will become unneeded?

also, as somebody apparently mentioned earlier, such a radical change in behavior, will probably require a major version number change. - will D become the second Python with version 2 and 3 support for next 10 years and consequent BDFL expel?

I will conclude with following: I heard what D developers stated one day what D will accept C code; but I don't think this is necessary and I will not judge D developers for not achieving this. Not to say C already has it primary successors (Limbo and Go (which for some reason decided not to look like C)).

September 14, 2021

On Tuesday, 14 September 2021 at 07:01:02 UTC, Alexey wrote:

>

On Tuesday, 14 September 2021 at 06:03:24 UTC, bauss wrote:

>

a lot of C code is/will be
ported to D

mythical possibility

I did this just the other day, translating 500 lines of a C raylib implementation of Asteroids into D. Method: copy&paste and fix errors. The most annoying bit was the extensive use of C99 struct initializers, a lot of

player.collider = (Vector3){math, math, math};

into

player.collider = Vector3(math, math, math);

The "if it compiles it's valid" is a very helpful rule for C code.

https://github.com/raysan5/raylib-games/blob/master/classics/src/asteroids.c
https://gist.github.com/jrfondren/7459713e2a4ad8d62d297abd4b0949d8

>

all this doesn't answer why D should be like C

D being like D includes the idea that C code either compiles with the same meaning or it fails to compile. If not for that, why should D look C-like at all?

But putting C aside, is this even a behavior that you want?

ushort x = 53;
int y = -x;
assert(y == 65483);
>

. or is it like:

  • C++ is C with classes
  • D is C++ with GC
    , yes?

so if C++ will gain GC - D will become unneeded?

C++ needs to lose a lot, not just gain.

For a fresh example, C++ needs to lose easily incoherent and tedious operator overloading: https://forum.dlang.org/post/mailman.283.1631549561.21945.digitalmars-d-learn@puremagic.com

September 14, 2021

On Monday, 13 September 2021 at 22:27:11 UTC, Alexey wrote:

>

It's also not exactly clear why:

  1. D should be backward compatible with C, which is 50 years old soon.

A lot of the current D ecosystem (that wants to be simple to build) relies on translated C: bindings, and stuff like codecs are especially hard to translate error-free.
So it is valuable to be backward compatible with C, in the sense that a copy-paster C expression should work or not build.

Note that this isn't still the case, for example:

int fun(int[4] a)
{
    // stuff
}

void foo()
{
    int[4] b;
    fun(a); // passed by value in D, passed by pointer in C
}

ImportC will help a lot here, for example if like me you'd like a WebP decoder in pure D there are none, it is just too big to translate.

>
  1. why exactly somebody should copy / paste (how many? thousands?) many lines of code without thinking and rechecking. Probably D can't be and shouldn't be compatible with C / C++ to that distinct.

It's very labor intensive to translate C to D, and a little mistake can bury the effort.

>
  1. Is really backward comparability with C/C++ so important?

C and C++ are different languages, the one reason C++ has succeeded is "C/C++", being able to compile C code.

September 14, 2021

On Tuesday, 14 September 2021 at 07:29:39 UTC, jfondren wrote:

>

On Tuesday, 14 September 2021 at 07:01:02 UTC, Alexey wrote:

>

On Tuesday, 14 September 2021 at 06:03:24 UTC, bauss wrote:

>

a lot of C code is/will be
ported to D

mythical possibility

I did this just the other day, translating 500 lines of a C raylib implementation of Asteroids into D. Method: copy&paste and fix errors. The most annoying bit was the extensive use of C99 struct initializers, a lot of

Ok.

We have the situation, what in the code

#include <stdio.h>

int main(int argc, char* argv[])
{
    unsigned char a = 0b100;
    unsigned int b = ~a;
    return 0;
}

in line unsigned int b = ~a; a is promoted to int before it's bit's flipped.

we also know what compiler should not silently to data transformations: for this reason D issues errors and warnings if it isn't sure what to do. but C, in example above, silently promotes a to int. - is this a good behavior? - is this behavior which D should inherit?

C can do also many other bad things silently - so what, should D support such behavior too? maybe D should silently support pointer magic, so C coder could easily copy-paste he's code to D?

September 14, 2021

On Tuesday, 14 September 2021 at 08:42:20 UTC, Alexey wrote:

>

C can do also many other bad things silently - so what, should D support such behavior too? maybe D should silently support pointer magic, so C coder could easily copy-paste he's code to D?

Obviously not. That's why there are C constructs that do not compile in D.

From the inception of D, a general rule has been that if C code is copied into a D source module and it compiles, then it should behave like C. This isn't about being "backward compatible" with C. It's about minimizing bugs in ported code. For example, when you're using a C library and you copy an example into your D code, if it compiles and then behaves differently, you've potentially introduced a silent bug.

In the early days, D programs were highly dependent on C libraries because D libraries didn't exist. So this loose rule that Walter tried to follow made a lot of sense. Today, we have more D libraries, but we still frequently make use of C libraries. The rule still makes sense, IMO.

September 14, 2021

On Tuesday, 14 September 2021 at 08:42:20 UTC, Alexey wrote:

>
#include <stdio.h>

int main(int argc, char* argv[])
{
    unsigned char a = 0b100;
    unsigned int b = ~a;
    return 0;
}

and here

#include <stdio.h>

int main(int argc, char* argv[])
{
    unsigned char a = 0b100;
    unsigned char b = ~a;
    return 0;
}

will C also silently promote a to int and silently truncate it to uchar? - should those under-carpet things also happen in D just to save C's behavior?

September 14, 2021

On 9/13/21 6:27 PM, Alexey wrote:

>

On Monday, 13 September 2021 at 21:03:41 UTC, Guillaume Piolat wrote:

>

On Sunday, 12 September 2021 at 14:14:03 UTC, Steven Schveighoffer wrote:

It's also not exactly clear why:

  1. D should be backward compatible with C, which is 50 years old soon.
  2. why exactly somebody should copy / paste (how many? thousands?) many lines of code without thinking and rechecking. Probably D can't be and shouldn't be compatible with C / C++ to that distinct.
  3. Is really backward comparability with C/C++ so important?

This is missing the point.

Yes, part of the rationale of intpromote (which despite its flaws, I happen to agree with the main thrust of), is that we want D code that looks like C and compiles to behave like C. But also, the C behavior is what people who have no cares about C would expect.

In other words, if you have:

ushort x = 500;
int y = -x;

you would expect y to be -500. But in D it's 65036. Which makes almost no sense at all.

Another alternative would be to disable negation on unsigned types. That would be also extremely disruptive.

We have a chance here to

  1. Make D compatible with C
  2. Continue to compile code that is correct in C, and makes sense in D (i.e. short y = -someShort)
  3. Warn and fix surprising results that are 99% likely bugs.

If we do it smartly.

-Steve

September 14, 2021

On Tuesday, 14 September 2021 at 09:07:24 UTC, Alexey wrote:

>
#include <stdio.h>

int main(int argc, char* argv[])
{
    unsigned char a = 0b100;
    unsigned char b = ~a;
    return 0;
}

will C also silently promote a to int and silently truncate it to uchar? - should those under-carpet things also happen in D just to save C's behavior?

Yes it will.
you can convince yourself if you run this.

#include <stdio.h>
#include <stdbool.h>

char* binPrint(int v, char* buffer);

#define bits(v) (sizeof(v) * 8)
int main(int argc, char* argv[])
{
    char buffer[bits(int) + 1];

    unsigned char a = 0b100;
    printf("a: %d -- %s\n",  a, binPrint(a, &buffer[0]));

    unsigned char b = ~a;
    unsigned int  c = ~a;
    printf("uchar b: %u -- %s\n",  b, binPrint(b, &buffer[0]));
    printf("uint c: %u -- %s\n",  c, binPrint(c, &buffer[0]));
}

char* binPrint(int v, char* buffer)
{
    int last_set_bit;
    for(int bit_idx = 0; bit_idx < bits(v); bit_idx++)
    {
        bool bit_set = (v & (1 << bit_idx));
        buffer[bits(v) - bit_idx] = bit_set ? '1' : '0';
        if (bit_set) last_set_bit = bit_idx;
    }
    buffer[bits(v) + 1] = '\0';
    return &buffer[bits(v) - last_set_bit];
}
#undef bits
September 14, 2021
On Tuesday, 14 September 2021 at 11:53:48 UTC, Steven Schveighoffer wrote:
> In other words, if you have:
>
> ```d
> ushort x = 500;
> int y = -x;
> ```
>
> you would expect y to be -500. But in D it's 65036. Which makes almost no sense at all.


Not if you actually understand what a ushort and the - operator does. And if you don't understand that, maybe you should not use ushort.

I'd note the same thing happens if you do an assign from uint to long.

        uint a = 500;
        long b = -a;
        writeln(b); // 4294966796

No deprecation warning either.


But yeah if you were copy/pasting from C I can see how it would be an unpleasant surprise. .... but then again speaking of long, if you copy/paste code from C that uses `long` to D, you are in for an unpleasant surprise since the size is different. sooooo meh.

> Another alternative would be to disable negation on unsigned types. That would be also extremely disruptive.

The negation operator could also implicitly cast it to the signed version of the same size. Of course then you are liable to carry the one at the end but like at a certain point people need to understand what they're actually doing and just use plain int if they don't know.



but like if it would just stop complaining and making me double cast every operation i'd prolly be happy enough

the status quo is absurd