digitalmars.D - sumtypes for D
- Walter Bright (5/5) Nov 28 2022 I've written most of a DIP for one. Should I:
- Dukc (4/9) Nov 28 2022 If you don't know, I'd go with 3. Or maybe post a link to the DIP
- Dukc (4/7) Nov 28 2022 But let's wait for Mike's opinion first. I can't remember for
- Nick Treleaven (7/20) Nov 28 2022 If the DIP is complete I think it's usually best to submit the
- Tejas (5/10) Nov 28 2022 I think you should post it, unless you feel you haven't worked on
- Basile B. (2/7) Nov 28 2022 1. DIP first. Then 3. announce the DIP
- Mike Parker (12/14) Nov 28 2022 This gets my vote. I think we should just drop the rule that you
- Walter Bright (2/12) Nov 28 2022 Sounds like a winner.
- rikki cattermole (3/3) Nov 28 2022 I'm pretty eager to see this DIP.
- Walter Bright (2/4) Nov 28 2022 Looking forward to it!
- ryuukk_ (4/9) Nov 28 2022 I would love to read the DIP, so i vote for 1., 3. works too, 2.
- novice2 (2/3) Nov 28 2022 remember @live, named parameters...
- IGotD- (4/7) Nov 28 2022 Actually creating a preview as well can help as then programmers
- Walter Bright (3/5) Nov 28 2022 Implementing it will be a substantial amount of work (as opposed to the ...
- zjh (4/11) Nov 28 2022 Can a `dip` be similar to a `plug-in`? As long as the `dip`
- Walter Bright (2/5) Nov 28 2022 I think you meant "fork" :-/
- Per =?UTF-8?B?Tm9yZGzDtnc=?= (7/12) Nov 28 2022 Sum-types is the one feature I miss the most in D, so you have my
- Per =?UTF-8?B?Tm9yZGzDtnc=?= (4/5) Nov 28 2022 Or rather the builtin feature I missed the most having
- max haughton (6/11) Nov 28 2022 Yes. You can do match as a template, fairly well even, but when
- deadalnix (14/15) Nov 28 2022 I'd like to point out that we still don't have a reasonable
- max haughton (29/45) Nov 28 2022 Built-in sumtypes will unify a lot of codebases if done right:
- rikki cattermole (9/9) Nov 28 2022 For all we know Walter just threw together some stuff on a whim, hence
- Walter Bright (1/1) Nov 28 2022 I agree, it's clear that sumtypes are pretty much required in a modern l...
- deadalnix (32/35) Nov 28 2022 Unifying and yada yada are all very nice sounding words, but I'm
- rikki cattermole (7/11) Nov 28 2022 Broken and incomplete implementations too.
- Walter Bright (2/8) Nov 28 2022 When posting things like this, links to the bugzilla entries are most ap...
- rikki cattermole (6/16) Nov 29 2022 I take it you haven't been reading my posts about shared library
- Walter Bright (5/5) Nov 29 2022 https://issues.dlang.org/show_bug.cgi?id=6019
- Walter Bright (4/7) Nov 30 2022 I looked at https://issues.dlang.org/show_bug.cgi?id=22367 in your list,...
- rikki cattermole (4/12) Nov 30 2022 This isn't fixing it.
- Walter Bright (2/17) Nov 30 2022 I don't know what you mean. It fixes the problem in 22367.
- rikki cattermole (7/14) Nov 30 2022 The symptom is that dmd is turning on requirement for ModuleInfo when it...
- Walter Bright (4/4) Nov 30 2022 Please repost your critique on 22367, so others interested in the Module...
- Adam D Ruppe (6/7) Nov 28 2022 Curious, what did you find lacking in std.sumtype?
- Walter Bright (5/8) Nov 28 2022 It's addressed in the draft DIP I just posted.
- Timon Gehr (25/36) Nov 29 2022 Nice! I think this general design, where it behaves just like a tagged
- Timon Gehr (2/3) Nov 29 2022 Meant to write "data flow analysis" here.
- Timon Gehr (32/43) Nov 29 2022 Some things that are missing:
- Timon Gehr (37/48) Nov 29 2022 BTW: I understand extraordinarily well where the desire for supporting
- Timon Gehr (6/11) Nov 29 2022 Should have been:
- Timon Gehr (17/27) Nov 29 2022 Maybe consider changing the syntax to something like:
- rikki cattermole (3/24) Nov 29 2022 Could you please post this on the new thread where the draft is linked?
- Timon Gehr (3/30) Nov 29 2022 Oops. Moved it all over. I guess the corresponding messages in this
- deadalnix (9/16) Nov 29 2022 Good question. They didn't work in my case mainly for 2 reasons:
- Nick Treleaven (4/11) Nov 29 2022 I haven't used it yet. But you can't implicitly convert an
- max haughton (36/72) Nov 28 2022 I have met a few people who were specifically turned off of D
- deadalnix (74/94) Nov 29 2022 It seems like the high impact item here is matching more than the
- Timon Gehr (10/21) Nov 29 2022 I am also in favor of making solutions that are needed for sum types
- Walter Bright (3/17) Nov 28 2022 It would be nice if you enumerated those fundamental problems. I don't k...
- deadalnix (22/24) Nov 28 2022 I have done so numerous times. Every single god damn time you
- Steven Schveighoffer (19/28) Nov 28 2022 This is pretty harsh for the single problem you bring up, which I agree
- Paul Backus (11/19) Nov 28 2022 The thing is, we pretty much know what the solution is. In the
- zjh (3/10) Nov 28 2022 There are solutions, why not to apply it?
- Paul Backus (5/16) Nov 28 2022 Walter Bright is strongly opposed to adding user-defined implicit
- zjh (9/13) Nov 28 2022 In C++, I have never used implicit conversion. I just add an
- Steven Schveighoffer (4/21) Nov 28 2022 This is not how I would solve it. I would solve it in the general case,
- Walter Bright (11/26) Nov 28 2022 I don't doubt you. The trouble is, the n.g. is ephemeral. Once it scroll...
- deadalnix (5/7) Nov 29 2022 No, this will remove all qualifiers on user defined types. Which
- Walter Bright (4/6) Nov 29 2022 The n.g. archives can be found here:
- Lars Johansson (3/3) Nov 29 2022 I'm new to the term 'sum type'. To me it sounds like sum type is
- Per =?UTF-8?B?Tm9yZGzDtnc=?= (3/6) Nov 29 2022 See https://en.wikipedia.org/wiki/Algebraic_data_type.
- Per =?UTF-8?B?Tm9yZGzDtnc=?= (2/4) Nov 29 2022 Specifically https://en.wikipedia.org/wiki/Tagged_union.
- Lars Johansson (2/7) Nov 29 2022 Tx:)
- rikki cattermole (11/11) Nov 29 2022 One idea: offer a way to transform template arguments prior to passing
- Vladimir Panteleev (46/47) Nov 29 2022 I really wish that instead of adding more language features, we
- H. S. Teoh (10/16) Nov 29 2022 [.[..]
- deadalnix (2/19) Nov 29 2022 Damn, this Andrei guy, he knew one thing or two...
- H. S. Teoh (28/36) Nov 29 2022 [...]
- zjh (2/5) Nov 29 2022 How can we improve the `core`?
- H. S. Teoh (40/46) Nov 29 2022 [...]
- Tejas (6/13) Nov 29 2022 In the end, it will come down to allowing the programmer to
- Paul Backus (13/29) Nov 29 2022 Lack of AST macros means we can't implement custom *syntax* in
- Tejas (6/30) Nov 29 2022 Oh? What are these enhancements?
- Paul Backus (15/30) Nov 30 2022 Stuff like
- zjh (6/7) Nov 29 2022 I think, It should be possible to improve the core language in
- Paulo Pinto (2/40) Nov 30 2022 We already have C++ for that, beware of having wishes coming true.
- H. S. Teoh (35/61) Nov 30 2022 [...]
- jmh530 (6/23) Nov 29 2022 I don't dispute this, but there's a bit of a gulf between saying
- ryuukk_ (5/53) Nov 29 2022 Why have slices as builtin, it should be a template that nobody
- ryuukk_ (16/75) Nov 29 2022 I don't think having a language for compiler writers is
- Timon Gehr (13/19) Nov 29 2022 Well, ideally both. Tagged unions are fundamental enough to get some
- Walter Bright (9/53) Nov 29 2022 There is std.sumtype
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
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 itIf 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
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
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: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.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 itIf 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.
Nov 28 2022
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 itI 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
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 it1. DIP first. Then 3. announce the DIP
Nov 28 2022
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 DIPThis 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
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
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
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
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 itI 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
2. just implement it and do a PRremember live, named parameters... 1,3 and 4 wil be endless debates and no results.
Nov 28 2022
On Monday, 28 November 2022 at 15:48:23 UTC, novice2 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.2. just implement it and do a PRremember live, named parameters... 1,3 and 4 wil be endless debates and no results.
Nov 28 2022
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
On Monday, 28 November 2022 at 21:22:55 UTC, Walter Bright wrote:On 11/28/2022 7:53 AM, IGotD- 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?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
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
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
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
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
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 itSum-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
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
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: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.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
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
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: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.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
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
I agree, it's clear that sumtypes are pretty much required in a modern language.
Nov 28 2022
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
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
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
On 29/11/2022 8:28 PM, Walter Bright wrote:On 11/28/2022 6:46 PM, rikki cattermole wrote: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.comSeriously, 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 29 2022
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
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
On 30/11/2022 9:30 PM, Walter Bright wrote:On 11/28/2022 6:46 PM, rikki cattermole 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.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
On 11/30/2022 6:50 AM, rikki cattermole wrote:On 30/11/2022 9:30 PM, Walter Bright wrote:I don't know what you mean. It fixes the problem in 22367.On 11/28/2022 6:46 PM, rikki cattermole 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.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
On 01/12/2022 9:38 AM, Walter Bright wrote: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.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
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
On Tuesday, 29 November 2022 at 02:33:21 UTC, deadalnix wrote:I'm literally building a sum typeCurious, 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
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
On 11/29/22 08:26, Walter Bright wrote:On 11/28/2022 6:53 PM, Adam D Ruppe wrote: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.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 29 2022
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
On 11/29/22 08:26, Walter Bright wrote:On 11/28/2022 6:53 PM, Adam D Ruppe wrote: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)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 29 2022
On 11/29/22 08:26, Walter Bright wrote:On 11/28/2022 6:53 PM, Adam D Ruppe wrote: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.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 29 2022
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
On 11/29/22 08:26, Walter Bright wrote:On 11/28/2022 6:53 PM, Adam D Ruppe 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.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 ...
Nov 29 2022
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
On 11/29/22 15:31, rikki cattermole wrote:On 30/11/2022 3:24 AM, Timon Gehr wrote:Oops. Moved it all over. I guess the corresponding messages in this thread can be deleted.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
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: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.I'm literally building a sum typeCurious, 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 29 2022
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 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.I'm literally building a sum typeCurious, 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 29 2022
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: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.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.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
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
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
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
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
On 11/28/22 9:42 PM, deadalnix wrote:On Tuesday, 29 November 2022 at 01:27:32 UTC, Walter Bright wrote: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. -SteveIt 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.
Nov 28 2022
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
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
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: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.combecause 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
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.comIn 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
On 11/28/22 10:37 PM, Paul Backus wrote:On Tuesday, 29 November 2022 at 03:03:37 UTC, Steven Schveighoffer wrote:This is not how I would solve it. I would solve it in the general case, with a new syntax. -SteveThe 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))`).
Nov 28 2022
On 11/28/2022 6:42 PM, deadalnix wrote:On Tuesday, 29 November 2022 at 01:27:32 UTC, Walter Bright wrote: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 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...Top level qualifiers can be removed with: cast()expression
Nov 28 2022
On Tuesday, 29 November 2022 at 06:45:37 UTC, Walter Bright wrote:Top level qualifiers can be removed with: cast()expressionNo, 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
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
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
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
On Tuesday, 29 November 2022 at 10:32:54 UTC, Per Nordlöw wrote:Specifically https://en.wikipedia.org/wiki/Tagged_union.Is sum type a simpler form of Raku's junction?See https://en.wikipedia.org/wiki/Algebraic_data_type.
Nov 29 2022
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:Tx:)Specifically https://en.wikipedia.org/wiki/Tagged_union.Is sum type a simpler form of Raku's junction?See https://en.wikipedia.org/wiki/Algebraic_data_type.
Nov 29 2022
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
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
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:[.[..] +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 BierceI'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.
Nov 29 2022
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:Damn, this Andrei guy, he knew one thing or two...On Monday, 28 November 2022 at 09:27:11 UTC, Walter Bright 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]. TI'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.
Nov 29 2022
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
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
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:[...] 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 FordThis 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
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: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[...][...] 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. [...]
Nov 29 2022
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: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.On Wed, Nov 30, 2022 at 02:23:20AM +0000, zjh via Digitalmars-d 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[...][...] 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. [...]
Nov 29 2022
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: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 processOn Wednesday, 30 November 2022 at 02:49:44 UTC, H. S. Teoh wrote: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.[...]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
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: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.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 30 2022
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
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
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
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:We already have C++ for that, beware of having wishes coming true.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
Nov 30 2022
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), isfragile (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
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: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.On Monday, 28 November 2022 at 09:27:11 UTC, Walter Bright 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]. TI'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.
Nov 29 2022
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: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'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
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: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 unionOn Monday, 28 November 2022 at 09:27:11 UTC, Walter Bright wrote: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'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
On 11/30/22 00:56, Vladimir Panteleev wrote:On Monday, 28 November 2022 at 09:27:11 UTC, Walter Bright wrote: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.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.
Nov 29 2022
On 11/29/2022 3:56 PM, Vladimir Panteleev wrote:On Monday, 28 November 2022 at 09:27:11 UTC, Walter Bright wrote:There is std.sumtype https://dlang.org/phobos/std_sumtype.htmlI'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.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