www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - sumtypes for D

reply Walter Bright <newshound2 digitalmars.com> writes:
I've written most of a DIP for one. Should I:

1. submit the DIP

2. just implement it and do a PR

3. post the DIP here

4. wait for a champion to take it over and submit it
Nov 28 2022
next sibling parent reply Dukc <ajieskola gmail.com> writes:
On Monday, 28 November 2022 at 09:27:11 UTC, Walter Bright wrote:
 I've written most of a DIP for one. Should I:

 1. submit the DIP

 2. just implement it and do a PR

 3. post the DIP here

 4. wait for a champion to take it over and submit it
If you don't know, I'd go with 3. Or maybe post a link to the DIP draft you have published at Github so you can edit it. Then, depending on how it goes, you can follow on with 1. or 4.
Nov 28 2022
next sibling parent Dukc <ajieskola gmail.com> writes:
On Monday, 28 November 2022 at 09:39:37 UTC, Dukc wrote:
 If you don't know, I'd go with 3. Or maybe post a link to the 
 DIP draft you have published at Github so you can edit it. 
 Then, depending on how it goes, you can follow on with 1. or 4.
But let's wait for Mike's opinion first. I can't remember for sure whether there was a rule about language maintainer submitting a DIP.
Nov 28 2022
prev sibling parent Nick Treleaven <nick geany.org> writes:
On Monday, 28 November 2022 at 09:39:37 UTC, Dukc wrote:
 On Monday, 28 November 2022 at 09:27:11 UTC, Walter Bright 
 wrote:
 I've written most of a DIP for one. Should I:

 1. submit the DIP

 2. just implement it and do a PR

 3. post the DIP here

 4. wait for a champion to take it over and submit it
If you don't know, I'd go with 3. Or maybe post a link to the DIP draft you have published at Github so you can edit it.
If the DIP is complete I think it's usually best to submit the DIP with a pull request so reviewers can check there's no issues with clarity/definition. Then when it's in a state for initial review the forum can comment on the design. When people want input on design decisions before completing a DIP then it gets discussed here first.
Nov 28 2022
prev sibling next sibling parent Tejas <notrealemail gmail.com> writes:
On Monday, 28 November 2022 at 09:27:11 UTC, Walter Bright wrote:
 I've written most of a DIP for one. Should I:

 1. submit the DIP

 2. just implement it and do a PR

 3. post the DIP here

 4. wait for a champion to take it over and submit it
I think you should post it, unless you feel you haven't worked on it enough and would like some feedback for wording/examples to be presented before formally putting it through the DIP process, then you can just post here as DIP xyzw
Nov 28 2022
prev sibling next sibling parent Basile B. <b2.temp gmx.com> writes:
On Monday, 28 November 2022 at 09:27:11 UTC, Walter Bright wrote:
 I've written most of a DIP for one. Should I:

 1. submit the DIP

 2. just implement it and do a PR

 3. post the DIP here

 4. wait for a champion to take it over and submit it
1. DIP first. Then 3. announce the DIP
Nov 28 2022
prev sibling next sibling parent reply Mike Parker <aldacron gmail.com> writes:
On Monday, 28 November 2022 at 09:27:11 UTC, Walter Bright wrote:
 I've written most of a DIP for one. Should I:

 1. submit the DIP
This gets my vote. I think we should just drop the rule that you can't author your own DIPs. Its only impact has been that your DIPs have stalled. I'm planning to modify the DIP process in the new year. Dropping this rule is a change I was considering, so let's just go ahead and do it. And for the record, one change I've already decided on is that I'm eliminating the Final Review round. A DIP can still have multiple rounds of Community Review if it goes through significant revision, but once the CR is done, it will now go straight to Formal Assessment.
Nov 28 2022
parent Walter Bright <newshound2 digitalmars.com> writes:
On 11/28/2022 4:35 AM, Mike Parker wrote:
 This gets my vote. I think we should just drop the rule that you can't author 
 your own DIPs. Its only impact has been that your DIPs have stalled.
 
 I'm planning to modify the DIP process in the new year. Dropping this rule is
a 
 change I was considering, so let's just go ahead and do it.
 
 And for the record, one change I've already decided on is that I'm eliminating 
 the Final Review round. A DIP can still have multiple rounds of Community
Review 
 if it goes through significant revision, but once the CR is done, it will now
go 
 straight to Formal Assessment.
Sounds like a winner.
Nov 28 2022
prev sibling next sibling parent reply rikki cattermole <rikki cattermole.co.nz> writes:
I'm pretty eager to see this DIP.

After doing work on writing up value type exceptions, I have a number of 
suggestions on improving a more generalized form of sum types :)
Nov 28 2022
parent Walter Bright <newshound2 digitalmars.com> writes:
On 11/28/2022 4:43 AM, rikki cattermole wrote:
 After doing work on writing up value type exceptions, I have a number of 
 suggestions on improving a more generalized form of sum types :)
Looking forward to it!
Nov 28 2022
prev sibling next sibling parent ryuukk_ <ryuukk.dev gmail.com> writes:
On Monday, 28 November 2022 at 09:27:11 UTC, Walter Bright wrote:
 I've written most of a DIP for one. Should I:

 1. submit the DIP

 2. just implement it and do a PR

 3. post the DIP here

 4. wait for a champion to take it over and submit it
I would love to read the DIP, so i vote for 1., 3. works too, 2. works too but i think discussing about it before and reading what others think about it is important
Nov 28 2022
prev sibling next sibling parent reply novice2 <sorryno em.ail> writes:
 2. just implement it and do a PR
remember live, named parameters... 1,3 and 4 wil be endless debates and no results.
Nov 28 2022
parent reply IGotD- <nise nise.com> writes:
On Monday, 28 November 2022 at 15:48:23 UTC, novice2 wrote:
 2. just implement it and do a PR
remember live, named parameters... 1,3 and 4 wil be endless debates and no results.
Actually creating a preview as well can help as then programmers can try it out an observe how behaves in their own code. That can be valuable input for the DIP.
Nov 28 2022
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 11/28/2022 7:53 AM, IGotD- wrote:
 Actually creating a preview as well can help as then programmers can try it
out 
 an observe how behaves in their own code. That can be valuable input for the
DIP.
Implementing it will be a substantial amount of work (as opposed to the trivial ImportC), so I'm reluctant to do so without a pretty positive response.
Nov 28 2022
parent reply zjh <fqbqrr 163.com> writes:
On Monday, 28 November 2022 at 21:22:55 UTC, Walter Bright wrote:
 On 11/28/2022 7:53 AM, IGotD- wrote:
 Actually creating a preview as well can help as then 
 programmers can try it out an observe how behaves in their own 
 code. That can be valuable input for the DIP.
Implementing it will be a substantial amount of work (as opposed to the trivial ImportC), so I'm reluctant to do so without a pretty positive response.
Can a `dip` be similar to a `plug-in`? As long as the `dip` author implements the corresponding `interface`, there will be a command line `preview` for it automatically?
Nov 28 2022
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 11/28/2022 6:37 PM, zjh wrote:
 Can a `dip` be similar to a `plug-in`? As long as the `dip` author implements 
 the corresponding `interface`, there will be a command line `preview` for it 
 automatically?
I think you meant "fork" :-/
Nov 28 2022
parent reply zjh <fqbqrr 163.com> writes:
On Tuesday, 29 November 2022 at 07:29:21 UTC, Walter Bright wrote:
 On 11/28/2022 6:37 PM, zjh wrote:
 I think you meant "fork" :-/
I just wonder if it is possible to use `plug-ins` like `vim` to expand `D`. Although the `official` does not agree with this `behavior`, but because the code is released along with the official installation, as long as you turn on a `switch`, you will gain the ability,like `class level private`.
Nov 28 2022
parent reply zjh <fqbqrr 163.com> writes:
On Tuesday, 29 November 2022 at 07:44:14 UTC, zjh wrote:

 I just wonder if it is possible to use `plug-ins` like `vim` to 
 expand `D`.
Developing `D` like `vim` and `vim's plugin`.
Nov 28 2022
parent zjh <fqbqrr 163.com> writes:
On Tuesday, 29 November 2022 at 07:46:13 UTC, zjh wrote:

 Developing `D` like `vim` and `vim's plugin`.
Encourage the development of `dip`. If `dip` is good for everyone, then join in the `main branch`. If `like` and `dislike` account for half, let users customize with switches. In existing `sc.ini`, users can `configure` various such switches.
Nov 28 2022
prev sibling next sibling parent reply Per =?UTF-8?B?Tm9yZGzDtnc=?= <per.nordlow gmail.com> writes:
On Monday, 28 November 2022 at 09:27:11 UTC, Walter Bright wrote:
 I've written most of a DIP for one. Should I:

 1. submit the DIP

 2. just implement it and do a PR

 3. post the DIP here

 4. wait for a champion to take it over and submit it
Sum-types is the one feature I miss the most in D, so you have my blessing. I'm definitely gonna review the DIP. Btw, - do you plan on making the sum-type cover nullable-types as a special case? - and is this a preparation for pattern-matching?
Nov 28 2022
parent reply Per =?UTF-8?B?Tm9yZGzDtnc=?= <per.nordlow gmail.com> writes:
On Monday, 28 November 2022 at 21:44:01 UTC, Per Nordlöw wrote:
 Sum-types is the one feature I miss the most in D.
Or rather the builtin feature I missed the most having standardized with a template-free `match()` enabling fine-tuned diagnostics.
Nov 28 2022
parent max haughton <maxhaton gmail.com> writes:
On Monday, 28 November 2022 at 21:52:20 UTC, Per Nordlöw wrote:
 On Monday, 28 November 2022 at 21:44:01 UTC, Per Nordlöw wrote:
 Sum-types is the one feature I miss the most in D.
Or rather the builtin feature I missed the most having standardized with a template-free `match()` enabling fine-tuned diagnostics.
Yes. You can do match as a template, fairly well even, but when it goes even slightly wrong it goes kaboom. The current C++ proposal defines semantics for deferring to existing library code, even, so the semantics could still be preserved but under error messages we can be proud of.
Nov 28 2022
prev sibling next sibling parent reply deadalnix <deadalnix gmail.com> writes:
On Monday, 28 November 2022 at 09:27:11 UTC, Walter Bright wrote:
 I've written most of a DIP for one. Should I:
I'd like to point out that we still don't have a reasonable collection library because it is not possible to have a user type that has properties similar to a slice (as in T[]). Solving this would also ensure ensure that we can have sumtype as a library that are just as good as the builtin ones. The reason we cannot now is because we cannot build library types that mimic the builtin ones. I would have liked you as a leader here to get people to focus here instead of adding to the pile of complexity. There is a runaway pattern in this community to chase the next great thing, not because it is is bringing that much value, but because that's a good distraction from the fundamentals problems that exists.
Nov 28 2022
next sibling parent reply max haughton <maxhaton gmail.com> writes:
On Tuesday, 29 November 2022 at 00:02:45 UTC, deadalnix wrote:
 On Monday, 28 November 2022 at 09:27:11 UTC, Walter Bright 
 wrote:
 I've written most of a DIP for one. Should I:
I'd like to point out that we still don't have a reasonable collection library because it is not possible to have a user type that has properties similar to a slice (as in T[]). Solving this would also ensure ensure that we can have sumtype as a library that are just as good as the builtin ones. The reason we cannot now is because we cannot build library types that mimic the builtin ones. I would have liked you as a leader here to get people to focus here instead of adding to the pile of complexity. There is a runaway pattern in this community to chase the next great thing, not because it is is bringing that much value, but because that's a good distraction from the fundamentals problems that exists.
Built-in sumtypes will unify a lot of codebases if done right: Tuples and sumtypes are to writing beautiful programs what the container issues are to writing beautiful libraries IMO. Currently you can do a good-ish sumtype as a library, but the ergonomics are fairly meh, exhaustiveness is (impossible?) hard, and so on. The type itself isn't really that interesting, although having them available everywhere under the same design (i.e. covariance without introducing structural typing and so on) is valuable, it's really the operations that tend to come with them that bring the joy. A mental model for library versus language ADTs that I developed translating Haskell code into D: our current std.sumtyle requires roughly (for N uses of a sumtype's features e.g. constructors etc.) you are basically O(N) identifiers more tired than Haskell. It's close to greatness but no closer IMO. I will also happily bet a beer (conviently unfalsifiable) that sumtypes and other ML derived features are what get people to stay with languages like the Ferrous one after their initial pitch. They're not the next thing, they're now basically omnipresent in languages that are either new enough or bold enough to include them - people looking at languages solely from the angle of improving C++ have been completely blindsided by this IMO. It's a common retort to say "do it as a library" or even "no one really cares about it that much" and so on but they (including tuples) have quietly transformed much of the industry. I also don't think this is either or, we should work on the container side (both the community and us two plus anyone else interested) too.
Nov 28 2022
next sibling parent rikki cattermole <rikki cattermole.co.nz> writes:
For all we know Walter just threw together some stuff on a whim, hence 
why he hasn't posted what he has yet. I did something recently too, 
another attempt at trying to fix ModuleInfo exportation on Windows which 
hasn't gone great.

But yeah ML is the feature set of future successful languages. The more 
analysis you bake into a language the better its going to be long term 
and ML features allow you to do this very effectively.

Memory safety wrt. data structures is much higher on my list of needs 
than sum types.
Nov 28 2022
prev sibling next sibling parent Walter Bright <newshound2 digitalmars.com> writes:
I agree, it's clear that sumtypes are pretty much required in a modern language.
Nov 28 2022
prev sibling parent reply deadalnix <deadalnix gmail.com> writes:
On Tuesday, 29 November 2022 at 00:48:32 UTC, max haughton wrote:
 Built-in sumtypes will unify a lot of codebases if done right: 
 Tuples and sumtypes are to writing beautiful programs what the 
 container issues are to writing beautiful libraries IMO.
Unifying and yada yada are all very nice sounding words, but I'm afraid this is not very actionable. Here is the deal. We can agree that this is useful. Great. Now step back and look at the larger picture. The number of people who would use D if we changed nothing to the current thing but sum type is exactly 0. Maybe 1 if stars align properly. In the same way traction control is a great feature to have on you car, but none of this matter when the passenger door cannot close. And the passenger door is not closing right now. This forum is full of problem that actual people have trying to write actual D code. See https://forum.dlang.org/thread/nzlnwbcezwyopjfiasan forum.dlang.org for instance from just today. A grand total of none of these problems people are facing would be addressed by sum types. Not even one, kind of, if you are squinting hard enough while blind drunk. In fact, this is especially funny because I have spent the last several day implementing what effectively amount to a sum type in D. While having a syntax to express sum type would have been nice, I don't doubt that, nothing on that front is a blocker. What's a blocker is that some of types packed in the sum are collection and I can't get them to behave right, because the way I need them to behave like builtin slice, but I cannot. I'm literally building a sum type, and I'm telling, NO amount of integration of sum type into the language would change anything about the practical problem I'm facing working on this, it would just enable less boilerplate in part of the code that have no problems. Certainly, less boilerplate is good, but I'm trying to get shit done. Boilerplate is workable. Broken type system is not. You guys need an intervention. I'm serious.
Nov 28 2022
next sibling parent reply rikki cattermole <rikki cattermole.co.nz> writes:
On 29/11/2022 3:33 PM, deadalnix wrote:
 Certainly, less boilerplate is good, but I'm trying to get shit done. 
 Boilerplate is workable. Broken type system is not.
 
 You guys need an intervention. I'm serious.
Broken and incomplete implementations too. Seriously, 2-3 days an actual dmd compiler dev could probably get ModuleInfo exportation on Windows working correctly and we could get shared library support in D starting to actually be decent. Just that one fix would mean we could close FOUR issues extremely easily! And add a whole new realm of possibilities for D.
Nov 28 2022
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 11/28/2022 6:46 PM, rikki cattermole wrote:
 Seriously, 2-3 days an actual dmd compiler dev could probably get ModuleInfo 
 exportation on Windows working correctly and we could get shared library
support 
 in D starting to actually be decent.
 
 Just that one fix would mean we could close FOUR issues extremely easily! And 
 add a whole new realm of possibilities for D.
When posting things like this, links to the bugzilla entries are most appreciated.
Nov 28 2022
parent reply rikki cattermole <rikki cattermole.co.nz> writes:
On 29/11/2022 8:28 PM, Walter Bright wrote:
 On 11/28/2022 6:46 PM, rikki cattermole wrote:
 Seriously, 2-3 days an actual dmd compiler dev could probably get 
 ModuleInfo exportation on Windows working correctly and we could get 
 shared library support in D starting to actually be decent.

 Just that one fix would mean we could close FOUR issues extremely 
 easily! And add a whole new realm of possibilities for D.
When posting things like this, links to the bugzilla entries are most appreciated.
I take it you haven't been reading my posts about shared library support? They cover my journey on this pretty well, the content isn't really suited to ticket comments so you won't find the interesting stuff there as its mostly just symptoms. https://forum.dlang.org/post/tlqrlu$2lok$1 digitalmars.com
Nov 29 2022
next sibling parent Walter Bright <newshound2 digitalmars.com> writes:
https://issues.dlang.org/show_bug.cgi?id=6019
https://issues.dlang.org/show_bug.cgi?id=22367
https://issues.dlang.org/show_bug.cgi?id=9816
https://issues.dlang.org/show_bug.cgi?id=4071

:-)
Nov 29 2022
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 11/28/2022 6:46 PM, rikki cattermole wrote:
 Seriously, 2-3 days an actual dmd compiler dev could probably get ModuleInfo 
 exportation on Windows working correctly and we could get shared library 
 support in D starting to actually be decent.
I looked at https://issues.dlang.org/show_bug.cgi?id=22367 in your list, and the solution appears to be straightforward. I outlined it in the issue. Anyone want to have a go at it?
Nov 30 2022
parent reply rikki cattermole <rikki cattermole.co.nz> writes:
On 30/11/2022 9:30 PM, Walter Bright wrote:
 On 11/28/2022 6:46 PM, rikki cattermole wrote:
 Seriously, 2-3 days an actual dmd compiler dev could probably get 
 ModuleInfo exportation on Windows working correctly and we could get 
 shared library support in D starting to actually be decent.
I looked at https://issues.dlang.org/show_bug.cgi?id=22367 in your list, and the solution appears to be straightforward. I outlined it in the issue. Anyone want to have a go at it?
This isn't fixing it. Its playing whack-a-mole on symptoms and making it that much harder to verify that DllImport was fixed satisfactorily.
Nov 30 2022
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 11/30/2022 6:50 AM, rikki cattermole wrote:
 On 30/11/2022 9:30 PM, Walter Bright wrote:
 On 11/28/2022 6:46 PM, rikki cattermole wrote:
 Seriously, 2-3 days an actual dmd compiler dev could probably get ModuleInfo 
 exportation on Windows working correctly and we could get shared library 
 support in D starting to actually be decent.
I looked at https://issues.dlang.org/show_bug.cgi?id=22367 in your list, and the solution appears to be straightforward. I outlined it in the issue. Anyone want to have a go at it?
This isn't fixing it. Its playing whack-a-mole on symptoms and making it that much harder to verify that DllImport was fixed satisfactorily.
I don't know what you mean. It fixes the problem in 22367.
Nov 30 2022
parent reply rikki cattermole <rikki cattermole.co.nz> writes:
On 01/12/2022 9:38 AM, Walter Bright wrote:
 This isn't fixing it.

 Its playing whack-a-mole on symptoms and making it that much harder to 
 verify that DllImport was fixed satisfactorily.
I don't know what you mean. It fixes the problem in 22367.
The symptom is that dmd is turning on requirement for ModuleInfo when it shouldn't. The problem is that we can't turn on ModuleInfo generation via a switch. We can't turn on ModuleInfo generation because it is not exported. We can't export it due to DllImport being incomplete. If we can turn on ModuleInfo generation it too fixes this bug.
Nov 30 2022
parent Walter Bright <newshound2 digitalmars.com> writes:
Please repost your critique on 22367, so others interested in the ModuleInfo 
issue can see it, as this thread is about sumtypes.

I will respond there.

Thanks!
Nov 30 2022
prev sibling next sibling parent reply Adam D Ruppe <destructionator gmail.com> writes:
On Tuesday, 29 November 2022 at 02:33:21 UTC, deadalnix wrote:
 I'm literally building a sum type
Curious, what did you find lacking in std.sumtype? Same question to Walter. (btw I've never used it myself but this seems an obvious question that needs to be answered by anyone doing their own implementation, in or out of the language)
Nov 28 2022
next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 11/28/2022 6:53 PM, Adam D Ruppe wrote:
 Curious, what did you find lacking in std.sumtype?
 
 Same question to Walter.
It's addressed in the draft DIP I just posted. https://github.com/WalterBright/DIPs/blob/sumtypes/DIPs/1NNN-(wgb).md I did email std.sumtype's author, Paul Backus, for his observations but have not heard back yet.
Nov 28 2022
next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 11/29/22 08:26, Walter Bright wrote:
 On 11/28/2022 6:53 PM, Adam D Ruppe wrote:
 Curious, what did you find lacking in std.sumtype?

 Same question to Walter.
It's addressed in the draft DIP I just posted. https://github.com/WalterBright/DIPs/blob/sumtypes/DIPs/1NNN-(wgb).md I did email std.sumtype's author, Paul Backus, for his observations but have not heard back yet.
Nice! I think this general design, where it behaves just like a tagged union but safe, makes some sense for D. I _really_ wish bad element access resulted in a compile-time error instead of a runtime error though. Basically, you could treat if(?s.member){ } and assert(?s.member); specially, and only allow accesses to s.member if they are guarded by one of them. By default, accessing members is disallowed. The user can then choose between: if(?s.member){ writeln(s.member); } and assert(?s.member); writeln(s.member); To either check the tag manually or opt into the runtime error very explicitly. I think catching errors early during type checking is one of the most compelling things about sum types in other languages, and it would be great if D could get that in some way. The analysis does not have to be particularly sophisticated. In particular, no control flow analysis is required.
Nov 29 2022
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 11/29/22 15:01, Timon Gehr wrote:
 no control flow analysis is required.
Meant to write "data flow analysis" here.
Nov 29 2022
prev sibling next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 11/29/22 08:26, Walter Bright wrote:
 On 11/28/2022 6:53 PM, Adam D Ruppe wrote:
 Curious, what did you find lacking in std.sumtype?

 Same question to Walter.
It's addressed in the draft DIP I just posted. https://github.com/WalterBright/DIPs/blob/sumtypes/DIPs/1NNN-(wgb).md I did email std.sumtype's author, Paul Backus, for his observations but have not heard back yet.
Some things that are missing: - non-default construction, e.g.: sumtype Result{ error, int value; } auto result1 = Result.error; auto result2 = Result.value(2); The above is a bit unergonomic, maybe there is a better way to expose those constructors. They should exist though, otherwise it is e.g., impossible to initialize an immutable sumtype. - introspection, e.g. is(T==sumtype) and __traits(allMembers, ...) - in particular, it would be nice to provide access to the associated enumeration and the tag, e.g. for Result above, there could be an automatically generated enum like this: enum Result{ error, value, } Then you could do something like: final switch(tag(result)) { case Tag!Result.error: ... case Tag!Result.value: ... } This way, sumtype can be a drop-in replacement for existing unsafe tagged unions. I guess with __traits(allMembers, ...) this can be done in the library, but nothing beats direct access to the tag. - how does it interact with type qualifiers? In particular, I guess you can have a sumtype with only immutable members and reassign them anyway? - pattern matching (though that's acknowledged in the DIP and can probably be designed later)
Nov 29 2022
prev sibling next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 11/29/22 08:26, Walter Bright wrote:
 On 11/28/2022 6:53 PM, Adam D Ruppe wrote:
 Curious, what did you find lacking in std.sumtype?

 Same question to Walter.
It's addressed in the draft DIP I just posted. https://github.com/WalterBright/DIPs/blob/sumtypes/DIPs/1NNN-(wgb).md I did email std.sumtype's author, Paul Backus, for his observations but have not heard back yet.
BTW: I understand extraordinarily well where the desire for supporting an explicitly nullable pointer comes from, but I worry that integrating it into the more general syntax implicitly is a bit too cute. It will lead to bad interactions in generic code. E.g.: sumtype WithDefault(T){ Default; T; } A user does not expect this to behave specially if `T` is a pointer. Generic code would have to explicitly check for that case and manually undo the rewrite in the library. I don't want to read the resulting unwieldy Phobos code. Explicitly nullable pointers are too good of a feature to just give up though, so instead, you could introduce explicit syntax for the null check. E.g.: sumtype Nullable{ Null, int* Ptr; invariant(Ptr !is null); } The semantics of this would be to check the invariant on assignment and if it fails, then default-initialize the type instead. There could be multiple invariants that each can only refer to one of the members. Then this would be distinct from: sumtype DoublyNullable{ Null, int* Ptr; } It would also be more general because it allows enforcing more general invariants. (But it could also be limited to the special case with null, at least in the beginning; what's important is that the different behavior is documented explicitly in a difference in syntax.) Note that with the semantics where a bad member access is a runtime error, you don't gain much over just using a raw pointer. Therefore, I really think D should statically enforce that the user checks the tag.
Nov 29 2022
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 11/29/22 15:18, Timon Gehr wrote:
 
 sumtype WithDefault(T){
      Default;
      T;
 }
Should have been: sumtype WithDefault(T){ Default, T value, }
Nov 29 2022
prev sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 11/29/22 08:26, Walter Bright wrote:
 On 11/28/2022 6:53 PM, Adam D Ruppe wrote:
 Curious, what did you find lacking in std.sumtype?

 Same question to Walter.
It's addressed in the draft DIP I just posted. https://github.com/WalterBright/DIPs/blob/sumtypes/DIPs/1NNN-(wgb).md ...
Maybe consider changing the syntax to something like: sumtype ST{ a; int* b; } The reason is that with comma-separated values, metaprogramming is hobbled. I think we really want to be able to do things like: sumtype ST(bool hasC){ a; int* b; static if(hasC){ float c; } } Similar for `static foreach`. The fact that this does not work for `enum`s is among the most annoying limitations of `enum`s.
Nov 29 2022
parent reply rikki cattermole <rikki cattermole.co.nz> writes:
On 30/11/2022 3:24 AM, Timon Gehr wrote:
 Maybe consider changing the syntax to something like:
 
 sumtype ST{
      a;
      int* b;
 }
 
 The reason is that with comma-separated values, metaprogramming is hobbled.
 
 I think we really want to be able to do things like:
 
 sumtype ST(bool hasC){
      a;
      int* b;
      static if(hasC){
          float c;
      }
 }
 
 Similar for `static foreach`. The fact that this does not work for 
 `enum`s is among the most annoying limitations of `enum`s.
Could you please post this on the new thread where the draft is linked? It is a good feedback and in this thread it'll get lost.
Nov 29 2022
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 11/29/22 15:31, rikki cattermole wrote:
 On 30/11/2022 3:24 AM, Timon Gehr wrote:
 Maybe consider changing the syntax to something like:

 sumtype ST{
      a;
      int* b;
 }

 The reason is that with comma-separated values, metaprogramming is 
 hobbled.

 I think we really want to be able to do things like:

 sumtype ST(bool hasC){
      a;
      int* b;
      static if(hasC){
          float c;
      }
 }

 Similar for `static foreach`. The fact that this does not work for 
 `enum`s is among the most annoying limitations of `enum`s.
Could you please post this on the new thread where the draft is linked? It is a good feedback and in this thread it'll get lost.
Oops. Moved it all over. I guess the corresponding messages in this thread can be deleted.
Nov 29 2022
prev sibling next sibling parent deadalnix <deadalnix gmail.com> writes:
On Tuesday, 29 November 2022 at 02:53:27 UTC, Adam D Ruppe wrote:
 On Tuesday, 29 November 2022 at 02:33:21 UTC, deadalnix wrote:
 I'm literally building a sum type
Curious, what did you find lacking in std.sumtype? Same question to Walter. (btw I've never used it myself but this seems an obvious question that needs to be answered by anyone doing their own implementation, in or out of the language)
Good question. They didn't work in my case mainly for 2 reasons: - The above mentioned problem with qualifiers. `const SumType(A, B)` is somehow completely unrelated to `SumType(const A, const B)` which is not workable in practice. - I needed a set of implicit conversions between the elements when the sum type is used is certain ways, and as far a I can tell, there is no way to extend std.sumtype to achieve this kind of things.
Nov 29 2022
prev sibling parent Nick Treleaven <nick geany.org> writes:
On Tuesday, 29 November 2022 at 02:53:27 UTC, Adam D Ruppe wrote:
 On Tuesday, 29 November 2022 at 02:33:21 UTC, deadalnix wrote:
 I'm literally building a sum type
Curious, what did you find lacking in std.sumtype? Same question to Walter. (btw I've never used it myself but this seems an obvious question that needs to be answered by anyone doing their own implementation, in or out of the language)
I haven't used it yet. But you can't implicitly convert an element type instance into a sum type struct instance. E.g. passing an int to a sum type struct function parameter.
Nov 29 2022
prev sibling parent reply max haughton <maxhaton gmail.com> writes:
On Tuesday, 29 November 2022 at 02:33:21 UTC, deadalnix wrote:
 On Tuesday, 29 November 2022 at 00:48:32 UTC, max haughton 
 wrote:
 Built-in sumtypes will unify a lot of codebases if done right: 
 Tuples and sumtypes are to writing beautiful programs what the 
 container issues are to writing beautiful libraries IMO.
Unifying and yada yada are all very nice sounding words, but I'm afraid this is not very actionable. Here is the deal. We can agree that this is useful. Great. Now step back and look at the larger picture. The number of people who would use D if we changed nothing to the current thing but sum type is exactly 0. Maybe 1 if stars align properly.
I have met a few people who were specifically turned off of D because they wanted real algebraic data types and pattern matching - as in "that's cute, where's the real thing" when shown library sum types.
 In the same way traction control is a great feature to have on 
 you car, but none of this matter when the passenger door cannot 
 close. And the passenger door is not closing right now.

 This forum is full of problem that actual people have trying to 
 write actual D code. See 
 https://forum.dlang.org/thread/nzlnwbcezwyopjfiasan forum.dlang.org for
instance from just today.

 A grand total of none of these problems people are facing would 
 be addressed by sum types. Not even one, kind of, if you are 
 squinting hard enough while blind drunk.
Well one is template bloat. I happily (well, readily) concede this is relatively minor compared to the type system as a whole but instantiating any operation *on* a sumtype is not cheap. One of the primary complaints is the build and link time which usually means some kind of explosive template code. Especially when you consider a lot of this code is actually thrown away i.e. used to check if such and such a thing is true. I will also note that "actual" people both informally and in a few surveys we've done over the years do consistently ask for this. We don't have to be democracy but an appeal to actual developer's work should be aware of that.
 In fact, this is especially funny because I have spent the last 
 several day implementing what effectively amount to a sum type 
 in D. While having a syntax to express sum type would have been 
 nice, I don't doubt that, nothing on that front is a blocker. 
 What's a blocker is that some of types packed in the sum are 
 collection and I can't get them to behave right, because the 
 way I need them to behave like builtin slice, but I cannot.
In what way specifically? const-ness? I also note that *many* *many* codebases have something that amounts to a sum type one way or another. As a result of that we have many incompatible sumtype implementations. They're also completely opaque to tooling.
 I'm literally building a sum type, and I'm telling, NO amount 
 of integration of sum type into the language would change 
 anything about the practical problem I'm facing working on 
 this, it would just enable less boilerplate in part of the code 
 that have no problems.
Without knowing the problem in more detail I have nothing. Even if the solution was hacky it's better to have magic contained in something the compiler controls then a foreign library IMO.
 Certainly, less boilerplate is good, but I'm trying to get shit 
 done. Boilerplate is workable. Broken type system is not.
Lack of boilerplate comes as a result of integration into the language, alongside correctness, it's not a goal in and of itself beyond informing a design. Boilerplate in this case does, however, fundamentally change the code I reach for. You can criticize this as being one step away from code golf but currently some hierarchies in D code go from being a careful idea in ones head (I hesitate to say abstraction because true abstraction is not necessarily achieved) to a bunch of unnecessary spew. It isn't so much boilerplate with library sumtypes being the issue as much that they're just annoying enough that they aren't the obvious choice.
Nov 28 2022
parent reply deadalnix <deadalnix gmail.com> writes:
On Tuesday, 29 November 2022 at 03:42:26 UTC, max haughton wrote:
 I have met a few people who were specifically turned off of D 
 because they wanted real algebraic data types and pattern 
 matching - as in "that's cute, where's the real thing" when 
 shown  library sum types.
It seems like the high impact item here is matching more than the library type. Herb Sutter as excellent work on how to do this in C++, most of it is applicable to D.
 Well one is template bloat. I happily (well, readily) concede 
 this is relatively minor compared to the type system as a whole 
 but instantiating any operation *on* a sumtype is not cheap. 
 One of the primary complaints is the build and link time which 
 usually means some kind of explosive template code.
You are missing the forest for the trees, a bit. Yes, template bloat is an issue, but there is a meta issue in this thread: lack of tools. Many issue can be "solved" not by solving anything, but by making them easily visible, discoverable, etc... Concrete exemple: do you know that the initial version of programs written in C++ are typically slower than their counter parts in Java? Large companies such as Google have a ton of data on this. So why is Google still writing high performance code in C++? because in C++, the have the tool to optimize further, and, as a result, while the initial version will be slower (on the balance of probabilities), the C++ one can be optimized more and more over time in ways that the Java one cannot. But here is where this become relevant to this specific issue: every time we change the language, we break tools. And we change the language all the time, with no easily predictable schedule, and often for value add that are at best marginal. To reuse Hazlitt's lingo, this is the unseen here. The cost we are paying but we are not seeing is the complete lack of a tooling ecosystem, because we keep destroying it before it can grow to a size where it provides value.
 I will also note that "actual" people both informally and in a 
 few surveys we've done over the years do consistently ask for 
 this. We don't have to be democracy but an appeal to actual 
 developer's work should be aware of that.
Well take it from someone who has experience building product, some of them are used by hundreds of million of people: this *NOT* how you want to look at it at all. Classic trap. There are a few reasons: - As the product builder, you are the expert. You have read all the latest research, you know of all the tradeoffs, you have played with numerous alternatives, etc... At least you should. Your users did not. If you base yourself on your users, you will build something inferior, and if your user know better than you do, then you have a big problem, because you are not expert enough, and *MUST* tackle this. Failure to do so means that you will build, at best, an average product, but likely worse than average because it'll lack a unified vision. - Even ignoring your first point, the sample is horribly biased. Indeed, the people you have in there, are mostly people who are not bothered by the worse features of your product. This is why the people who build great product are typically relentless in their criticism of what they've built. They know that, to get to the next level, they need to fix problem that very few in their user base complain about, and if they don't take on that role, nobody will. The people who see the flaws are, for the most part, not in your sample.
 I also note that *many* *many* codebases have something that 
 amounts to a sum type one way or another. As a result of that 
 we have many incompatible sumtype implementations. They're also 
 completely opaque to tooling.
Very true. This can mean a few things. Maybe that sum types in the languages are needed, but also maybe that there are more fundamental problems that compel people to roll their own. There used to be a ton of string types in C++ circa 15 years ago. Literally every project came with its own string type. The solution wasn't to make string a part of the language, but rather to ensure there were the tools available to make the one from the standard lib really good, to such a degree that people felt compelled to get rid of their own versions. You will note that this is not always the right path, but this is the first path that you want to consider, because the compounding effect are much, much much greater. If you fix the language such as the library solution is world class, then you also fix the same problem for a ton of other unrelated libraries solutions for unrelated problems. And then, maybe, you reach a point where you actually need to bake things into the language. But for as long as you have not reached the above stage, you simply don't know.
 Without knowing the problem in more detail I have nothing. Even 
 if the solution was hacky it's better to have magic contained 
 in something the compiler controls then a foreign library IMO.
Yes, and what I'm telling you is that the problems who'd deserve to be solved here are not specific to sum types, at least, not the worse offenders. Therefore, baking a special case solution for sum type would: 1/ Not solve the core issue to begin with. 2/ Make the core issue harder to solve, because it now has to be compatible with whatever is done for sum types. 3/ Increase language complexity, which means more bugs and other problem in practice. 4/ Tooling problems.
Nov 29 2022
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 11/29/22 14:30, deadalnix wrote:
 
 Yes, and what I'm telling you is that the problems who'd deserve to be 
 solved here are not specific to sum types, at least, not the worse 
 offenders.
I am also in favor of making solutions that are needed for sum types available to user-defined types to a good extent. But I do think some new solutions are needed, also on the front of the grammar.
 Therefore, baking a special case solution for sum type would:
 1/ Not solve the core issue to begin with.
Together with tuples, it solves the issue that there are no algebraic data types. I think this is significant and no pure library solution can match the ergonomics of a well-designed built-in solution.
 2/ Make the core issue harder to solve, because it now has to be 
 compatible with whatever is done for sum types.
Ideally that's not a constraint because it will be done right for sum types first and can then inform a more general solution.
 3/ Increase language complexity, which means more bugs and other problem 
 in practice.
 4/ Tooling problems.
Fair points.
Nov 29 2022
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 11/28/2022 4:02 PM, deadalnix wrote:
 I'd like to point out that we still don't have a reasonable collection library 
 because it is not possible to have a user type that has properties similar to
a 
 slice (as in T[]).
 
 Solving this would also ensure ensure that we can have sumtype as a library
that 
 are just as good as the builtin ones. The reason we cannot now is because we 
 cannot build library types that mimic the builtin ones.
 
 I would have liked you as a leader here to get people to focus here instead of 
 adding to the pile of complexity.
 
 There is a runaway pattern in this community to chase the next great thing,
not 
 because it is is bringing that much value, but because that's a good
distraction 
 from the fundamentals problems that exists.
It would be nice if you enumerated those fundamental problems. I don't know what they are.
Nov 28 2022
parent reply deadalnix <deadalnix gmail.com> writes:
On Tuesday, 29 November 2022 at 01:27:32 UTC, Walter Bright wrote:
 It would be nice if you enumerated those fundamental problems. 
 I don't know what they are.
I have done so numerous times. Every single god damn time you answer the same thing. IT IS NOT POSSIBLE TO WRITE A COLLECTION IN D THAT BEHAVE PROPERLY AS PER THE TYPE SYSTEM'S RULES. Is that big enough? vector? Set? Map? Does any of it ring a bell? Even range code completely shits the best as long as you throw a const in there. Type qualifier do not turtle down (Vector!int and Vector!const(int) are completely unrelated constructs), the top level qualifier need to be able to pop when things are passe by value, etc... You know what these behavior are, there are the one of builtin slices. This is not random, this is the behavior that is needed for containers, range, and, for that matter, sum types. Adding more stuff on top of broken foundations achieve only one goal: an increase complexity. Because none of these things are the actual bottleneck for anyone. Would I want tuples, sum types and whatnot, assuming the core language was not full of bear traps? Yes. Absolutely. Let's talk about it when the bear trap situation is under control. Because none of this is useful.
Nov 28 2022
next sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 11/28/22 9:42 PM, deadalnix wrote:
 On Tuesday, 29 November 2022 at 01:27:32 UTC, Walter Bright wrote:
 It would be nice if you enumerated those fundamental problems. I don't 
 know what they are.
I have done so numerous times. Every single god damn time you answer the same thing. IT IS NOT POSSIBLE TO WRITE A COLLECTION IN D THAT BEHAVE PROPERLY AS PER THE TYPE SYSTEM'S RULES.
This is pretty harsh for the single problem you bring up, which I agree would be nice to fix, but absolutely is not a fundamental problem for having containers in D. Yes, if you have the same problem over and over again, it's frustrating to have it continually ignored or dismissed. But it's also not possible to always search this forums for all the times it was brought up. Half the time, I don't remember conversations that *I have had* on these forums, and sometimes I sheepishly discover that I had the opposite opinion some years ago. So please let's discuss this problem in a productive way. The problem is that there's no syntax to "tail-modify" a type other than a pointer or an array. This is the biggest problem with properly using const on ranges (it doesn't prevent using const containers, or prevent ranges to const data, it just prevents taking a range to a *mutable container* and iterating it via a const parameter). I think I've been bringing this problem up for 10 years. It would be a huge win to get it solved. -Steve
Nov 28 2022
parent reply Paul Backus <snarwin gmail.com> writes:
On Tuesday, 29 November 2022 at 03:03:37 UTC, Steven 
Schveighoffer wrote:
 The problem is that there's no syntax to "tail-modify" a type 
 other than a pointer or an array. This is the biggest problem 
 with properly using const on ranges (it doesn't prevent using 
 const containers, or prevent ranges to const data, it just 
 prevents taking a range to a *mutable container* and iterating 
 it via a const parameter).

 I think I've been bringing this problem up for 10 years. It 
 would be a huge win to get it solved.
The thing is, we pretty much know what the solution is. In the general case, solving this requires user-defined implicit conversions, because in the general case only the user has the knowledge necessary to establish the correspondence between a templated type's *structure* (e.g., "the head-mutable version of `const(Foo!T)`") and its *name* (e.g., `Foo!(const(T))`). The problem is, that solution has been declared categorically off the table, so we are stuck going in circles debating the merits and shortcoming of various half-measures.
Nov 28 2022
next sibling parent reply zjh <fqbqrr 163.com> writes:
On Tuesday, 29 November 2022 at 03:37:39 UTC, Paul Backus wrote:
 because in the general case only the user has the knowledge 
 necessary to establish the correspondence between a templated 
 type's *structure* (e.g., "the head-mutable version of 
 `const(Foo!T)`") and its *name* (e.g., `Foo!(const(T))`).

 The problem is, that solution has been declared categorically 
 off the table, so we are stuck going in circles debating the 
 merits and shortcoming of various half-measures.
There are solutions, why not to apply it? D should not become a `religion`.
Nov 28 2022
parent reply Paul Backus <snarwin gmail.com> writes:
On Tuesday, 29 November 2022 at 04:05:46 UTC, zjh wrote:
 On Tuesday, 29 November 2022 at 03:37:39 UTC, Paul Backus wrote:
 because in the general case only the user has the knowledge 
 necessary to establish the correspondence between a templated 
 type's *structure* (e.g., "the head-mutable version of 
 `const(Foo!T)`") and its *name* (e.g., `Foo!(const(T))`).

 The problem is, that solution has been declared categorically 
 off the table, so we are stuck going in circles debating the 
 merits and shortcoming of various half-measures.
There are solutions, why not to apply it? D should not become a `religion`.
Walter Bright is strongly opposed to adding user-defined implicit conversions to D. You can search the forum for his posts on the subject; here is one example: https://forum.dlang.org/post/rs9k19$1982$1 digitalmars.com
Nov 28 2022
parent zjh <fqbqrr 163.com> writes:
On Tuesday, 29 November 2022 at 04:12:14 UTC, Paul Backus wrote:

 Walter Bright is strongly opposed to adding user-defined 
 implicit conversions to D. You can search the forum for his 
 posts on the subject; here is one example:

 https://forum.dlang.org/post/rs9k19$1982$1 digitalmars.com
In C++, I have never used implicit conversion. I just add an `explicit`. This seems to be a problem of "const" limitation. I think that, like `user defined implicit conversion`, you can add an attribute to machine check. In this way, users are only allowed to add an "implicit conversion" of a "specific" attribute, which may be a real implicit conversion, indicating that the user knows what he is doing.
Nov 28 2022
prev sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 11/28/22 10:37 PM, Paul Backus wrote:
 On Tuesday, 29 November 2022 at 03:03:37 UTC, Steven Schveighoffer wrote:
 The problem is that there's no syntax to "tail-modify" a type other 
 than a pointer or an array. This is the biggest problem with properly 
 using const on ranges (it doesn't prevent using const containers, or 
 prevent ranges to const data, it just prevents taking a range to a 
 *mutable container* and iterating it via a const parameter).

 I think I've been bringing this problem up for 10 years. It would be a 
 huge win to get it solved.
The thing is, we pretty much know what the solution is. In the general case, solving this requires user-defined implicit conversions, because in the general case only the user has the knowledge necessary to establish the correspondence between a templated type's *structure* (e.g., "the head-mutable version of `const(Foo!T)`") and its *name* (e.g., `Foo!(const(T))`).
This is not how I would solve it. I would solve it in the general case, with a new syntax. -Steve
Nov 28 2022
prev sibling next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 11/28/2022 6:42 PM, deadalnix wrote:
 On Tuesday, 29 November 2022 at 01:27:32 UTC, Walter Bright wrote:
 It would be nice if you enumerated those fundamental problems. I don't know 
 what they are.
I have done so numerous times. Every single god damn time you answer the same thing.
I don't doubt you. The trouble is, the n.g. is ephemeral. Once it scrolls away, it's forgotten. A more permanent document is needed, one you can just link to instead of repeating yourself, which I agree must be annoying for you. For example, I've proposed an improvement to C for years, and wrote an article about it which I just link to rather than having to explain it again endlessly. https://www.digitalmars.com/articles/C-biggest-mistake.html Adding Enhancement Requests to bugzilla also can serve this purpose.
 IT IS NOT POSSIBLE TO WRITE A COLLECTION IN D THAT BEHAVE PROPERLY AS PER THE 
 TYPE SYSTEM'S RULES.
 
 Is that big enough? vector? Set? Map? Does any of it ring a bell? Even range 
 code completely shits the best as long as you throw a const in there.
 
 Type qualifier do not turtle down (Vector!int and Vector!const(int) are 
 completely unrelated constructs), the top level qualifier need to be able to
pop 
 when things are passe by value, etc...
Top level qualifiers can be removed with: cast()expression
Nov 28 2022
parent deadalnix <deadalnix gmail.com> writes:
On Tuesday, 29 November 2022 at 06:45:37 UTC, Walter Bright wrote:
 Top level qualifiers can be removed with:

     cast()expression
No, this will remove all qualifiers on user defined types. Which is one more reason one cannot provide a user defined type that behave like the builtin ones, and this is something you want to be able to do, for collections, ranges, as well as for sum types.
Nov 29 2022
prev sibling next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 11/28/2022 6:42 PM, deadalnix wrote:
 I have done so numerous times. Every single god damn time you answer the same 
 thing.
The n.g. archives can be found here: https://www.digitalmars.com/d/archives/digitalmars/D/index.html It's searchable, but I don't know what to search for.
Nov 29 2022
parent reply Lars Johansson <lars 11dim.se> writes:
I'm new to the term 'sum type'. To me it sounds like sum type is 
a kind of 'or' set.
Is sum type a simpler form of Raku's junction?
Nov 29 2022
parent reply Per =?UTF-8?B?Tm9yZGzDtnc=?= <per.nordlow gmail.com> writes:
On Tuesday, 29 November 2022 at 10:30:40 UTC, Lars Johansson 
wrote:
 I'm new to the term 'sum type'. To me it sounds like sum type 
 is a kind of 'or' set.
 Is sum type a simpler form of Raku's junction?
See https://en.wikipedia.org/wiki/Algebraic_data_type.
Nov 29 2022
parent reply Per =?UTF-8?B?Tm9yZGzDtnc=?= <per.nordlow gmail.com> writes:
On Tuesday, 29 November 2022 at 10:32:54 UTC, Per Nordlöw wrote:
 Is sum type a simpler form of Raku's junction?
See https://en.wikipedia.org/wiki/Algebraic_data_type.
Specifically https://en.wikipedia.org/wiki/Tagged_union.
Nov 29 2022
parent Lars Johansson <lars 11dim.se> writes:
On Tuesday, 29 November 2022 at 10:33:27 UTC, Per Nordlöw wrote:
 On Tuesday, 29 November 2022 at 10:32:54 UTC, Per Nordlöw wrote:
 Is sum type a simpler form of Raku's junction?
See https://en.wikipedia.org/wiki/Algebraic_data_type.
Specifically https://en.wikipedia.org/wiki/Tagged_union.
Tx:)
Nov 29 2022
prev sibling parent rikki cattermole <rikki cattermole.co.nz> writes:
One idea: offer a way to transform template arguments prior to passing 
them to the parameter.

```d
Foo!(const(int));
struct Foo(T |= Unqual) {}
```

Becomes:

```d
Foo!(Unqual!(const(int)));

struct Foo(T) {}
```
Nov 29 2022
prev sibling parent reply Vladimir Panteleev <thecybershadow.lists gmail.com> writes:
On Monday, 28 November 2022 at 09:27:11 UTC, Walter Bright wrote:
 I've written most of a DIP for one. Should I:
I really wish that instead of adding more language features, we would improve the language so that things like this are implementable *in* the language. I'm not sure about the argument that not everyone might use the same type if it's implemented as a custom type. Even if one were to argue that not everyone uses Phobos, the implementation can go into Druntime, which is an extension of the compiler, which solves this problem. The example in the DIP about null pointers is wrong. It can still be useful to distinguish between non-null pointers, null pointers, and some third state such as "no pointer". `Nullable!(Nullable!(Nullable!int)) foo` is perfectly valid. We don't even need a standardized `NonNull` type or trait or whatever. Leverage existing D features instead: ```d template nullIsValid(T) { static if (is(T == struct)) enum nullIsValid = { try { union U { ubyte[T.sizeof] bytes = 0; T t; } U u; assert(u.t); // call invariant return true; // no exception was thrown - null is a valid state } catch (Throwable e) return false; // exception was thrown - null is an INVALID state }(); else enum nullIsValid = true; } ``` or something like that. Currently it doesn't work because you can't call struct invariants directly, and can't catch `assert(false)` in CTFE. But, these are fixable and examples of things that would improve metaprogramming at a fundamental, building-block level and enable building more cool high-level types and data structures, not just sum types.
Nov 29 2022
next sibling parent reply "H. S. Teoh" <hsteoh qfbox.info> writes:
On Tue, Nov 29, 2022 at 11:56:40PM +0000, Vladimir Panteleev via Digitalmars-d
wrote:
 On Monday, 28 November 2022 at 09:27:11 UTC, Walter Bright wrote:
 I've written most of a DIP for one. Should I:
I really wish that instead of adding more language features, we would improve the language so that things like this are implementable *in* the language.
[.[..] +1, I think this is a better approach. If a library type can't do what a built-in type does, then extend the language until it can. As Andrei said in TDPL: "experience has shown time and again that offering many magic types that are unattainable to user code is a frustrating proposition and a sign of poor language design" [TDPL, 2010 ed, p.239]. T -- Knowledge is that area of ignorance that we arrange and classify. -- Ambrose Bierce
Nov 29 2022
next sibling parent reply deadalnix <deadalnix gmail.com> writes:
On Wednesday, 30 November 2022 at 00:10:47 UTC, H. S. Teoh wrote:
 On Tue, Nov 29, 2022 at 11:56:40PM +0000, Vladimir Panteleev 
 via Digitalmars-d wrote:
 On Monday, 28 November 2022 at 09:27:11 UTC, Walter Bright 
 wrote:
 I've written most of a DIP for one. Should I:
I really wish that instead of adding more language features, we would improve the language so that things like this are implementable *in* the language.
[.[..] +1, I think this is a better approach. If a library type can't do what a built-in type does, then extend the language until it can. As Andrei said in TDPL: "experience has shown time and again that offering many magic types that are unattainable to user code is a frustrating proposition and a sign of poor language design" [TDPL, 2010 ed, p.239]. T
Damn, this Andrei guy, he knew one thing or two...
Nov 29 2022
parent reply "H. S. Teoh" <hsteoh qfbox.info> writes:
On Wed, Nov 30, 2022 at 12:42:38AM +0000, deadalnix via Digitalmars-d wrote:
 On Wednesday, 30 November 2022 at 00:10:47 UTC, H. S. Teoh wrote:
[...]
 +1, I think this is a better approach.  If a library type can't do
 what a built-in type does, then extend the language until it can.
 As Andrei said in TDPL: "experience has shown time and again that
 offering many magic types that are unattainable to user code is a
 frustrating proposition and a sign of poor language design" [TDPL,
 2010 ed, p.239].
[...]
 Damn, this Andrei guy, he knew one thing or two...
And to elaborate a little, for those people who groan at "yet another library type": a common objection is that a library type has poorer error messages. Well, it's just the same thing in different clothes: if a library type can't have good error messages, why is that? Because the language cannot express certain things, or can't do it well, so the library author's hands are tied. Giving up and pushing the type into the language is merely avoiding the problem (now the compiler writer has to solve the same problems, only in the compiler -- the amount of effort required is equivalent). What actually addresses the problem is: fix the language so that the library author *can* provide good error messages. Because this isn't just about adding sumtype or whatever other magic type, this is about making it possible for *any* user type to provide the same level of functionality as built-in types. It's about empowering the library writer so that he can replicate the power of a built-in type, integrated so well into the language that it feels like native type. This includes containers that behave like built-in arrays, ARC'd types that behave like pointers, etc.. Solve this at the core, and it will enable progress on many other fronts. Fail at this, and you're doomed to putting out individual fires one by one, ala whack-a-mole. Today it's sumtypes, tomorrow it's ARC types, the next day it's head-immutable, it will never end. T -- Don't drink and derive. Alcohol and algebra don't mix.
Nov 29 2022
next sibling parent reply zjh <fqbqrr 163.com> writes:
On Wednesday, 30 November 2022 at 01:09:03 UTC, H. S. Teoh wrote:
 This includes containers that behave like built-in arrays, 
 ARC'd types that behave like pointers, etc..  Solve this at the 
 core, and it will enable progress on many other fronts.
How can we improve the `core`?
Nov 29 2022
parent reply "H. S. Teoh" <hsteoh qfbox.info> writes:
On Wed, Nov 30, 2022 at 02:23:20AM +0000, zjh via Digitalmars-d wrote:
 On Wednesday, 30 November 2022 at 01:09:03 UTC, H. S. Teoh wrote:
 This includes containers that behave like built-in arrays, ARC'd
 types that behave like pointers, etc..  Solve this at the core, and
 it will enable progress on many other fronts.
How can we improve the `core`?
[...] By extending the language in such a way that a user type can accomplish what currently can only be done by a built-in type. To randomly pick a recent example: const(T)[] can be implicitly cast to const(T[]), but UserContainer!(const(T)) cannot be implicitly cast to const(UserContainer!T). There are various ways of dealing with this: One way is to ignore it ("the language does not support this"), which is the current status quo -- the result is that library container types will always be 2nd class, and they can never fully emulate the behaviour of built-in arrays. Another way is to introduce a new built-in type that emulates some or all of the functionality of UserContainer. It solves this particular problem (just replace UserContainer with the new built-in type, or some adaptation of the new built-in type), but the fundamental problem (Template!(const T) is incompatible with const(Template!T)) remains unsolved. Next time, somebody comes along and complains that AnotherContainer!(const T) is not compatible with const(AnotherContainer!T), so we're back to square 1 again. One way to actually solve this problem is to let user types declare the equivalence between their const forms. From a discussion a few years ago I had here on the forum, we could introduce an opImplicitCast method/template that the compiler looks up whenever user code has an instance of Container!(const T) but needs an instance of const(Container!T). Then there would be some way for this method/template to cast the container or create a proxy or something, to produce the needed instance of const(Container!T). This makes the language extensible: it doesn't need to invent special rules for converting between various forms of const in relation to Container, the definition of Container itself provides the instructions of what to do to achieve this conversion (or prohibit it, as the case may be). The language remains agnostic of how const should interact with user types, but provides the library author the tools to tell it what to do for each particular case. (BTW I'm not pushing for this particular solution, just using it as an illustration of what I'm talking about.) IOW, empower the user instead of trying to make the language omniscient about every last imaginable use case. T -- It is not the employer who pays the wages. Employers only handle the money. It is the customer who pays the wages. -- Henry Ford
Nov 29 2022
next sibling parent reply Tejas <notrealemail gmail.com> writes:
On Wednesday, 30 November 2022 at 02:49:44 UTC, H. S. Teoh wrote:
 On Wed, Nov 30, 2022 at 02:23:20AM +0000, zjh via Digitalmars-d 
 wrote:
 [...]
[...] By extending the language in such a way that a user type can accomplish what currently can only be done by a built-in type. [...]
In the end, it will come down to allowing the programmer to manipulate the AST directly in order to perform all the operations that the compiler can perform... And we know AST macros ain't happening
Nov 29 2022
parent reply Paul Backus <snarwin gmail.com> writes:
On Wednesday, 30 November 2022 at 03:45:13 UTC, Tejas wrote:
 On Wednesday, 30 November 2022 at 02:49:44 UTC, H. S. Teoh 
 wrote:
 On Wed, Nov 30, 2022 at 02:23:20AM +0000, zjh via 
 Digitalmars-d wrote:
 [...]
[...] By extending the language in such a way that a user type can accomplish what currently can only be done by a built-in type. [...]
In the end, it will come down to allowing the programmer to manipulate the AST directly in order to perform all the operations that the compiler can perform... And we know AST macros ain't happening
Lack of AST macros means we can't implement custom *syntax* in library code (except via string mixins). It does not, in principle, place any hard limit on the *semantics* we can implement. Fully-featured pattern matching requires new syntax, so it will have to be a built-in language feature, but sum types themselves are mostly about semantics, not syntax. With a handful of general-purpose language enhancements, we could in principle have a library sumtype that works just as well as a built-in one from a semantic perspective--*and* we could use the same enhancements to improve other library-defined types, like containers, ranges, etc.
Nov 29 2022
parent reply Tejas <notrealemail gmail.com> writes:
On Wednesday, 30 November 2022 at 03:55:18 UTC, Paul Backus wrote:
 On Wednesday, 30 November 2022 at 03:45:13 UTC, Tejas wrote:
 On Wednesday, 30 November 2022 at 02:49:44 UTC, H. S. Teoh 
 wrote:
 [...]
In the end, it will come down to allowing the programmer to manipulate the AST directly in order to perform all the operations that the compiler can perform... And we know AST macros ain't happening
Lack of AST macros means we can't implement custom *syntax* in library code (except via string mixins). It does not, in principle, place any hard limit on the *semantics* we can implement. Fully-featured pattern matching requires new syntax, so it will have to be a built-in language feature, but sum types themselves are mostly about semantics, not syntax. With a handful of general-purpose language enhancements, we could in principle have a library sumtype that works just as well as a built-in one from a semantic perspective--*and* we could use the same enhancements to improve other library-defined types, like containers, ranges, etc.
Oh? What are these enhancements? - One is Deadalnix's "allow `const type!int` to convert to `type!(const int)`" - Another I know of is many folks asking for some kinda hook in the template type inference process
Nov 29 2022
parent reply Paul Backus <snarwin gmail.com> writes:
On Wednesday, 30 November 2022 at 05:29:03 UTC, Tejas wrote:
 On Wednesday, 30 November 2022 at 03:55:18 UTC, Paul Backus 
 wrote:
 Fully-featured pattern matching requires new syntax, so it 
 will have to be a built-in language feature, but sum types 
 themselves are mostly about semantics, not syntax. With a 
 handful of general-purpose language enhancements, we could in 
 principle have a library sumtype that works just as well as a 
 built-in one from a semantic perspective--*and* we could use 
 the same enhancements to improve other library-defined types, 
 like containers, ranges, etc.
Oh? What are these enhancements? - One is Deadalnix's "allow `const type!int` to convert to `type!(const int)`" - Another I know of is many folks asking for some kinda hook in the template type inference process
Stuff like - User-defined implicit conversions. - Returning error messages from failed `is(...)` and `__traits(compiles)` checks instead of just `false`. - Allowing library code to *display* its own custom error messages, with the same control and flexibility the compiler has for built-in messages (currently we only have `static assert`). - User-defined GC scanning for library types (`opGCScan`?). - User-defined value ranges for aggregate fields (e.g., pointer that can't be null, integer that can't go above/below a certain limit). All of these are things that built-in types have access to already, and all of these would have useful applications beyond just sum types.
Nov 30 2022
next sibling parent jmh530 <john.michael.hall gmail.com> writes:
On Wednesday, 30 November 2022 at 13:45:09 UTC, Paul Backus wrote:
 [snip]

 - User-defined implicit conversions.
 - Returning error messages from failed `is(...)` and 
 `__traits(compiles)` checks instead of just `false`.
 - Allowing library code to *display* its own custom error 
 messages, with the same control and flexibility the compiler 
 has for built-in messages (currently we only have `static 
 assert`).
 - User-defined GC scanning for library types (`opGCScan`?).
 - User-defined value ranges for aggregate fields (e.g., pointer 
 that can't be null, integer that can't go above/below a certain 
 limit).

 All of these are things that built-in types have access to 
 already, and all of these would have useful applications beyond 
 just sum types.
Not sure what is meant by the above about template type inference, but here are enhancement requests for what Paul mentioned. https://issues.dlang.org/show_bug.cgi?id=23523 https://issues.dlang.org/show_bug.cgi?id=23527 https://issues.dlang.org/show_bug.cgi?id=23526 https://issues.dlang.org/show_bug.cgi?id=23525 https://issues.dlang.org/show_bug.cgi?id=23524 Feel free to add more info there to further explain what you are looking for.
Nov 30 2022
prev sibling parent Tejas <notrealemail gmail.com> writes:
On Wednesday, 30 November 2022 at 13:45:09 UTC, Paul Backus wrote:
 - User-defined value ranges for aggregate fields (e.g., pointer 
 that can't be null, integer that can't go above/below a certain 
 limit).
Don't we kind of have this with `invariant`?
Nov 30 2022
prev sibling parent zjh <fqbqrr 163.com> writes:
On Wednesday, 30 November 2022 at 02:49:44 UTC, H. S. Teoh wrote:

 ...
I think, It should be possible to improve the core language in the way of `vim-like plug-in`. There should also be a list of `important core related to do` items. `Implicit cast` is different from `implicit cast const`.
Nov 29 2022
prev sibling parent reply Paulo Pinto <pjmlp progtools.org> writes:
On Wednesday, 30 November 2022 at 01:09:03 UTC, H. S. Teoh wrote:
 On Wed, Nov 30, 2022 at 12:42:38AM +0000, deadalnix via 
 Digitalmars-d wrote:
 On Wednesday, 30 November 2022 at 00:10:47 UTC, H. S. Teoh 
 wrote:
[...]
 +1, I think this is a better approach.  If a library type 
 can't do what a built-in type does, then extend the language 
 until it can. As Andrei said in TDPL: "experience has shown 
 time and again that offering many magic types that are 
 unattainable to user code is a frustrating proposition and a 
 sign of poor language design" [TDPL, 2010 ed, p.239].
[...]
 Damn, this Andrei guy, he knew one thing or two...
And to elaborate a little, for those people who groan at "yet another library type": a common objection is that a library type has poorer error messages. Well, it's just the same thing in different clothes: if a library type can't have good error messages, why is that? Because the language cannot express certain things, or can't do it well, so the library author's hands are tied. Giving up and pushing the type into the language is merely avoiding the problem (now the compiler writer has to solve the same problems, only in the compiler -- the amount of effort required is equivalent). What actually addresses the problem is: fix the language so that the library author *can* provide good error messages. Because this isn't just about adding sumtype or whatever other magic type, this is about making it possible for *any* user type to provide the same level of functionality as built-in types. It's about empowering the library writer so that he can replicate the power of a built-in type, integrated so well into the language that it feels like native type. This includes containers that behave like built-in arrays, ARC'd types that behave like pointers, etc.. Solve this at the core, and it will enable progress on many other fronts. Fail at this, and you're doomed to putting out individual fires one by one, ala whack-a-mole. Today it's sumtypes, tomorrow it's ARC types, the next day it's head-immutable, it will never end. T
We already have C++ for that, beware of having wishes coming true.
Nov 30 2022
parent "H. S. Teoh" <hsteoh qfbox.info> writes:
On Wed, Nov 30, 2022 at 12:13:52PM +0000, Paulo Pinto via Digitalmars-d wrote:
 On Wednesday, 30 November 2022 at 01:09:03 UTC, H. S. Teoh wrote:
[...]
 And to elaborate a little, for those people who groan at "yet
 another library type": a common objection is that a library type has
 poorer error messages.  Well, it's just the same thing in different
 clothes: if a library type can't have good error messages, why is
 that?  Because the language cannot express certain things, or can't
 do it well, so the library author's hands are tied.  Giving up and
 pushing the type into the language is merely avoiding the problem
 (now the compiler writer has to solve the same problems, only in the
 compiler -- the amount of effort required is equivalent).  What
 actually addresses the problem is: fix the language so that the
 library author *can* provide good error messages.
 
 Because this isn't just about adding sumtype or whatever other magic
 type, this is about making it possible for *any* user type to
 provide the same level of functionality as built-in types.  It's
 about empowering the library writer so that he can replicate the
 power of a built-in type, integrated so well into the language that
 it feels like native type.  This includes containers that behave
 like built-in arrays, ARC'd types that behave like pointers, etc..
 Solve this at the core, and it will enable progress on many other
 fronts.  Fail at this, and you're doomed to putting out individual
 fires one by one, ala whack-a-mole.  Today it's sumtypes, tomorrow
 it's ARC types, the next day it's head-immutable, it will never end.
[...]
 We already have C++ for that, beware of having wishes coming true.
Yes and no. C++ does let you customize all sorts of things (including dangerous things like unary `operator&`, `operator,`, and other such things that *really* mess with program syntax), but it does so in an unclean, non-orthogonal way that gives you 1 way to solve your problem plus 10 other ways of shooting your foot. Take for example overloading the comparison operators. Instead of D's much saner approach of having a single opCmp that ensures consistency between <, <=, >=, >, C++ lets you overload each of those operators separately. As a result, library code has tons of boilerplate (you need
=4 operator overload functions instead of just a single opCmp), is
fragile (the compiler does not help you maintain consistency between operator<, operator<=, operator>=, and operator>=), and wide open for abuse (I can, for example, write operator< to be an input operator and operator> to format your hard disk). In the meantime, nothing lets user code dictate how a custom type / function should behave in the face of Koenig lookup + SFINAE, a nasty combination where in order to understand which overload just got called, you have to understand the entire codebase (an impossible task in a large project). IOW, C++ lets you customize everything, yes, but it does so in the least optimal, most fragile, unorthogonal, and unmaintainable way. What D needs is hooks into core semantics in the pattern of opEquals/opCmp, not in the pattern of C++'s operator==, operator!=, operator<, operator<=, ad nauseum. This requires careful thought and design, not just blindly going "oh user code wants to overload the comma operator? sure, just add operator,() and you're all set!" or "oh user code wants to override const? sure, why not introduce operator const() to the language". The user should be empowered, yes, but with a properly-designed tool, not a lit bundle of dynamite with which to blow himself up. T -- If it breaks, you get to keep both pieces. -- Software disclaimer notice
Nov 30 2022
prev sibling parent jmh530 <john.michael.hall gmail.com> writes:
On Wednesday, 30 November 2022 at 00:10:47 UTC, H. S. Teoh wrote:
 On Tue, Nov 29, 2022 at 11:56:40PM +0000, Vladimir Panteleev 
 via Digitalmars-d wrote:
 On Monday, 28 November 2022 at 09:27:11 UTC, Walter Bright 
 wrote:
 I've written most of a DIP for one. Should I:
I really wish that instead of adding more language features, we would improve the language so that things like this are implementable *in* the language.
[.[..] +1, I think this is a better approach. If a library type can't do what a built-in type does, then extend the language until it can. As Andrei said in TDPL: "experience has shown time and again that offering many magic types that are unattainable to user code is a frustrating proposition and a sign of poor language design" [TDPL, 2010 ed, p.239]. T
I don't dispute this, but there's a bit of a gulf between saying it and it actually happening. There needs to be a specific list of things that need to be changed, preferably as bug reports, otherwise Walter will complain about it getting lost in old forum posts.
Nov 29 2022
prev sibling next sibling parent reply ryuukk_ <ryuukk.dev gmail.com> writes:
On Tuesday, 29 November 2022 at 23:56:40 UTC, Vladimir Panteleev 
wrote:
 On Monday, 28 November 2022 at 09:27:11 UTC, Walter Bright 
 wrote:
 I've written most of a DIP for one. Should I:
I really wish that instead of adding more language features, we would improve the language so that things like this are implementable *in* the language. I'm not sure about the argument that not everyone might use the same type if it's implemented as a custom type. Even if one were to argue that not everyone uses Phobos, the implementation can go into Druntime, which is an extension of the compiler, which solves this problem. The example in the DIP about null pointers is wrong. It can still be useful to distinguish between non-null pointers, null pointers, and some third state such as "no pointer". `Nullable!(Nullable!(Nullable!int)) foo` is perfectly valid. We don't even need a standardized `NonNull` type or trait or whatever. Leverage existing D features instead: ```d template nullIsValid(T) { static if (is(T == struct)) enum nullIsValid = { try { union U { ubyte[T.sizeof] bytes = 0; T t; } U u; assert(u.t); // call invariant return true; // no exception was thrown - null is a valid state } catch (Throwable e) return false; // exception was thrown - null is an INVALID state }(); else enum nullIsValid = true; } ``` or something like that. Currently it doesn't work because you can't call struct invariants directly, and can't catch `assert(false)` in CTFE. But, these are fixable and examples of things that would improve metaprogramming at a fundamental, building-block level and enable building more cool high-level types and data structures, not just sum types.
Why have slices as builtin, it should be a template that nobody can read or write themselves On top of an exception hidden within..
Nov 29 2022
parent ryuukk_ <ryuukk.dev gmail.com> writes:
On Wednesday, 30 November 2022 at 00:17:04 UTC, ryuukk_ wrote:
 On Tuesday, 29 November 2022 at 23:56:40 UTC, Vladimir 
 Panteleev wrote:
 On Monday, 28 November 2022 at 09:27:11 UTC, Walter Bright 
 wrote:
 I've written most of a DIP for one. Should I:
I really wish that instead of adding more language features, we would improve the language so that things like this are implementable *in* the language. I'm not sure about the argument that not everyone might use the same type if it's implemented as a custom type. Even if one were to argue that not everyone uses Phobos, the implementation can go into Druntime, which is an extension of the compiler, which solves this problem. The example in the DIP about null pointers is wrong. It can still be useful to distinguish between non-null pointers, null pointers, and some third state such as "no pointer". `Nullable!(Nullable!(Nullable!int)) foo` is perfectly valid. We don't even need a standardized `NonNull` type or trait or whatever. Leverage existing D features instead: ```d template nullIsValid(T) { static if (is(T == struct)) enum nullIsValid = { try { union U { ubyte[T.sizeof] bytes = 0; T t; } U u; assert(u.t); // call invariant return true; // no exception was thrown - null is a valid state } catch (Throwable e) return false; // exception was thrown - null is an INVALID state }(); else enum nullIsValid = true; } ``` or something like that. Currently it doesn't work because you can't call struct invariants directly, and can't catch `assert(false)` in CTFE. But, these are fixable and examples of things that would improve metaprogramming at a fundamental, building-block level and enable building more cool high-level types and data structures, not just sum types.
Why have slices as builtin, it should be a template that nobody can read or write themselves On top of an exception hidden within..
I don't think having a language for compiler writers is compelling for non-compiler writers There is value in having common constructs implemented as first class language feature - better error message - better debugging - easier to integrate with tooling - everyone agree on a syntax - performance When all the std eats the budget of template soup, what's left for me? using templates on top of templates on top of other templates, then users complain it takes 60 seconds to compile It's important to showcase metaprogramming capabilities, but not everything has to be a template, specially for something as basic as tagged union
Nov 29 2022
prev sibling next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 11/30/22 00:56, Vladimir Panteleev wrote:
 On Monday, 28 November 2022 at 09:27:11 UTC, Walter Bright wrote:
 I've written most of a DIP for one. Should I:
I really wish that instead of adding more language features, we would improve the language so that things like this are implementable *in* the language.
Well, ideally both. Tagged unions are fundamental enough to get some syntactic sugar. So are tuples. But except for syntax, I agree that user-defined types should be able to benefit as well. Here, I guess this would mean to add some mechanism to allow the language to understand which `union` member is currently active. This would also help with precise GC. Another consideration is compile times. Sometimes it makes sense to build things into the language because you don't want to interpret them again and again if you can compile them once into the compiler frontend. I also don't like magic though. Ideally it should be possible to write a shallow wrapper `struct` (template) around any other type without losing any functionality.
Nov 29 2022
prev sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 11/29/2022 3:56 PM, Vladimir Panteleev wrote:
 On Monday, 28 November 2022 at 09:27:11 UTC, Walter Bright wrote:
 I've written most of a DIP for one. Should I:
I really wish that instead of adding more language features, we would improve the language so that things like this are implementable *in* the language.
There is std.sumtype https://dlang.org/phobos/std_sumtype.html
 I'm not sure about the argument that not everyone might use the same type if 
 it's implemented as a custom type. Even if one were to argue that not everyone 
 uses Phobos, the implementation can go into Druntime, which is an extension of 
 the compiler, which solves this problem.
In general you're correct. But sometimes, it's a big win to put things into the language. Two examples: ddoc and unittest. The conventional wisdom at the time was these certainly should not be part of the core language.
 The example in the DIP about null pointers is wrong. It can still be useful to 
 distinguish between non-null pointers, null pointers, and some third state
such 
 as "no pointer". `Nullable!(Nullable!(Nullable!int)) foo` is perfectly valid.
True, but the draft design doesn't prevent doing that.
 We don't even need a standardized `NonNull` type or trait or whatever.
Leverage 
 existing D features instead:
 
 ```d
 template nullIsValid(T)
 {
      static if (is(T == struct))
          enum nullIsValid = {
              try
              {
                  union U
                  {
                      ubyte[T.sizeof] bytes = 0;
                      T t;
                  }
                  U u;
                  assert(u.t); // call invariant
                  return true; // no exception was thrown - null
is a valid state
              }
              catch (Throwable e)
                  return false; // exception was thrown - null
is an INVALID state
          }();
      else
          enum nullIsValid = true;
 }
 ```
 
 or something like that. Currently it doesn't work because you can't call
struct 
 invariants directly, and can't catch `assert(false)` in CTFE. But, these are 
 fixable and examples of things that would improve metaprogramming at a 
 fundamental, building-block level and enable building more cool high-level
types 
 and data structures, not just sum types.
True, but I wouldn't have a null pointer violation be anything but a fatal error, not a catchable exception.
Nov 29 2022