September 20, 2019
On Friday, 20 September 2019 at 07:48:25 UTC, Dukc wrote:
> But in fact, most of D stuff has "null" anyway: floats, chars, arrays, pointers, classes regardless of the definition. Only bools, integrals and enums (if you don't define one) do not, none of which are complex types. The philosophy AFAIK is that a type should always provide a null value, if it can be assigned normally "wrong" values without enlarging it.

Yeah and I don't much approve of all that either... how many unexpected crashes can be laid at the feet of objects being "segfault by default"? You're argument is basically "that's how it is, so that's how it should be." The proliferation of non-null invariants in our codebase begs to disagree.
September 20, 2019
On Friday, 20 September 2019 at 07:58:42 UTC, FeepingCreature wrote:
> You're argument is basically "that's how it is, so that's how it should be." The proliferation of non-null invariants in our codebase begs to disagree.

Didn't mean to say that -just that the struct design is consistent with rest of the language. I personally like the current philosophy fairly much, not a lot of experience from doing things the other way so I'm not very qualified to make strong comments. Walter however has reasoning:

https://digitalmars.com/articles/b81.html

You can agree or disagree.
September 20, 2019
On Friday, 20 September 2019 at 04:42:51 UTC, Max Samukha wrote:
> That is why almost every D struct with a destructor is compelled to implement those opCall/external constructor/lazy initialization hacks.

It may be because the empty state is valid for them.
September 20, 2019
On Friday, 20 September 2019 at 07:58:42 UTC, FeepingCreature wrote:
> Yeah and I don't much approve of all that either... how many unexpected crashes can be laid at the feet of objects being "segfault by default"? You're argument is basically "that's how it is, so that's how it should be." The proliferation of non-null invariants in our codebase begs to disagree.

When your code has a bug, a crash is the best outcome you can hope for.
September 20, 2019
On Friday, 20 September 2019 at 08:24:29 UTC, Kagamin wrote:
> When your code has a bug, a crash is the best outcome you can hope for.

Not so. The best outcome, and something D often strives for, is a helpful and informative compiler error.
September 20, 2019
On Friday, 20 September 2019 at 08:24:29 UTC, Kagamin wrote:
> On Friday, 20 September 2019 at 07:58:42 UTC, FeepingCreature wrote:
>> Yeah and I don't much approve of all that either... how many unexpected crashes can be laid at the feet of objects being "segfault by default"? You're argument is basically "that's how it is, so that's how it should be." The proliferation of non-null invariants in our codebase begs to disagree.
>
> When your code has a bug, a crash is the best outcome you can hope for.

And in the best case the language shouldn't encourage to introduce bugs.
September 21, 2019
On Friday, 20 September 2019 at 07:53:00 UTC, Andrea Fontana wrote:
> class MyClass {}
>
> struct Fixture
> {
>   int i;
>   immutable MyClass c;
> }
>
> auto fixture()
> {
>   Fixture ret =
>   {
>     i : 10,
>     c : new MyClass()
>   };
>
>   return ret;
> }
>
> void main()
> {
>   with(fixture())
>   {
>
>   }
> }
>
> Andrea

How is that different from the function-as-constructor examples by the other posters? Anyway, the status quo is very unlikely to ever change, so I am shutting up.
September 21, 2019
On Friday, 20 September 2019 at 08:20:05 UTC, Kagamin wrote:
> On Friday, 20 September 2019 at 04:42:51 UTC, Max Samukha wrote:
>> That is why almost every D struct with a destructor is compelled to implement those opCall/external constructor/lazy initialization hacks.
>
> It may be because the empty state is valid for them.

For some of them, it is.
September 23, 2019
On Friday, 20 September 2019 at 09:05:47 UTC, FeepingCreature wrote:
> On Friday, 20 September 2019 at 08:24:29 UTC, Kagamin wrote:
>> When your code has a bug, a crash is the best outcome you can hope for.
>
> Not so. The best outcome, and something D often strives for, is a helpful and informative compiler error.

Formal verification hopefully solves it, but it's usually developed as a separate tool and still requires a lot of work(?).
September 23, 2019
On Friday, 20 September 2019 at 07:48:25 UTC, Dukc wrote:
> I know this all has the downside that you cannot implement more complex "never null" types in a practical way. But in fact, most of D stuff has "null" anyway: floats, chars, arrays, pointers, classes regardless of the definition. Only bools, integrals and enums (if you don't define one) do not, none of which are complex types. The philosophy AFAIK is that a type should always provide a null value, if it can be assigned normally "wrong" values without enlarging it.

I just want to point out that this isn't an inherently unsolvable problem. You can have a type system where leaving your variable uninitialized is statically forbidden, while using sum types (Optional!T, Result!(T,E), etc) to handle functions taking or returning "wrong" values.

It doesn't even have to be as complex as Rust. Just disable default construction for types without a .init value, and encourage the user to use Optional!T for corner cases.