digitalmars.D - Phobos 3 Discussion Notes - 02-01-2024
- Adam Wilson (96/96) Feb 02 Walter and I had a productive conversation yesterday about Phobos
- aberba (12/16) Feb 02 What about the missing standard library pieces that are core to
- Richard (Rikki) Andrew Cattermole (9/30) Feb 02 That is not part of the current work, although Adam does have a wish
- aberba (5/16) Feb 02 I understand what you're saying however it doesn't necessarily
- Richard (Rikki) Andrew Cattermole (3/23) Feb 02 Oh it will need reviewing line by line prior to copying.
- Adam Wilson (5/25) Feb 02 If you have a list of stuff that you think should be removed from
- Adam Wilson (12/23) Feb 02 The above list are all things that I would love to see make it in
- Lance Bachmeier (19/36) Feb 02 A better solution would be something like this:
- jmh530 (2/8) Feb 02 You think dub should be integrated into the language?
- Lance Bachmeier (6/18) Feb 02 It wouldn't be necessary. The compiler would only have to know
- Adam Wilson (33/52) Feb 02 I cannot argue strenuously enough against putting the packaging
- Lance Bachmeier (20/60) Feb 02 I responded to the other comment, but I'll give the same answer.
- Mengu (3/7) Feb 02 If I'm not mistaken Go has this for over 10 years now. I'm not
- Adam Wilson (40/75) Feb 02 But that's not true is it? How does it know which versions of the
- Lance Bachmeier (19/72) Feb 03 It doesn't need to if only the most recent version as of the
- Adam Wilson (93/117) Feb 03 This makes a number of assumptions about both the package itself
- Paul Backus (13/26) Feb 02 Why isn't Atila's document stored in a respository or shared
- Adam Wilson (22/50) Feb 02 Probably because reaching for GitHub is not how people
- ryuukk_ (20/20) Feb 02 Concerning allocators, needs a simpler API in `core.memory`,
- Walter Bright (3/10) Feb 02 - Drop all support for wchar and dchar from the templates. Instead, use ...
- jmh530 (9/13) Feb 02 When it comes to discussions around functions that allocate to
- Hipreme (10/25) Feb 02 It may be still a bad solution. Countless times I have done
- jmh530 (9/35) Feb 04 The work I’ve been doing is related to linear algebra. Nothing
- Jonathan M Davis (27/41) Feb 02 That's certainly the approach that I think that we should be taking for ...
- monkyyy (2/6) Feb 02 https://forum.dlang.org/thread/ghsihtmlurzsuslyzgnv@forum.dlang.org
- Andrea Fontana (18/51) Feb 02 What about std.v1.*, std.v2.* and so on? And obviously std.v1.*
- Adam Wilson (33/85) Feb 02 This hasn't been fully decided yet, and I probably need to have a
- ryuukk_ (10/16) Feb 03 What typeinfo/moduleinfo has to do with a networking module in
- ryuukk_ (5/23) Feb 03 Oh, and Exception Handling?
- Alexandru Ermicioi (6/10) Feb 03 Existing try catch syntax could be improved to support tagged
- Richard (Rikki) Andrew Cattermole (7/20) Feb 03 Yes it is well known that we want a different exception handling
- Adam Wilson (19/23) Feb 03 The EH problem has two potential answers.
- Atila Neves (6/17) Feb 05 Not unless we solve the "bubbling up" issue to avoid pattern
- Richard (Rikki) Andrew Cattermole (3/7) Feb 05 Oh look, someone has already done it!
- Atila Neves (3/10) Feb 05 Nice! How did I miss this??
- Richard (Rikki) Andrew Cattermole (3/16) Feb 05 Probably because you weren't on Discord or reading any of my comments on...
- Paul Backus (13/20) Feb 03 Obviously we are not going to get all of Phobos to work with
- Adam Wilson (18/30) Feb 03 This is the path that we're taking. We want to make Phobos as
- Sebastiaan Koppe (5/16) Feb 05 Absolutely.
- Atila Neves (3/17) Feb 05 I think our goal is to make `-betterC` obsolete. As in: if you
- zjh (2/4) Feb 05 Very nice.
- Paul Backus (5/17) Feb 05 This is more of a goal for druntime than Phobos, but yes, agreed.
- Atila Neves (5/25) Feb 05 Yeah, that's a good point. For instance: not allocating for no
- monkyyy (17/22) Feb 05 This feels delusional to me; like I don't know how the formal
- Paul Backus (11/23) Feb 05 The way you avoid this stuff is by testing. Run your unit tests
- monkyyy (15/32) Feb 05 That just adds a singluar blessed environment, it will be very
- H. S. Teoh (6/8) Feb 05 +1, this is the right approach.
- Mengu (4/8) Feb 02 Will there be a plan to put Phobos 2 on life support and
- Meta (3/4) Feb 04 Can you expand on this a bit more? I've contributed to std.traits
- Jonathan M Davis (36/40) Feb 04 The main thing that it needs IMHO is going through it and making sure th...
- ryuukk_ (10/29) Feb 04 On Sunday, 4 February 2024 at 02:25:25 UTC, Adam Wilson wrote:
- Jonathan M Davis (136/140) Feb 04 A number of us do not agree with you, and I for one never will. For many
- ryuukk_ (13/13) Feb 04 On Sunday, 4 February 2024 at 12:35:02 UTC, Jonathan M Davis
- Sergey (3/7) Feb 04 Why to be envious, and not just use this one for example
- aberba (5/18) Feb 04 No a fun of checking errors by return. Such code looks more
- Sebastiaan Koppe (13/23) Feb 04 I personally find exceptions useful only when I want to jump many
- H. S. Teoh (27/39) Feb 04 But I thought exceptions were not intended to be used in that kind of
- Sebastiaan Koppe (33/67) Feb 05 Sorry, I didn't phrase it correctly. You are right, exceptions
- H. S. Teoh (25/32) Feb 04 Exceptions are like the GC: they free your APIs from being littered with
- Paul Backus (9/19) Feb 04 I have bad news for you. This behavior is not the fault of
- Jonathan M Davis (31/50) Feb 04 std.traits doesn't actually rely on that. It does its own checks for enu...
- Meta (17/21) Feb 04 Man this is such an easily-fixable problem. I wish Walter weren't
- Atila Neves (30/90) Feb 05 And then subsequent versions get put in a package with a version
- Martyn (16/39) Feb 06 Very interesting!
- Paul Backus (14/20) Feb 06 Nothing's set in stone yet, but in the proposal I'm working on,
- Martyn (4/21) Feb 07 Thank you for taking the time to respond. I understand a proposal
- Atila Neves (6/26) Feb 07 The problem with this approach, as C++ found out, is that
- ryuukk_ (39/70) Feb 07 I do that as well
- Richard (Rikki) Andrew Cattermole (9/37) Feb 07 I came to a similar conclusion from my usage of std.experimental.allocat...
- Paul Backus (14/20) Feb 07 The relevant constraint here isn't composability, it's safety.
- Jonathan M Davis (28/50) Feb 07 Allocators should be @safe where they can be, but I think that a number ...
- Richard (Rikki) Andrew Cattermole (12/16) Feb 07 I do not.
- Paul Backus (16/34) Feb 07 With -preview=dip1000 and -preview=systemVariables, it is
- Jonathan M Davis (13/34) Feb 08 Well, regardless of what we end up doing iwth non-copyable types in Phob...
- Atila Neves (2/17) Feb 12 What specifically would we need support for?
- Paul Backus (27/34) Feb 12 It's not really any specific thing; it's more that Phobos's
- Atila Neves (6/30) Feb 13 I see. This is an instance of a more general problem of "nasty
- Paul Backus (4/9) Feb 13 If you want some examples to crib from, check out the unittests
- Atila Neves (4/14) Feb 13 Nice! Now we "just" have to move them somewhere common (so that
- ryuukk_ (9/14) Feb 08 We are here, we said we don't like them templated
- Paul Backus (29/42) Feb 07 Yes, I'm aware of this problem, but I don't see a way around it.
- Atila Neves (7/12) Feb 07 All good points, thanks. I like the "just use ranges" approach,
- Jonathan M Davis (28/43) Feb 07 Well, stuff that actually has to operate on the container itself is like...
- jmh530 (24/30) Feb 07 If you need to allocate or deallocate, then it's useful to treat
- Atila Neves (6/17) Feb 12 alias MyVec = Vector(MyType, Mallocator);
- jmh530 (52/70) Feb 12 I assume you mean `alias MyVec = Vector!(MyType, Mallocator);`.
- Atila Neves (6/12) Feb 13 My point is that things going out of scope can trigger
Walter and I had a productive conversation yesterday about Phobos 3 and we felt it would be appropriate to share some notes on our discussion. The conversation started out with me fumbling around trying to understand how Editions are going to effect Phobos. The discussion settled around two topics. The first was how to construct the package structure for Phobos 3. Walter has proposed using `std2.` as the root namespace. His primary reason was that he wanted to avoid the potential for importing anything from `std.` that might trigger auto-decoding. I pointed out two major flaws with this design. First, it would be very easy to accidentally type `std.` in an `std2.` module. We realized that this would be a problem no matter what root name was used and that the appropriate answer would be to specify a DStyle rule specific to Phobos that only modules in `std.` can import `std.` modules. Second, this design implies that the '2' in `std2.` is a version specifier that would be incremented with each Phobos release. This was not the intention and we agreed that it would be confusing. I proposed using `sys.` as the root name for Phobos 3 and Walter found that acceptable. We briefly discussed splitting up Phobos into multiple roots and no firm agreement was reached. The other major topic of discussion was what I've been calling the "Crippled by Default" design of editions, where the oldest edition (technically the last pre-edition release) is the default edition if no edition is specified. This poses a few challenges from an end-user standpoint, but the argument that ended up resonating was the idea that in engineering we always want to make the "right" way the default or easiest way to do something, and then provide escape hatches where necessary. Therefore, the compiler should default to use the latest version and then provide the ability via a switch to set the edition, or lack thereof, of the modules an import path. This solves the problem of abandon-ware packages being accessible without presenting the new user with an ever more decayed version of the compiler. We want to put out best foot forward and presenting the last pre-editions release, which is constantly getting old as time passes, does not do that. No specific agreement was reached but Walter agreed to consider it. When then moved on to a conversation about how Walter envisions editions actually working. Since none of have seen the document that Atila is working on, Walter shared his opinions on how it should work. Essentially, Walter would like to see a "hybrid" approach having edition attributes for specific experimental features, and then having a yearly "roll-up" edition that includes all the promoted features from the prior year. So if DIP1000 gets promoted to Edition 2025, then DIP1000 would be active by default in that edition and all subsequent editions without having to specifically enable it. I did bring up that this was likely to cause another "function attribute soup" problem, but in general I wholeheartedly agree C++ both do something similar so it would be conceptually comfortable to users coming from those languages. Atila, if you're reading this, this is what Walter was thinking/hoping would appear, but since we don't have your document we were mostly left to speculate. We await your document drop with anticipation! After that we had a discussion about how to distribute Phobos. This mostly centered on what release cadence to use. I argued for linking the Phobos version to the edition release schedule. I think this is sensible and makes it easier for people to reason about which compiler/library pairing they are using. Walter was fine with that, but he does not want to use the "Edition" language to describe Phobos releases. I think this makes sense as Phobos doesn't really have editions, but following SemVer, it would have yearly major releases. This would mean that new features are released once per year, and bugfixes would be released on whatever the fast-cadence schedule is for DMD in between Yearly Edition roll-ups. Finally, we touched briefly on the major changes we would like to see in Phobos 3 and these are the major changes we are committing to for Phobos 3 so far: - Removal of Autodecoding. - Promoting allocators out of experimental. - Range interface redesign (see JMD's thread [here](https://forum.dlang.org/thread/mailman.588.1705813271.3719.digitalmars-d puremagic.com)). - Fix std.traits. The above list is not exhaustive and we are open to further suggestions. For myself, I would love to see Cryptography and Stream API's make it into Phobos, but I am sure that the list of what the community wants to add is legion so those could end up being lower priority. One thing I would like to arrange if possible is planning sessions with the people involved with that specific change streamed to YouTube so that the community can participate via the Discord. If a person wishes to join the stream for a face-to-face discussion we would make the link available via DM. I found this discussion with Walter to be a much more efficient use of time and far more agreeable than writing long posts on the NG (the irony given the length of this post... I know). If you would like to participate in the design discussion on Phobos 3, I am currently hosting a repo on my GitHub with GH Discussions for unresolved/undesigned topics, and PR's for editing the actual design document. Link is here: https://github.com/LightBender/PhobosV3-Design
Feb 02
On Friday, 2 February 2024 at 09:09:37 UTC, Adam Wilson wrote:Walter and I had a productive conversation yesterday about Phobos 3 and we felt it would be appropriate to share some notes on our discussion. [...]What about the missing standard library pieces that are core to everyday software dev? Stuff you get out of the box with java/python. Is there such considerations beyond fixing the mistakes of v2? * Json * XML * Streams * Networking (http, socket, ...) .... If I understand correctly, v3 is about . How about new module additions to v3 such as the above?
Feb 02
On 03/02/2024 3:46 AM, aberba wrote:On Friday, 2 February 2024 at 09:09:37 UTC, Adam Wilson wrote:That is not part of the current work, although Adam does have a wish list and thoughts about it. Please note that Phobos is getting close enough to the 64k symbol limit on Windows that we cannot be expanding its scope. So the consideration of how to architect a new standard library must occur prior to work on it. Starting with something that isn't just a wish list is right. It isn't some library that we can chop and change on, its going to live for 20+ years so its going to have to be designed right.Walter and I had a productive conversation yesterday about Phobos 3 and we felt it would be appropriate to share some notes on our discussion. [...]What about the missing standard library pieces that are core to everyday software dev? Stuff you get out of the box with java/python. Is there such considerations beyond fixing the mistakes of v2? * Json * XML * Streams * Networking (http, socket, ...) .... If I understand correctly, v3 is about . How about new module additions to v3 such as the above?
Feb 02
On Friday, 2 February 2024 at 15:08:37 UTC, Richard (Rikki) Andrew Cattermole wrote:On 03/02/2024 3:46 AM, aberba wrote:I understand what you're saying however it doesn't necessarily mean "adding" to existing code. I think a lot of the old legacy stuff should be removed from new std.[...]That is not part of the current work, although Adam does have a wish list and thoughts about it. Please note that Phobos is getting close enough to the 64k symbol limit on Windows that we cannot be expanding its scope. So the consideration of how to architect a new standard library must occur prior to work on it. Starting with something that isn't just a wish list is right. It isn't some library that we can chop and change on, its going to live for 20+ years so its going to have to be designed right.
Feb 02
On 03/02/2024 6:48 AM, aberba wrote:On Friday, 2 February 2024 at 15:08:37 UTC, Richard (Rikki) Andrew Cattermole wrote:Oh it will need reviewing line by line prior to copying. So yeah that should be our default.On 03/02/2024 3:46 AM, aberba wrote:I understand what you're saying however it doesn't necessarily mean "adding" to existing code. I think a lot of the old legacy stuff should be removed from new std.[...]That is not part of the current work, although Adam does have a wish list and thoughts about it. Please note that Phobos is getting close enough to the 64k symbol limit on Windows that we cannot be expanding its scope. So the consideration of how to architect a new standard library must occur prior to work on it. Starting with something that isn't just a wish list is right. It isn't some library that we can chop and change on, its going to live for 20+ years so its going to have to be designed right.
Feb 02
On Friday, 2 February 2024 at 17:48:30 UTC, aberba wrote:On Friday, 2 February 2024 at 15:08:37 UTC, Richard (Rikki) Andrew Cattermole wrote:If you have a list of stuff that you think should be removed from Phobos, I am all ears. If you could start a discussion over in the repo that would be most helpful. https://github.com/LightBender/PhobosV3-Design/discussionsOn 03/02/2024 3:46 AM, aberba wrote:I understand what you're saying however it doesn't necessarily mean "adding" to existing code. I think a lot of the old legacy stuff should be removed from new std.[...]That is not part of the current work, although Adam does have a wish list and thoughts about it. Please note that Phobos is getting close enough to the 64k symbol limit on Windows that we cannot be expanding its scope. So the consideration of how to architect a new standard library must occur prior to work on it. Starting with something that isn't just a wish list is right. It isn't some library that we can chop and change on, its going to live for 20+ years so its going to have to be designed right.
Feb 02
On Friday, 2 February 2024 at 14:46:45 UTC, aberba wrote:What about the missing standard library pieces that are core to everyday software dev? Stuff you get out of the box with java/python. Is there such considerations beyond fixing the mistakes of v2? * Json * XML * Streams * Networking (http, socket, ...) .... If I understand correctly, v3 is about . How about new module additions to v3 such as the above?The above list are all things that I would love to see make it in to Phobos 3. The reason that I haven't put them down as commitments is because, as Rikki noted, the present design does not yet allow us to make those commitments yet. The multi-root design I've proposed would allow us to deliver them without breaking Windows, but my campaign to get it accepted hasn't been approved yet. And you did hit on an important point though, the things that we are looking at adding are cross-cutting concerns that are applicable to a wide variety of software and that's the guideline we're going to follow moving forward.
Feb 02
On Friday, 2 February 2024 at 14:46:45 UTC, aberba wrote:On Friday, 2 February 2024 at 09:09:37 UTC, Adam Wilson wrote:A better solution would be something like this: ``` dub dxml; void main() { // Call functions from the dxml package } ``` The compiler would know about certain popular packages on code.dlang.org. It would download the package if needed, and it would know where to find the relevant files. There are good reasons to not add that stuff to Phobos. The standard to get something in Phobos is high enough that it leads to a lot of wasted time for many people, it doesn't bloat the compiler download size, it takes advantage of work that's already been done, and it could be done quickly, rather than the years it takes to get stuff done otherwise. (I'm writing this fully aware of how things get done around here, but I'm going to put it out there anyway.)Walter and I had a productive conversation yesterday about Phobos 3 and we felt it would be appropriate to share some notes on our discussion. [...]What about the missing standard library pieces that are core to everyday software dev? Stuff you get out of the box with java/python. Is there such considerations beyond fixing the mistakes of v2? * Json * XML * Streams * Networking (http, socket, ...) .... If I understand correctly, v3 is about . How about new module additions to v3 such as the above?
Feb 02
On Friday, 2 February 2024 at 16:46:29 UTC, Lance Bachmeier wrote:On Friday, 2 February 2024 at 14:46:45 UTC, aberba wrote:You think dub should be integrated into the language?[...]A better solution would be something like this: ``` dub dxml; [...]
Feb 02
On Friday, 2 February 2024 at 18:03:32 UTC, jmh530 wrote:On Friday, 2 February 2024 at 16:46:29 UTC, Lance Bachmeier wrote:It wouldn't be necessary. The compiler would only have to know how to download the source files of a Dub package if they're not currently available. Other than that, there'd be no difference to the compiler/language between this and the `import std.whatever` statements we use right now.On Friday, 2 February 2024 at 14:46:45 UTC, aberba wrote:You think dub should be integrated into the language?[...]A better solution would be something like this: ``` dub dxml; [...]
Feb 02
On Friday, 2 February 2024 at 16:46:29 UTC, Lance Bachmeier wrote:On Friday, 2 February 2024 at 14:46:45 UTC, aberba wrote: A better solution would be something like this: ``` dub dxml; void main() { // Call functions from the dxml package } ``` The compiler would know about certain popular packages on code.dlang.org. It would download the package if needed, and it would know where to find the relevant files.I cannot argue strenuously enough against putting the packaging system in to the compiler directly. Not only will it balloon the build times by orders of magnitude, it is a serious violation of separation-of-concerns. The compiler should concern itself with compiling code and nothing else. The compiler is the wrong place to be handling third-party packages, that is properly the venue of the build system.There are good reasons to not add that stuff to Phobos. The standard to get something in Phobos is high enough that it leads to a lot of wasted time for many people, it doesn't bloat the compiler download size, it takes advantage of work that's already been done, and it could be done quickly, rather than the years it takes to get stuff done otherwise. (I'm writing this fully aware of how things get done around here, but I'm going to put it out there anyway.)People always say there are good reasons, but are light on actual reasons. Saying that Phobos has a high bar is not itself a reason so much as an excuse to not make the effort. In any case, I have a slightly different philosophy around PR's. I do not consider bikeshedding over formatting and other trivia to be a valid reason to delay a PR. I've posted about this elsewhere. If your code passes it's tests, delivers what it says it delivers, and helps us achieve our stated goals for the release, it goes in. Will bugs escape, sure, bugs escaping is normal, but I find our habit of using bikeshedding to stall out PRs we don't agree with to be rather odious. Merge buttons exist to prevent people from tying up PR's in bureaucratic nonsense. I intend to push them. Furthermore, if you disagree with how a PR does something that is non-trivial, either offer up a competing PR or remain silent. If you do not offer up a competing PR then we will assume that you are either not as concerned as your comments make you sound, or you are not actually sure that your solution is better. In either case, you can always submit a PR to improve upon the original PR. PR's are free, let's make more of them. Under my watch (if the community doesn't kick me out) Phobos will move faster. And yes, there might even be more bugs that escape. My plan is to use the monthly(Atila?) releases between the major roll-up releases mentioned in my original post to catch them before they get to the wider population.
Feb 02
On Friday, 2 February 2024 at 18:57:48 UTC, Adam Wilson wrote:On Friday, 2 February 2024 at 16:46:29 UTC, Lance Bachmeier wrote:I responded to the other comment, but I'll give the same answer. What I'm proposing doesn't have anything to do with the packaging system, Dub, or any of that. The only thing the compiler would have to know is how to download the source files of a package if they haven't already been downloaded.On Friday, 2 February 2024 at 14:46:45 UTC, aberba wrote: A better solution would be something like this: ``` dub dxml; void main() { // Call functions from the dxml package } ``` The compiler would know about certain popular packages on code.dlang.org. It would download the package if needed, and it would know where to find the relevant files.I cannot argue strenuously enough against putting the packaging system in to the compiler directly. Not only will it balloon the build times by orders of magnitude, it is a serious violation of separation-of-concerns. The compiler should concern itself with compiling code and nothing else. The compiler is the wrong place to be handling third-party packages, that is properly the venue of the build system.A sufficient reason is that I know how things get done around here, and an updated Phobos with these additions will optimistically be released in 2032. Most of the work has already been done. Why not reuse it? It's been eight months since I proposed a simple solution to the problem that library writers have to support too many compiler releases. Label some compiler releases as not being supported by library writers. It would have solved the problem fully and it could have been done by the end of the day. Obviously we couldn't do that. Instead we got editions. Eight months later, we still don't have an initial proposal, and the problem for library writers continues.There are good reasons to not add that stuff to Phobos. The standard to get something in Phobos is high enough that it leads to a lot of wasted time for many people, it doesn't bloat the compiler download size, it takes advantage of work that's already been done, and it could be done quickly, rather than the years it takes to get stuff done otherwise. (I'm writing this fully aware of how things get done around here, but I'm going to put it out there anyway.)People always say there are good reasons, but are light on actual reasons. Saying that Phobos has a high bar is not itself a reason so much as an excuse to not make the effort.Under my watch (if the community doesn't kick me out) Phobos will move faster. And yes, there might even be more bugs that escape. My plan is to use the monthly(Atila?) releases between the major roll-up releases mentioned in my original post to catch them before they get to the wider population.I hope that's true. It's hard to change the culture of any organization, especially one built on volunteer labor.
Feb 02
On Friday, 2 February 2024 at 19:39:34 UTC, Lance Bachmeier wrote:A sufficient reason is that I know how things get done around here, and an updated Phobos with these additions will optimistically be released in 2032. Most of the work has already been done. Why not reuse it?If I'm not mistaken Go has this for over 10 years now. I'm not aware of any other language/ecosystem that followed this.
Feb 02
On Friday, 2 February 2024 at 19:39:34 UTC, Lance Bachmeier wrote:On Friday, 2 February 2024 at 18:57:48 UTC, Adam Wilson wrote:But that's not true is it? How does it know which versions of the package are acceptable? Which of the acceptable versions does it pull? How does it handle the packages' dependencies? You simply cannot have the compiler pull a package without going through the entire dependency resolution process. Which means you're building DUB into DMD. Compilers are not package managers. I've asked Walter about this idea before and the reception was ... not positive, so probably best to just drop it.I cannot argue strenuously enough against putting the packaging system in to the compiler directly. Not only will it balloon the build times by orders of magnitude, it is a serious violation of separation-of-concerns. The compiler should concern itself with compiling code and nothing else. The compiler is the wrong place to be handling third-party packages, that is properly the venue of the build system.I responded to the other comment, but I'll give the same answer. What I'm proposing doesn't have anything to do with the packaging system, Dub, or any of that. The only thing the compiler would have to know is how to download the source files of a package if they haven't already been downloaded.That's not a reason. You're saying that you know what the reason is, that you're not going to state the reason, but that your special knowledge is so perfect that you can confidently state a ridiculous timeline as fact? I would suggest that you might want to consider how superlatively arrogant that sounds. DConf 2024 is probably a stretch, but sometime in 2025 is probably realistic, unless the money floodgates open and time can be purchased, but I'm not holding my breath for that outcome.People always say there are good reasons, but are light on actual reasons. Saying that Phobos has a high bar is not itself a reason so much as an excuse to not make the effort.A sufficient reason is that I know how things get done around here, and an updated Phobos with these additions will optimistically be released in 2032. Most of the work has already been done. Why not reuse it?It's been eight months since I proposed a simple solution to the problem that library writers have to support too many compiler releases. Label some compiler releases as not being supported by library writers. It would have solved the problem fully and it could have been done by the end of the day. Obviously we couldn't do that. Instead we got editions. Eight months later, we still don't have an initial proposal, and the problem for library writers continues.That is pretty much where this is going to end. Walter and I discussed tying Phobos releases to Compiler Editions, and he was amenable to the idea, his only sticking point was to not use "Editions" to describe Phobos, and "Versions" or "Releases" works just fine for our purposes. I would expect to see Phobos 3 land with the first Edition. Both of which I would expect in 2025. I am sorry to hear that it's not getting there as fast as you want it to, but that is the nature of volunteer projects, so unless you're willing to step up and help out, it's going to happen at pretty much whatever pace the rest of us can afford. But don't expect much sympathy when you're whining about a problem you're not doing anything to help solve.Yes and no, so long as the primary volunteers working on a specific piece stay the same then yes, expect similar results. But change out the personnel and I would expect the results to change. This is also true in a for-profit corp, but to a lesser degree, as volunteers are usually far less restricted by onerous policies. If I run Phobos development, I will run it differently. Walter has asked that I not go crazy, but so far everything I've talked about has been met with some variant of "that's ... different" so skepticism yes, but so far Walter and the DLF have been willing to extend me that latitude.Under my watch (if the community doesn't kick me out) Phobos will move faster. And yes, there might even be more bugs that escape. My plan is to use the monthly(Atila?) releases between the major roll-up releases mentioned in my original post to catch them before they get to the wider population.I hope that's true. It's hard to change the culture of any organization, especially one built on volunteer labor.
Feb 02
On Saturday, 3 February 2024 at 03:36:08 UTC, Adam Wilson wrote:On Friday, 2 February 2024 at 19:39:34 UTC, Lance Bachmeier wrote:It doesn't need to if only the most recent version as of the compiler release is supported.On Friday, 2 February 2024 at 18:57:48 UTC, Adam Wilson wrote:But that's not true is it? How does it know which versions of the package are acceptable?I cannot argue strenuously enough against putting the packaging system in to the compiler directly. Not only will it balloon the build times by orders of magnitude, it is a serious violation of separation-of-concerns. The compiler should concern itself with compiling code and nothing else. The compiler is the wrong place to be handling third-party packages, that is properly the venue of the build system.I responded to the other comment, but I'll give the same answer. What I'm proposing doesn't have anything to do with the packaging system, Dub, or any of that. The only thing the compiler would have to know is how to download the source files of a package if they haven't already been downloaded.Which of the acceptable versions does it pull?Answered above.How does it handle the packages' dependencies? You simply cannot have the compiler pull a package without going through the entire dependency resolution process.This is actually a non-issue for many packages on code.dlang.org. I've been downloading the D source files and putting them in my repos for years. I specified that this would be for some of the popular packages, not arbitrary packages.I actually listed multiple good reasons in my original comment, all of which you ignored, so I gave another.That's not a reason. You're saying that you know what the reason is, that you're not going to state the reason,People always say there are good reasons, but are light on actual reasons. Saying that Phobos has a high bar is not itself a reason so much as an excuse to not make the effort.A sufficient reason is that I know how things get done around here, and an updated Phobos with these additions will optimistically be released in 2032. Most of the work has already been done. Why not reuse it?This...doesn't make sense. There was a complaint that library writers have to support too many compiler releases. Well, that's an easy problem to solve, which the open source world has used for decades. Just say "we only support releases X and Y". I even gave examples. Wouldn't take any work at all, just a simple management decision, done. Now you're telling me I should just shut up because I'm not the one doing any of the work that doesn't need to be done? I give up.It's been eight months since I proposed a simple solution to the problem that library writers have to support too many compiler releases. Label some compiler releases as not being supported by library writers. It would have solved the problem fully and it could have been done by the end of the day. Obviously we couldn't do that. Instead we got editions. Eight months later, we still don't have an initial proposal, and the problem for library writers continues.That is pretty much where this is going to end. Walter and I discussed tying Phobos releases to Compiler Editions, and he was amenable to the idea, his only sticking point was to not use "Editions" to describe Phobos, and "Versions" or "Releases" works just fine for our purposes. I would expect to see Phobos 3 land with the first Edition. Both of which I would expect in 2025. I am sorry to hear that it's not getting there as fast as you want it to, but that is the nature of volunteer projects, so unless you're willing to step up and help out, it's going to happen at pretty much whatever pace the rest of us can afford. But don't expect much sympathy when you're whining about a problem you're not doing anything to help solve.
Feb 03
On Saturday, 3 February 2024 at 19:08:34 UTC, Lance Bachmeier wrote:It doesn't need to if only the most recent version as of the compiler release is supported.This makes a number of assumptions about both the package itself and is inherently limiting. Problems: 1. Updating a package for security/bugs/etc. now requires a compiler update. 2. Chicken-egg problems. Compiler makes breaking change that breaks the package, but the package maintainer cannot update the package until after the compiler has shipped. Therefore the package, and all of it's users, are broken for an entire release cycle. This could theoretically be solved with extremely tight coordination with package maintainers, but nothing in D's history suggests that there is even a remote possibility of this occurring on even a semi-repeatable basis. The package maintainers are volunteers too, if they miss the deadline, broken code ships and people yell at us for shipping broken code. 3. More chicken-egg problems. The syntax you propose implies the execution of DUB in the background. OK, but DUB is built with DMD, so by this design, you need DUB to pull a Phobos package to build DUB. Yes, there are bootstrapping designs, but ask Iain or Kinke about the bootstrapping rules for GCC or LLVM some time, they are highly restrictive. 4. Enforces the use of DUB, no other tool/package system can be built or substituted without changing the compiler syntax. D has a relatively diverse build tool ecosystem, are we telling them to just go pound sand? 5. Not all packages conform to Phobos' standards. Many gc-allocate heavily, or use exceptions, etc. By doing this we are explicitly telling entire groups of the D userspace that chunks of Phobos aren't for them, but that we can't easily tell them which chunks those are because we don't control them, so now they have to go lobby individual maintainers to support them. The screaming about Phobos' problems are loud enough without inviting even more trouble by pulling in packages that were never intended or designed to be held to Phobos' standards. And this doesn't address the fact that the first thing the community will ask for is the ability to specify package versions. I can hear Atila (Mr. Build-Speed himself) warming up his fingers from here for an explanation as to why any one of the above four problems make this idea untenable. But all five make it a complete non-starter with everybody who maintains the compiler. I submit that there are more useful ways to expend energy than pining for something that is simply never going to happen.This is actually a non-issue for many packages on code.dlang.org. I've been downloading the D source files and putting them in my repos for years. I specified that this would be for some of the popular packages, not arbitrary packages.This implies that there are design constraints on the package then (no dependencies?), correct?I actually listed multiple good reasons in my original comment, all of which you ignored, so I gave another.You have correctly pointed out that I did not do a point-by-point answer to your claims so here you go. (Relevant snippet below with responses interspersed)There are good reasons to not add that stuff to Phobos.I disagree, expanding Phobos expands the range of software that can be built without needing DUB, thus expanding the capabilities of software that can be built where DUB is unavailable or untenable, while avoiding the problems listed above.The standard to get something in Phobos is high enough that it leads to a lot of wasted time for many people,It is high, and there is a good reason for that. Phobos has to work everywhere, it has to meet a broad variety of use case, and user environments. I do agree that there are adjustments that could be made. For example, we tend to spend a lot of time on unnecessary bikeshedding and in some cases bikeshedding is used to intentionally stall out PRs. So one change than can be made is to focus on more qualitative reviews and not allow bikeshedding to stall a PR. Another, more controversial, change that I've been considering proposing, but know is going to receive considerable resistance, is allowing PR's that do not fulfill all the environmental rules (like not using the GC or using exceptions) to pass and then inviting others to modify the code to fit those rules. This is a deeply controversial idea and the debates I've had that only nibble at the edges of it have been ... emotional.it doesn't bloat the compiler download size,Just how much does the library code add to the download though? Most of the download size in the binaries, not the library code. Assuming an atrocious 5:1 text-compression ratio we would have to add 10MB of code to add just 2MB of download size. For reference, Phobos V 2.106 is 12.6MB on my NTFS partition. We could triple the capability of the standard library for the cost of an additional 4MB on a 32MB installer. In this modern era of Cable/DSL/Fiber I fail to see how an additional megabyte or two of download size is a serious concern, especially since 10-20MB of library code is a serious amount of additional utility that would be available OOTB.it takes advantage of work that's already been done,This is true, but is the work that's been done of the quality we want to ship as a top-line package? Does it follow the standards and idioms that the users of Phobos are used too?and it could be done quickly, rather than the years it takes to get stuff done otherwise.This is likely untrue. First, even using DUB as an external executable, you still need to teach DMD how to execute DUB and parse the `dub -v` output. That is a non-trivial amount of work. And we would have to figure out how this interacts with traditional `dub` project files (if two different versions are specified, what happens? The interactions are non-trivial and will require significant amount of code and testing of the compiler. Then you have to teach the library which packages are acceptable and manually maintain lists of versions match which compilers.This...doesn't make sense. There was a complaint that library writers have to support too many compiler releases. Well, that's an easy problem to solve, which the open source world has used for decades. Just say "we only support releases X and Y". I even gave examples. Wouldn't take any work at all, just a simple management decision, done. Now you're telling me I should just shut up because I'm not the one doing any of the work that doesn't need to be done? I give up.As I pointed out above, there is in fact significant work that would need to be done.
Feb 03
On Friday, 2 February 2024 at 09:09:37 UTC, Adam Wilson wrote:When then moved on to a conversation about how Walter envisions editions actually working. Since none of have seen the document that Atila is working on, Walter shared his opinions on how it should work. [...] [...] Atila, if you're reading this, this is what Walter was thinking/hoping would appear, but since we don't have your document we were mostly left to speculate. We await your document drop with anticipation!Why isn't Atila's document stored in a respository or shared drive somewhere that Walter has read access to? I understand not wanting to release it to the public before it's ready, but the fact that even the two leaders of the D project are forced to *guess* what the other is working on is completely ridiculous. The good news is that this is a really easy problem to solve. If setting up a private Github repository and pushing to it is too much effort, even something as simple as using Google docs would work.If you would like to participate in the design discussion on Phobos 3, I am currently hosting a repo on my GitHub with GH Discussions for unresolved/undesigned topics, and PR's for editing the actual design document. Link is here: https://github.com/LightBender/PhobosV3-DesignGreat to see. Is there a plan to update this repository and/or its Discussions page to reflect the material covered in this post? If not, how can I volunteer to help make that happen?
Feb 02
On Friday, 2 February 2024 at 16:46:08 UTC, Paul Backus wrote:On Friday, 2 February 2024 at 09:09:37 UTC, Adam Wilson wrote:Probably because reaching for GitHub is not how people think-by-default when thinking about a document. I only stumbled to it because Walter sent me a markdown document for his Phobos 3 ideas and that randomly triggered the connection in my head. I agree that the present situation is less than ideal, but it's what we've got to work with.When then moved on to a conversation about how Walter envisions editions actually working. Since none of have seen the document that Atila is working on, Walter shared his opinions on how it should work. [...] [...] Atila, if you're reading this, this is what Walter was thinking/hoping would appear, but since we don't have your document we were mostly left to speculate. We await your document drop with anticipation!Why isn't Atila's document stored in a respository or shared drive somewhere that Walter has read access to? I understand not wanting to release it to the public before it's ready, but the fact that even the two leaders of the D project are forced to *guess* what the other is working on is completely ridiculous.The good news is that this is a really easy problem to solve. If setting up a private Github repository and pushing to it is too much effort, even something as simple as using Google docs would work.I merged two of the open PRs on the document last night based on the discussion. I have one more to do (DUB Only Builds) but I ran out of steam and needed to get some sleep. There is a discussion open on Versioned Roots, but I talked Walter out of that, so I will post updates there and I have opened a PR to my proposed multi-root design here: https://github.com/LightBender/PhobosV3-Design/pull/3 but I need to update it on the basis of the discussion. Time is, as always, in short supply. If you have ideas about the general design that aren't fully formed or need to debated please open up a new Discussion (if I need some form of access let me know, this is my first time using Discussions). If you have a specific change proposal to the document please open up a PR and we'll discuss it in the Review comments.If you would like to participate in the design discussion on Phobos 3, I am currently hosting a repo on my GitHub with GH Discussions for unresolved/undesigned topics, and PR's for editing the actual design document. Link is here: https://github.com/LightBender/PhobosV3-DesignGreat to see. Is there a plan to update this repository and/or its Discussions page to reflect the material covered in this post? If not, how can I volunteer to help make that happen?
Feb 02
Concerning allocators, needs a simpler API in `core.memory`, without assumptions and without typeinfo, so libraries can depend on it from bare metal to higher level desktop applications, i dream of a way to change the associated array's allocator for a custom one for example The one in `std.experimental` is too over engineered to depend on it Concerning `std.traits` is this package really needed? perhaps work should go in improving `__traits` instead? I agree with aberba, i view the STD as building blocks for your program, instead of just utility functions, `std.net` `std.event` `std.container` `std.database` etc Hence i view the "fix std.traits` a waste of time, at least for a Phobos 3 work To me Phobos 3 should be an opportunity to make D's std competitive with other language's std, `std.net` shouldn't be a binding to curl for example, and if that's not in phobos 3's goals, then what's the point? Too many people asking how to ship with curl on windows.. that shouldn't be a problem when someone is using the language's std, it should just work
Feb 02
On 2/2/2024 1:09 AM, Adam Wilson wrote:Finally, we touched briefly on the major changes we would like to see in Phobos 3 and these are the major changes we are committing to for Phobos 3 so far: - Removal of Autodecoding. - Promoting allocators out of experimental. - Range interface redesign (see JMD's thread [here](https://forum.dlang.org/thread/mailman.588.1705813271.3719.digitalmars-d puremagic.com)). - Fix std.traits.- Drop all support for wchar and dchar from the templates. Instead, use the adaptors from std.utf to convert wchar/dchar to/from char.
Feb 02
On Friday, 2 February 2024 at 09:09:37 UTC, Adam Wilson wrote:Walter and I had a productive conversation yesterday about Phobos 3 and we felt it would be appropriate to share some notes on our discussion. [snip]When it comes to discussions around functions that allocate to the heap, I think there is some benefit in implementing lower-level functionality in functions that do not do any allocations whatsoever. You can then have higher level API above that that controls allocation and is more convenient to use. That way users can opt in to whatever they want or write their own more convenient API on top of the lower level functions. May not work for everything, but could be a useful approach.
Feb 02
On Friday, 2 February 2024 at 18:19:47 UTC, jmh530 wrote:On Friday, 2 February 2024 at 09:09:37 UTC, Adam Wilson wrote:It may be still a bad solution. Countless times I have done functions which know how much to preallocate. The eager solution always seems to be a lot faster, and I have noticed the pattern of using `map` or `filter` or anything more + `.array` looking to infinitely slower than if you had a direct version. And I don't know about `release` versions. The thing is that 99% of the time I'm testing on debug builds and getting less speed only because I'm on debug looks really bad. This should be addressed.Walter and I had a productive conversation yesterday about Phobos 3 and we felt it would be appropriate to share some notes on our discussion. [snip]When it comes to discussions around functions that allocate to the heap, I think there is some benefit in implementing lower-level functionality in functions that do not do any allocations whatsoever. You can then have higher level API above that that controls allocation and is more convenient to use. That way users can opt in to whatever they want or write their own more convenient API on top of the lower level functions. May not work for everything, but could be a useful approach.
Feb 02
On Friday, 2 February 2024 at 18:39:33 UTC, Hipreme wrote:On Friday, 2 February 2024 at 18:19:47 UTC, jmh530 wrote:The work I’ve been doing is related to linear algebra. Nothing really lazy or map-like. For instance, think of it like dgemm doing matrix multiplication without doing any allocations. It takes a pointer to the result matrix as an input and requires information about how if that will be. A higher level D version could work in terms of slices so that the API is cleaner. A higher level API could handle the case where the result is allocated with GC.On Friday, 2 February 2024 at 09:09:37 UTC, Adam Wilson wrote:It may be still a bad solution. Countless times I have done functions which know how much to preallocate. The eager solution always seems to be a lot faster, and I have noticed the pattern of using `map` or `filter` or anything more + `.array` looking to infinitely slower than if you had a direct version. And I don't know about `release` versions. The thing is that 99% of the time I'm testing on debug builds and getting less speed only because I'm on debug looks really bad.Walter and I had a productive conversation yesterday about Phobos 3 and we felt it would be appropriate to share some notes on our discussion. [snip]When it comes to discussions around functions that allocate to the heap, I think there is some benefit in implementing lower-level functionality in functions that do not do any allocations whatsoever. You can then have higher level API above that that controls allocation and is more convenient to use. That way users can opt in to whatever they want or write their own more convenient API on top of the lower level functions. May not work for everything, but could be a useful approach.
Feb 04
On Friday, February 2, 2024 11:19:47 AM MST jmh530 via Digitalmars-d wrote:On Friday, 2 February 2024 at 09:09:37 UTC, Adam Wilson wrote:That's certainly the approach that I think that we should be taking for a number of things (and to an extent, it's what Phobos already does with some stuff - just not everywhere). There are plenty of cases where if you really want something user-friendly, you need to be giving fewer options and just allocating stuff on the heap, but it often makes perfect sense to build that on top of much less user-friendly stuff that provides more functionality for those who really need it. This is exactly the approach that I've taken with my socket library that I need to finish one of these days. It provides a low-level API using structs and nogc, whereas for higher level socket stuff (e.g. code that needs to operate on sockets without caring whether they're using SSL/TLS or not), you're almost certainly going to want classes - and you're definitely going to want stuff on the heap given the need to do stuff like point to sockets on other threads to close them. A much simpler example of this sort of thing that we already have in Phobos is range-based functions vs array functions - e.g. splitter vs split. The range-based ones are much more flexible, and they typically don't allocate (though in some cases might due to closures), but they're also much more verbose when you actually want to operate on arrays, since then you end up with calls to array all over the place, and you potentially lose out on optimization opportunites for those cases where an algorithm can be implemented more efficiently for an array. So, by having both, you have the option to avoid the allocations and work with a wider range of types - or you can use the array-specific version when you don't need those extra capabilities. - Jonathan M DavisWalter and I had a productive conversation yesterday about Phobos 3 and we felt it would be appropriate to share some notes on our discussion. [snip]When it comes to discussions around functions that allocate to the heap, I think there is some benefit in implementing lower-level functionality in functions that do not do any allocations whatsoever. You can then have higher level API above that that controls allocation and is more convenient to use. That way users can opt in to whatever they want or write their own more convenient API on top of the lower level functions. May not work for everything, but could be a useful approach.
Feb 02
On Friday, 2 February 2024 at 09:09:37 UTC, Adam Wilson wrote:Finally, we touched briefly on the major changes we would like to see in Phobos 3 and these are the major changes we are committing to for Phobos 3 so far: - Range interface redesignhttps://forum.dlang.org/thread/ghsihtmlurzsuslyzgnv forum.dlang.org
Feb 02
On Friday, 2 February 2024 at 09:09:37 UTC, Adam Wilson wrote:First, it would be very easy to accidentally type `std.` in an `std2.` module. We realized that this would be a problem no matter what root name was used and that the appropriate answer would be to specify a DStyle rule specific to Phobos that only modules in `std.` can import `std.` modules.What about std.v1.*, std.v2.* and so on? And obviously std.v1.* == std.*Therefore, the compiler should default to use the latest version and then provide the ability via a switch to set the edition, or lack thereof, of the modules an import path. This solves the problem of abandon-ware packages being accessible without presenting the new user with an ever more decayed version of the compiler. We want to put out best foot forward and presenting the last pre-editions release, which is constantly getting old as time passes, does not do that. No specific agreement was reached but Walter agreed to consider it.Is the newest compiler compatible with oldest phobos? Maybe some sort of automagical import std.old.v108;After that we had a discussion about how to distribute Phobos. This mostly centered on what release cadence to use. I argued for linking the Phobos version to the edition release schedule. I think this is sensible and makes it easier for people to reason about which compiler/library pairing they are using. Walter was fine with that, but he does not want to use the "Edition" language to describe Phobos releases. I think this makes sense as Phobos doesn't really have editions, but following SemVer, it would have yearly major releases. This would mean that new features are released once per year, and bugfixes would be released on whatever the fast-cadence schedule is for DMD in between Yearly Edition roll-ups.Can phobos and dmd split themselves, just like any other library, or are we supposed to keep them together?Finally, we touched briefly on the major changes we would like to see in Phobos 3 and these are the major changes we are committing to for Phobos 3 so far: - Removal of Autodecoding.+1- Promoting allocators out of experimental.+1- Range interface redesign+1- Fix std.traits.+1 - Removing ext dependencies could make things easier (f.e. libcurl) for multi-platform development (it's nice to statically compile everything in a single executable, but it's not that easy: I did it for https://github.com/trikko/tshare) - Phobos with webassembly - Phobos with betterC Andrea
Feb 02
On Friday, 2 February 2024 at 21:11:51 UTC, Andrea Fontana wrote:On Friday, 2 February 2024 at 09:09:37 UTC, Adam Wilson wrote:This hasn't been fully decided yet, and I probably need to have a chat with Atila so we can sort out some of the practical issues. But what I am pushing for is tying Phobos versions to matching editions. Example: Phobos 3 == Edition 2025 (2024?), Phobos 4 == Edition 2026, etc. The plan as I understand it is that Phobos 3 code can be built with later editions. So the "Edition 2025" is a minimum supported edition level.First, it would be very easy to accidentally type `std.` in an `std2.` module. We realized that this would be a problem no matter what root name was used and that the appropriate answer would be to specify a DStyle rule specific to Phobos that only modules in `std.` can import `std.` modules.What about std.v1.*, std.v2.* and so on? And obviously std.v1.* == std.*Therefore, the compiler should default to use the latest version and then provide the ability via a switch to set the edition, or lack thereof, of the modules an import path. This solves the problem of abandon-ware packages being accessible without presenting the new user with an ever more decayed version of the compiler. We want to put out best foot forward and presenting the last pre-editions release, which is constantly getting old as time passes, does not do that. No specific agreement was reached but Walter agreed to consider it.Is the newest compiler compatible with oldest phobos? Maybe some sort of automagical import std.old.v108;I've heard rumors about going mono-repo. But for the moment they are in separate repos, and the initial Phobos 3 development will likely be done in a separate repo to avoid waiting on and conflicting with the primary development path. After that I would expect it to land in the same repo as Phobos 2.After that we had a discussion about how to distribute Phobos. This mostly centered on what release cadence to use. I argued for linking the Phobos version to the edition release schedule. I think this is sensible and makes it easier for people to reason about which compiler/library pairing they are using. Walter was fine with that, but he does not want to use the "Edition" language to describe Phobos releases. I think this makes sense as Phobos doesn't really have editions, but following SemVer, it would have yearly major releases. This would mean that new features are released once per year, and bugfixes would be released on whatever the fast-cadence schedule is for DMD in between Yearly Edition roll-ups.Can phobos and dmd split themselves, just like any other library, or are we supposed to keep them together?Easier said that done, because the one thing you cannot do without an external library is cryptography, and if the advice is to just use OpenSSL, we would be better served telling them to skip that entirely and just check themselves into a mental institution directly (I implemented crypto using OpenSSL, AMA). Specific to libcurl I think we should use the built-in sockets, but this requires a bunch of work from JMD, who is also heading up ranges. We have a lot of work and few people to help, so we have to be judicious here, and C libraries via ImportC offer an appealing amount of leverage.Finally, we touched briefly on the major changes we would like to see in Phobos 3 and these are the major changes we are committing to for Phobos 3 so far: - Removal of Autodecoding.+1- Promoting allocators out of experimental.+1- Range interface redesign+1- Fix std.traits.+1 - Removing ext dependencies could make things easier (f.e. libcurl) for multi-platform development (it's nice to statically compile everything in a single executable, but it's not that easy: I did it for https://github.com/trikko/tshare)- Phobos with webassemblyThis is mostly a DMD/DRT problem. The big hang-up with WASM has been that WASM only recently got GC support and the current compiler integrations haven't been updated to support, it you want to help out with that, look for a call for volunteers from Mike Parker some time in the near future. WASM is pretty high up the priority list.- Phobos with betterCThis is not in the cards. BetterC would seriously constrain the capability of Phobos as we expect to support TypeInfo/ModuleInfo, threading, Dynamic/Associative arrays, and static module constructors/destructors.Andrea
Feb 02
On Saturday, 3 February 2024 at 03:49:54 UTC, Adam Wilson wrote:What typeinfo/moduleinfo has to do with a networking module in the STD for example? Dynamic array/associative array can be made to work with -betterC, i mentioned in my reply above, minimal allocator API in `core.memory` make associative array able to change its allocator, and build APIs in phobos around allocators and people who use betterC will be able to consume phobos without people working on phobos having to know/care about betterC If you care about simplicity and efficiency, obviously- Phobos with betterCThis is not in the cards. BetterC would seriously constrain the capability of Phobos as we expect to support TypeInfo/ModuleInfo, threading, Dynamic/Associative arrays, and static module constructors/destructors.Andrea
Feb 03
On Saturday, 3 February 2024 at 11:53:05 UTC, ryuukk_ wrote:On Saturday, 3 February 2024 at 03:49:54 UTC, Adam Wilson wrote:Oh, and Exception Handling? Get in native tuple and tagged union in the language, and you'll be able to build nice error handling code I hope no EH in Phobos 3What typeinfo/moduleinfo has to do with a networking module in the STD for example? Dynamic array/associative array can be made to work with -betterC, i mentioned in my reply above, minimal allocator API in `core.memory` make associative array able to change its allocator, and build APIs in phobos around allocators and people who use betterC will be able to consume phobos without people working on phobos having to know/care about betterC If you care about simplicity and efficiency, obviously- Phobos with betterCThis is not in the cards. BetterC would seriously constrain the capability of Phobos as we expect to support TypeInfo/ModuleInfo, threading, Dynamic/Associative arrays, and static module constructors/destructors.Andrea
Feb 03
On Saturday, 3 February 2024 at 11:54:48 UTC, ryuukk_ wrote:Oh, and Exception Handling? Get in native tuple and tagged union in the language, and you'll be able to build nice error handling code I hope no EH in Phobos 3Existing try catch syntax could be improved to support tagged union you've mentioned btw. Compiler then would inject extra code on each statement that returns a tagged union to automatically forward to appropriate catch clause, if an exception is returned from said statement.
Feb 03
On 04/02/2024 1:40 AM, Alexandru Ermicioi wrote:On Saturday, 3 February 2024 at 11:54:48 UTC, ryuukk_ wrote:Yes it is well known that we want a different exception handling implementation in addition to the runtime one we have now. I suspect I should probably begin doing a write up on sum types. I'm not happy with Walter's design. It leaves some things out that are kinda needed to match the problem domain. https://github.com/rikkimax/DIPs/blob/value_type_exceptions/DIPs/DIP1xxx-RC.mdOh, and Exception Handling? Get in native tuple and tagged union in the language, and you'll be able to build nice error handling code I hope no EH in Phobos 3Existing try catch syntax could be improved to support tagged union you've mentioned btw. Compiler then would inject extra code on each statement that returns a tagged union to automatically forward to appropriate catch clause, if an exception is returned from said statement.
Feb 03
On Saturday, 3 February 2024 at 11:54:48 UTC, ryuukk_ wrote:Oh, and Exception Handling? Get in native tuple and tagged union in the language, and you'll be able to build nice error handling code I hope no EH in Phobos 3The EH problem has two potential answers. The first is the sumtype answer. That would be zero runtime cost and would achieve a similar result as the current EH scheme. The second is that, absent sumtype exceptions, Phobos will be designed to not use exceptions wherever possible. There will always be cases where exceptions are needed so we can't entirely rule them out, but any time one is added it will require some serious justification. This goes back to not wanting to box ourselves into any tight corners or inferior designs in the name of slavishly attempting to a too-restrictive standard. Consider this potential problem, we completely eradicate EH in Phobos 3, create a number of less-than-ideal implementations, and then the next Edition of D drops with sumtype exceptions and now we have to go back and rebuild all those known inferior designs because EH became acceptable to the crowd again. It is better to build the best design up-front, pay a small penalty for it, then work on minimizing the penalty.
Feb 03
On Sunday, 4 February 2024 at 01:14:56 UTC, Adam Wilson wrote:On Saturday, 3 February 2024 at 11:54:48 UTC, ryuukk_ wrote:Three: copy Herb Sutter's idea.Oh, and Exception Handling? Get in native tuple and tagged union in the language, and you'll be able to build nice error handling code I hope no EH in Phobos 3The EH problem has two potential answers.The first is the sumtype answer. That would be zero runtime cost and would achieve a similar result as the current EH scheme.Not unless we solve the "bubbling up" issue to avoid pattern matching over and over again when none of the N functions in the call stack between `main` and the one "throwing" care. So far all I know of is Rust's `?` and monads.
Feb 05
On 06/02/2024 3:41 AM, Atila Neves wrote:The EH problem has two potential answers. Three: copy Herb Sutter's idea.Oh look, someone has already done it! https://github.com/rikkimax/DIPs/blob/value_type_exceptions/DIPs/DIP1xxx-RC.md
Feb 05
On Monday, 5 February 2024 at 15:45:36 UTC, Richard (Rikki) Andrew Cattermole wrote:On 06/02/2024 3:41 AM, Atila Neves wrote:Nice! How did I miss this??The EH problem has two potential answers. Three: copy Herb Sutter's idea.Oh look, someone has already done it! https://github.com/rikkimax/DIPs/blob/value_type_exceptions/DIPs/DIP1xxx-RC.md
Feb 05
On 06/02/2024 6:38 AM, Atila Neves wrote:On Monday, 5 February 2024 at 15:45:36 UTC, Richard (Rikki) Andrew Cattermole wrote:Probably because you weren't on Discord or reading any of my comments on the N.G. ;)On 06/02/2024 3:41 AM, Atila Neves wrote:Nice! How did I miss this??The EH problem has two potential answers. Three: copy Herb Sutter's idea.Oh look, someone has already done it! https://github.com/rikkimax/DIPs/blob/value_type_exceptions/DIPs/DIP1xxx-RC.md
Feb 05
On Saturday, 3 February 2024 at 03:49:54 UTC, Adam Wilson wrote:On Friday, 2 February 2024 at 21:11:51 UTC, Andrea Fontana wrote:Obviously we are not going to get all of Phobos to work with BetterC, but significant chunks of it already do, and there's a good deal more that could be considered low-hanging fruit. I think the right approach here is to try to make code BetterC-compatible when we can, and to at least keep BetterC compatibility in mind as a "nice-to-have" goal (but not a requirement) when doing API design. For example, if the only thing keeping a function from being BetterC-compatible is that it uses the GC to allocate memory for an error message, it's probably worth a little bit of extra effort to either get rid of that GC dependency, or provide a `version (D_BetterC)` alternative.- Phobos with betterCThis is not in the cards. BetterC would seriously constrain the capability of Phobos as we expect to support TypeInfo/ModuleInfo, threading, Dynamic/Associative arrays, and static module constructors/destructors.
Feb 03
On Saturday, 3 February 2024 at 12:53:34 UTC, Paul Backus wrote:Obviously we are not going to get all of Phobos to work with BetterC, but significant chunks of it already do, and there's a good deal more that could be considered low-hanging fruit. I think the right approach here is to try to make code BetterC-compatible when we can, and to at least keep BetterC compatibility in mind as a "nice-to-have" goal (but not a requirement) when doing API design. For example, if the only thing keeping a function from being BetterC-compatible is that it uses the GC to allocate memory for an error message, it's probably worth a little bit of extra effort to either get rid of that GC dependency, or provide a `version (D_BetterC)` alternative.This is the path that we're taking. We want to make Phobos as widely usable as possible, but there is a balancing act we have to perform. If we restrict the language features we allow ourselves to much, there are entire classes of capabilities we cannot deliver. BetterC is too much, for example, we wouldn't be able to use classes/interfaces or the GC where it's appropriate. JMD and I were talking about sockets and I think he came up with an interesting approach to this problem. He built a low-level API that is either BetterC compliant or very close to it, and then built a higher level API on top of that. The low-level API is painful to use but it allowed him to build the high-level API he wanted in a way that made sense. You can use the low-level API if you absolutely need that level of performance/control/etc, but most projects will find the high-level API to be sufficient for their needs. Perhaps this is a concept that we should investigate for other areas of Phobos?
Feb 03
On Sunday, 4 February 2024 at 01:01:28 UTC, Adam Wilson wrote:JMD and I were talking about sockets and I think he came up with an interesting approach to this problem. He built a low-level API that is either BetterC compliant or very close to it, and then built a higher level API on top of that. The low-level API is painful to use but it allowed him to build the high-level API he wanted in a way that made sense. You can use the low-level API if you absolutely need that level of performance/control/etc, but most projects will find the high-level API to be sufficient for their needs. Perhaps this is a concept that we should investigate for other areas of Phobos?Absolutely. A lot of things in Phobos unnecessarily use classes. I feel very strongly that V3 should go in the direction of using structs where possible, non-copyable/scoped/unique ones if needed.
Feb 05
On Saturday, 3 February 2024 at 12:53:34 UTC, Paul Backus wrote:On Saturday, 3 February 2024 at 03:49:54 UTC, Adam Wilson wrote:I think our goal is to make `-betterC` obsolete. As in: if you don't use the feature, you don't pay for it, and it's implicit.[...]Obviously we are not going to get all of Phobos to work with BetterC, but significant chunks of it already do, and there's a good deal more that could be considered low-hanging fruit. I think the right approach here is to try to make code BetterC-compatible when we can, and to at least keep BetterC compatibility in mind as a "nice-to-have" goal (but not a requirement) when doing API design. For example, if the only thing keeping a function from being BetterC-compatible is that it uses the GC to allocate memory for an error message, it's probably worth a little bit of extra effort to either get rid of that GC dependency, or provide a `version (D_BetterC)` alternative.
Feb 05
On Monday, 5 February 2024 at 14:38:56 UTC, Atila Neves wrote:I think our goal is to make `-betterC` obsolete. As in: if you don't use the feature, you don't pay for it, and it's implicit.Very nice.
Feb 05
On Monday, 5 February 2024 at 14:38:56 UTC, Atila Neves wrote:On Saturday, 3 February 2024 at 12:53:34 UTC, Paul Backus wrote:This is more of a goal for druntime than Phobos, but yes, agreed. Even in the 100% pay-as-you-go world, I think we'll still want Phobos APIs to avoid depending on (and paying for) more druntime features than they really need to.I think the right approach here is to try to make code BetterC-compatible when we can, and to at least keep BetterC compatibility in mind as a "nice-to-have" goal (but not a requirement) when doing API design. For example, if the only thing keeping a function from being BetterC-compatible is that it uses the GC to allocate memory for an error message, it's probably worth a little bit of extra effort to either get rid of that GC dependency, or provide a `version (D_BetterC)` alternative.I think our goal is to make `-betterC` obsolete. As in: if you don't use the feature, you don't pay for it, and it's implicit.
Feb 05
On Monday, 5 February 2024 at 15:40:11 UTC, Paul Backus wrote:On Monday, 5 February 2024 at 14:38:56 UTC, Atila Neves wrote:Yeah, that's a good point. For instance: not allocating for no reason, and leaving it up to the user instead. If they *want* to call `.array` on the result, that's up to them. Preferring "sink" `toString` implementations, that kind of thing.On Saturday, 3 February 2024 at 12:53:34 UTC, Paul Backus wrote:This is more of a goal for druntime than Phobos, but yes, agreed. Even in the 100% pay-as-you-go world, I think we'll still want Phobos APIs to avoid depending on (and paying for) more druntime features than they really need to.I think the right approach here is to try to make code BetterC-compatible when we can, and to at least keep BetterC compatibility in mind as a "nice-to-have" goal (but not a requirement) when doing API design. For example, if the only thing keeping a function from being BetterC-compatible is that it uses the GC to allocate memory for an error message, it's probably worth a little bit of extra effort to either get rid of that GC dependency, or provide a `version (D_BetterC)` alternative.I think our goal is to make `-betterC` obsolete. As in: if you don't use the feature, you don't pay for it, and it's implicit.
Feb 05
On Monday, 5 February 2024 at 15:40:11 UTC, Paul Backus wrote:This feels delusional to me; like I don't know how the formal style with its contracts and extra asserts and 5 layered datetime will ever avoid rogue imports that aren't part of a blessed compile environment. I have a wasm build script, feel free to test if any single function of any of the std can compile with libc.math imports t_time which isnt found with the broken wasm enverment. The current style leads to highly incestuous, overly reliant on long correct versions of code that just leads to a highly connected graph. I see no suggesting from any "pay-as-you-go std" advocate that isn't "we wil be more careful", "we will compile with more nogc" when I dont even know if it would work but a solution id see would need to make local imports only be allowed in templated code(so it actually functioned as pay as you go), drastically cutting back on complexity(no 500 line nullable and 100 line template contracts)I think our goal is to make `-betterC` obsolete. As in: if you don't use the feature, you don't pay for it, and it's implicit.Even in the 100% pay-as-you-go world, I think we'll still want Phobos APIs to avoid depending on (and paying for) more druntime features than they really need to.
Feb 05
On Monday, 5 February 2024 at 16:36:02 UTC, monkyyy wrote:On Monday, 5 February 2024 at 15:40:11 UTC, Paul Backus wrote:The way you avoid this stuff is by testing. Run your unit tests with `-betterC` and any accidental druntime dependencies you add will be revealed to you very quickly. The current version of Phobos was written before BetterC existed and is kind of lazy about testing in general, so it doesn't do this, but I'm hoping that will change with Phobos V3. I've tried to set an example with `std.sumtype`. Unlike every other module in Phobos, its unit tests are enabled in BetterC by default, and those that depend on druntime have to make this explicit by using a `version` condition.This feels delusional to me; like I don't know how the formal style with its contracts and extra asserts and 5 layered datetime will ever avoid rogue imports that aren't part of a blessed compile environment.I think our goal is to make `-betterC` obsolete. As in: if you don't use the feature, you don't pay for it, and it's implicit.Even in the 100% pay-as-you-go world, I think we'll still want Phobos APIs to avoid depending on (and paying for) more druntime features than they really need to.
Feb 05
On Monday, 5 February 2024 at 16:46:20 UTC, Paul Backus wrote:On Monday, 5 February 2024 at 16:36:02 UTC, monkyyy wrote:That just adds a singluar blessed environment, it will be very very unlikely that it will compile on wasm, a new embedded chip that releases in 2025, bsd, or a new rust os in 2040. Which is a potential option but it's not a mythical "pay-as-you-go" and then you'll see nogc avocates being like "oi I needed to import toStringz but your (algorthim thats 100x simplier with allocation) allocates and broke my code, because of a 9 long import chain of unused code" https://www.youtube.com/watch?v=a-767WnbaCQ "just do ___"; no we are not even close to the phase change point, I suggest someone needs an answer for how you reduce the fundamental "order"/R0 of imports, which I think is 2 imports per file, or being extremely strict about local imports being in templates so they dont compile if unusedOn Monday, 5 February 2024 at 15:40:11 UTC, Paul Backus wrote:The way you avoid this stuff is by testing. Run your unit tests with `-betterC` and any accidental druntime dependencies you add will be revealed to you very quickly.This feels delusional to me; like I don't know how the formal style with its contracts and extra asserts and 5 layered datetime will ever avoid rogue imports that aren't part of a blessed compile environment.I think our goal is to make `-betterC` obsolete. As in: if you don't use the feature, you don't pay for it, and it's implicit.Even in the 100% pay-as-you-go world, I think we'll still want Phobos APIs to avoid depending on (and paying for) more druntime features than they really need to.
Feb 05
On Mon, Feb 05, 2024 at 02:38:56PM +0000, Atila Neves via Digitalmars-d wrote: [...]I think our goal is to make `-betterC` obsolete. As in: if you don't use the feature, you don't pay for it, and it's implicit.+1, this is the right approach. T -- It said to install Windows 2000 or better, so I installed Linux instead.
Feb 05
On Friday, 2 February 2024 at 09:09:37 UTC, Adam Wilson wrote:Walter and I had a productive conversation yesterday about Phobos 3 and we felt it would be appropriate to share some notes on our discussion. [...]Will there be a plan to put Phobos 2 on life support and eventually sunset it? It doesn't make sense to support that forever.
Feb 02
On Friday, 2 February 2024 at 09:09:37 UTC, Adam Wilson wrote:Fix std.traitsCan you expand on this a bit more? I've contributed to std.traits in the past and would like to help improve it for Phobos v2.
Feb 04
On Sunday, February 4, 2024 2:07:44 AM MST Meta via Digitalmars-d wrote:On Friday, 2 February 2024 at 09:09:37 UTC, Adam Wilson wrote:The main thing that it needs IMHO is going through it and making sure that it's doing the right thing for each trait and that the exact set of traits that it has is really what we want, since right now, several of them are doing the wrong thing (e.g. treating enum as if it were its base type with stuff like isIntegral, isNumeric, etc., which is a source of bugs). The names also potentially need to be cleaned up, and it just needs to be looked over in general to make sure that it's really what we want. It's grown organically over the years, the current situation with D is not the same as when std.traits was started, and we've learned more since then, so the exact set of traits that we want to have in there likely should be adjusted now that we have an opportunity to essentially start from scratch with it. That being said, as I understand it, what initiated the idea to rework it as one of Phobos v3's priorities is that Walter doesn't understand traits like isSomeChar and finds them confusing, though I suspect that that's probably because he hasn't done much with them, if nothing else, because dmd doesn't use Phobos, and I would expect that it does a lot less with templated code than a lot of D code does, though I haven't dug through its code lately. I also get the impression that some folks just plain don't like what the module does, but given how D's template constraints work, we fundamentally need traits like it has even if the exact set that is in there needs work. There's also likely some debate to be had over std.traits vs __traits. On the whole, std.traits adds stuff on top of __traits, so plenty of folks use both, but part of the idea behind std.traits was to make it so that most code wouldn't need to use __traits. The advantage of that is that the result is cleaner code (since __traits tends to be pretty ugly), but it also means more template instantiations. So, I expect that there is going to be some disagreement on what we should be doing there (though there's no reason why we can't have traits in std.traits which simply wrap __traits stuff even if some folks want to use __traits directly as much as possible). But regardless, there are a number of things that std.traits tests that aren't in __traits. In any case, as things stand, I don't think there really is agreement on what should be done with std.traits, and deciding what exactly needs to happen with it is one of the things that we're going to need to figure out. - Jonathan M DavisFix std.traitsCan you expand on this a bit more? I've contributed to std.traits in the past and would like to help improve it for Phobos v2.
Feb 04
On Sunday, 4 February 2024 at 09:30:58 UTC, Jonathan M Davis wrote:So, I expect that there is going to be some disagreement on what we should be doing there (though there's no reason why we can't have traits in std.traits which simply wrap __traits stuff even if some folks want to use __traits directly as much as possible). But regardless, there are a number of things that std.traits tests that aren't in __traits. In any case, as things stand, I don't think there really is agreement on what should be done with std.traits, and deciding what exactly needs to happen with it is one of the things that we're going to need to figure out. - Jonathan M DavisOn Sunday, 4 February 2024 at 02:25:25 UTC, Adam Wilson wrote:D's feature has problem, and is annoying to use? Don't be like C++, don't bloat the std, fix the language STD should not be the place to fix language's shortcoming EH is evil, some platforms has banned it completly (apple), and application in Rust too, not just C++, it is an inferior design https://www.theregister.com/2024/01/31/microsoft_seeks_rust_developers/This goes back to not wanting to box ourselves into any tightcorners or inferior designs in the name of slavishly attempting to a too-restrictive standard. Consider this potential problem, we completely eradicate EH in Phobos 3, create a number of less-than-ideal implementations, and then the next Edition of D drops with sumtype exceptions and now we have to go back and rebuild all those known inferior designs because EH became acceptable to the crowd again.
Feb 04
On Sunday, February 4, 2024 3:13:39 AM MST ryuukk_ via Digitalmars-d wrote:EH is evil, some platforms has banned it completly (apple), and application in Rust too, not just C++, it is an inferior design https://www.theregister.com/2024/01/31/microsoft_seeks_rust_developers/A number of us do not agree with you, and I for one never will. For many situations, exceptions are by far the best error handling mechanism that there is. D's implementation of it could certainly use some improvements (e.g. while being able to have a hierarchy for exceptions is valuable, the fact that they're classes and thus have to be heap allocated is a problem for code that needs to avoid the GC), so it would be great if D's implementation for exceptions could be improved, but the basic concept is solid and makes a lot of code cleaner as a result (e.g. I'd never want to write a parser that didn't use exceptions; being able to separate the error handling code from the actual parsing makes the code _far_ cleaner and far less error-prone than any other error handling mechanism that I've ever encountered). Obviously, there are situations where exceptions are not appropriate (e.g. it was definitely a mistake to have Phobos decoding Unicode all of the place and potentially throw a UTFException from practically anywhere as a result), and any properly written library is going to have to be intelligent about when any particular error handling mechanism is used, but exceptions are far, far too useful to not use - especially when the main alternative is checking return values all over the place. So, while there are places that Phobos currently uses exceptions where it shouldn't, there are others where using them is very much the right thing to do IMHO, and I would use them again in the next version of Phobos (and argue strongly against anyone trying to not use them there), because if I didn't, the result would be worse code that was harder to use. In general, exceptions are best when 1. It's cleaner to assume that an operation will succeed, and it's reasonable to assume that it will succeed. Parsing is a great example of this. You're not going to do something like validate that an XML document is going to parse correctly and then parse it, since that would basically mean parsing it twice. You're just going to parse it and then report when that fails so that the caller can handle it. And exceptions make that very clean, because then you only have to have the one place at the top that catches the exception, and the rest of the code can just do its thing. The way that exceptions bubble up, allowing code along the way to completely ignore the error handling and then have somewhere higher up the stack that is actually in a position to handle the error condition catch the exception and handle it is an amazing feature. 2. It's also best to use exceptions when you can't guarantee that an operation will succeed but where it's reasonable to assume that it will - particularly when it's actually impossible to check that an operation will succeed beforehand. A great example of this would be reading a file. It's good practice to check that the file exists first, but even then, you can't guarantee that opening it will succeed, because the file could be removed between the time you check and the time you go to open it (or a variety of other errors could occur which cause opening or reading the file to fail). The same goes for most file operations really. Any of them could fail, and there needs to be a way to report that, and it clutters up the code considerably if you have to deal with checking return values all over the place - on top of the fact that it makes it impossible to simply return an object or buffer from a function and use it if you also have to check an error condition. You're stuck either returning the object via one of the parameters or using a compound type where you have to check if the operation succeeded and then extract the actual return value from it, which absolutely destroys your ability to chain function calls - on top of making it far more likely that code will fail to check the return value like it should, resulting in it assuming that the call succeeded when it didn't. 3. For constructors, exceptions are really your only option unless you want to get into doing two-part initialization, which is known to be error-prone, and the advice I've almost always seen is to avoid it like the plague. So, if a constructor needs to validate its arguments - or report any other error condition that might occur while it's being constructed - an exception is going to be the way to do it unless you want to do something like add a member function to the type just so that you can check whether it was constructed correctly, and at that point, you might as well just be doing two-part initialization. 4. And exceptions are an excellent choice in any situation where you need to be sure that an error condition is not ignored - or at least put the code in a position where either the exception is caught and handled in whatever manner is appropriate, or the program is killed, because the error condition wasn't handled. Obviously, not all error conditions fall into that category, but there are plenty of situations where error conditions must be handled for the application to operate properly, and that's much more likely to happen with an exception than with any other error reporting mechanism that D has. Some other languages force that by forcing you to check return values, but that can be incredibly annoying, and it results in far more verbose code, because you have to put error-handling code everywhere instead of just letting the exception bubble up to the code that can actually handle it properly. Now, obviously, there are situations where exceptions aren't appropriate. An obvious one is where an error is likely, because using an exception in that kind of situation is going to be inefficient in comparison to other options, and if the error path is that likely, then trying to separate out the error handling code like you do with try-catch statements really doesn't make sense anyway. And of course there are situations where validating stuff ahead of time is perfectly reasonable and allows the code beyond that to just assume that everything works without needing to report error conditions at all, because the validation was already done. Unicode decoding is one such case where that often makes sense. If you validate the Unicode when you read in a file, then the rest of the code doesn't have to. Phobos, unfortunately, currently picks the worst of both worlds, because readText checks the Unicode, and then you have auto-decoding all over the place which validates the text again and throws an exception if it's invalid. So, we end up with a bunch of code that can't be nothrow or nogc just because of a potential UTFException which can't possibly be thrown if the text was already validated. And of course there are also situations where it's actually reasonable to ignore an error, in which case, throwing an exception wouldn't make sense - but no other reporting mechanism would either. Unicode can actually be handled in such a fashion in some cases, because it has the replacement character so that you can use it anywhere that you encounter an invalid code point, which gives text processing a way to process text without worrying about invalid Unicode. That's obviously not a good choice in all cases, but without auto-decoding, that choice is left up to the programmer as it should be. And with D, there are situations where exceptions can't be used where they could be in a language like C++, because D's exceptions are allocated on the heap, which not only means allocating memory, but it typically means using the GC, which is fine for most code but not fine for all code. So, anyone in that kind of situation is going to need to avoid exceptions even if they would otherwise be the best choice. And naturally, there are idiots who use exceptions for stupid things (e.g. throwing an exception when you're checking a condition instead of just returning bool, or having a type implement an interface and then throw an exception if you call a function that it doesn't actualy support), which I expect is part of the reason that some folks dislike exceptions. So, there's no question that exceptions can be a problem, but overall, in the hands of someone who knows what they're doing, they can be an excellent tool and result in much cleaner, less error-prone APIs. Obviously, you're free to hate exceptions for whatever reasons you may have, and we're obviously not going to use them for everything in Phobos, because that would be dumb, but given that there are cases where code is clearly cleaner and easier to use correctly when exceptions are used, you're not going to find general agreement with the idea that exceptions are inherently bad. I expect that for most people, the disagreement is going to be on which cases exactly they make sense for, and which they don't, not whether they're a bad idea in general. And personally, I wouldn't use D if it didn't have exceptions. It would be far too miserable to not have them. So, while D's exceptions could certainly use some improvement, I never would have started using D if it hadn't supported exceptions, and if Walter seriously tried to get rid of them, I'd go find another language to use instead. The exact form exceptions in D take may change at some point in the future, but their basic functionality is IMHO critical to writing good APIs, and part of the reason that languages like C are miserable to use is that they don't have a comparable feature. - Jonathan M Davis
Feb 04
On Sunday, 4 February 2024 at 12:35:02 UTC, Jonathan M Davis wrote: I get it, you are interested in the propagation mechanic, it can be done with error handling code too, take a look at Swift/Zig, take a look at Go2's proposal, many have succesfully moved away from EH, I learnt from them There is no reason to be stubborn about the way it is currently done in phobos, DMD was successfully built without exceptions, let's embrace and enhance this My game+engine are also successfully built without EH, and i'd love to move away from the C way of checking errors, and i'm envious of how other people are doing it with their other languages
Feb 04
On Sunday, 4 February 2024 at 15:54:53 UTC, ryuukk_ wrote:On Sunday, 4 February 2024 at 12:35:02 UTC, Jonathan M Davis i'd love to move away from the C way of checking errors, and i'm envious of how other people are doing it with their other languagesWhy to be envious, and not just use this one for example https://tchaloupka.github.io/expected/expected.html ?
Feb 04
On Sunday, 4 February 2024 at 15:54:53 UTC, ryuukk_ wrote:On Sunday, 4 February 2024 at 12:35:02 UTC, Jonathan M Davis wrote: I get it, you are interested in the propagation mechanic, it can be done with error handling code too, take a look at Swift/Zig, take a look at Go2's proposal, many have succesfully moved away from EH, I learnt from them There is no reason to be stubborn about the way it is currently done in phobos, DMD was successfully built without exceptions, let's embrace and enhance thisNo a fun of checking errors by return. Such code looks more difficult to read than it should. So it possible but not ideal. These language have gotten very little use out there. Exception is proven and works.My game+engine are also successfully built without EH, and i'd love to move away from the C way of checking errors, and i'm envious of how other people are doing it with their other languages
Feb 04
On Sunday, 4 February 2024 at 12:35:02 UTC, Jonathan M Davis wrote:On Sunday, February 4, 2024 3:13:39 AM MST ryuukk_ via Digitalmars-d wrote:I personally find exceptions useful only when I want to jump many stack frames at once. Overall I find them taxing because they add another possible 'return' value to a function. Sometimes its documented, but 9 out of 10 times you'll find out at runtime. Knowing all the possible error states of a function helps me enormously in avoiding surprises later on. While it might seem overwhelming at first, I find it liberating because the complete state space is right in front of me. I guess it is similar to the benefits of local reasoning. Note I often write server programs. YMMV with e.g. batch programs.EH is evil, some platforms has banned it completly (apple), application in Rust too, not just C++, it is an inferior design https://www.theregister.com/2024/01/31/microsoft_seeks_rust_developers/A number of us do not agree with you, and I for one never will. For many situations, exceptions are by far the best error handling mechanism that there is.
Feb 04
On Sun, Feb 04, 2024 at 09:10:20PM +0000, Sebastiaan Koppe via Digitalmars-d wrote: [...]I personally find exceptions useful only when I want to jump many stack frames at once.But I thought exceptions were not intended to be used in that kind of way. They're more like an abort condition to short-circuit the normal flow of control. If a failure condition is an expected part of the program, throwing an exception is probably not the best way of implementing it.Overall I find them taxing because they add another possible 'return' value to a function. Sometimes its documented, but 9 out of 10 times you'll find out at runtime.But isn't it enough to just have a blanket catch block in the dispatch code to swallow any exceptions that downstream code might generate? You don't have to know exactly what it is, you just catch it, abort the offending task, and move on to the next one?Knowing all the possible error states of a function helps me enormously in avoiding surprises later on. While it might seem overwhelming at first, I find it liberating because the complete state space is right in front of me. I guess it is similar to the benefits of local reasoning. Note I often write server programs. YMMV with e.g. batch programs.There are certainly valid considerations about the predictability of control flow. I.e., if you call a series of functions in a row and they are all nothrow, you can rest assured that the control flow will reach the end of the block, and not bail out on you in the middle. Still, when a fatal error happens deep inside some low-level code and there's nothing else you can do until you get back to the high-level business logic, exceptions are very useful. To manually bubble the error state all the way back up the call stack is just too onerous. It forces all intermediate levels of code to be dependent on the exact error codes / sumtypes so that it can be properly propagated up to the level where the code has enough context to react to it meaningfully. This increases coupling between orthogonal code. Using exceptions avoids this spurious coupling. T -- People tell me I'm stubborn, but I refuse to accept it!
Feb 04
On Sunday, 4 February 2024 at 23:16:36 UTC, H. S. Teoh wrote:On Sun, Feb 04, 2024 at 09:10:20PM +0000, Sebastiaan Koppe via Digitalmars-d wrote: [...]Sorry, I didn't phrase it correctly. You are right, exceptions obviously aren't for control flow. I meant that I find them very useful when I'm in the bowels of a library and need to bubble up an error to the original caller. With exceptions you can do this without involving the middle layer; just throw and let someone else care about it. This is very convenient. However, that is about the only thing that they have going for me.I personally find exceptions useful only when I want to jump many stack frames at once.But I thought exceptions were not intended to be used in that kind of way. They're more like an abort condition to short-circuit the normal flow of control. If a failure condition is an expected part of the program, throwing an exception is probably not the best way of implementing it.Sometimes that can work yes. I find that when I'm writing server software however, I often want to handle a subset of the possible failures. That might involve a blanket retry, a retry with tweaked parameters, a possible fallback, etc. Using algebraic datatypes has always been a lot more explicit for me.Overall I find them taxing because they add another possible 'return' value to a function. Sometimes its documented, but 9 out of 10 times you'll find out at runtime.But isn't it enough to just have a blanket catch block in the dispatch code to swallow any exceptions that downstream code might generate? You don't have to know exactly what it is, you just catch it, abort the offending task, and move on to the next one?Yes, exactly. I value that a lot.Note I often write server programs. YMMV with e.g. batch programs.There are certainly valid considerations about the predictability of control flow. I.e., if you call a series of functions in a row and they are all nothrow, you can rest assured that the control flow will reach the end of the block, and not bail out on you in the middle.Still, when a fatal error happens deep inside some low-level code and there's nothing else you can do until you get back to the high-level business logic, exceptions are very useful. To manually bubble the error state all the way back up the call stack is just too onerous. It forces all intermediate levels of code to be dependent on the exact error codes / sumtypes so that it can be properly propagated up to the level where the code has enough context to react to it meaningfully. This increases coupling between orthogonal code. Using exceptions avoids this spurious coupling.With exceptions there is coupling as well. In fact, I would argue the coupling is worse since its over a wider distance. Plus you have to 'discover' them over time. It is true that it can sometimes be a bit onerous. In practice its only in a few rare cases, so I do it and move on. The possible set of failures is pretty static so its not like you have to extend the set all the time. --- To conclude, I guess I consider exceptions to be very unstructured. Not only do they rarely contain the right information in order to decide the next step (unless you want to parse strings), because it is an open hierarchy, basically anything goes and you have no idea what gets thrown at you. Not to mention that a refactor might change or add an exception, and there is no way you get informed about that during compilation.
Feb 05
On Sun, Feb 04, 2024 at 05:35:02AM -0700, Jonathan M Davis via Digitalmars-d wrote:On Sunday, February 4, 2024 3:13:39 AM MST ryuukk_ via Digitalmars-d wrote:[...]EH is evil, some platforms has banned it completly (apple), and in Rust too, not just C++, it is an inferior designA number of us do not agree with you, and I for one never will. For many situations, exceptions are by far the best error handling mechanism that there is.Exceptions are like the GC: they free your APIs from being littered with error-handling paraphrenalia that crowd out the actual business logic. Just like not having the GC forces your code and APIs to be crowded with memory-management paraphrenalia. Both memory management and error-handling are secondary concerns; the primary concern is actually making progress in your problem domain: doing what the code set out to achieve in the first place. As such, code should be focused as much as possible on the business logic rather than have secondary concerns occupy most of the space. Ideally, the main code should *only* express the business logic; memory management and error-handling should be done in a footnote rather than in the main body of the code. Try/catch blocks let you do this to a large extent; whereas having to manually check error codes or unwrap error sumtypes just adds excessive verbosity to the primary logic, which makes code more tedious to write, harder to read, and less maintainable as a result. I suspect, though, that most objections to EH are directed primarily at the specific implementation of it using libunwind like in C++, rather than the concept itself of EH. That part I agree with: the way EH is implemented could be done better. But as far as the concept is concerned it's fine, and trying to get rid of it is just silly. T -- The easy way is the wrong way, and the hard way is the stupid way. Pick one.
Feb 04
On Sunday, 4 February 2024 at 09:30:58 UTC, Jonathan M Davis wrote:The main thing that it needs IMHO is going through it and making sure that it's doing the right thing for each trait and that the exact set of traits that it has is really what we want, since right now, several of them are doing the wrong thing (e.g. treating enum as if it were its base type with stuff like isIntegral, isNumeric, etc., which is a source of bugs).I have bad news for you. This behavior is not the fault of std.traits, but is actually baked into the language itself. For example, the spec for __traits(isIntegral) says:The integral types are: byte, ubyte, short, ushort, int, uint, long, ulong, cent, ucent, bool, char, wchar, dchar, vectors of integral types, and enums with an integral base type.https://dlang.org/spec/traits.html#isIntegral Maybe we can clean this up in a new language edition, but as long as this is how the underlying __traits work, std.traits should work the same way.
Feb 04
On Sunday, February 4, 2024 8:04:00 AM MST Paul Backus via Digitalmars-d wrote:On Sunday, 4 February 2024 at 09:30:58 UTC, Jonathan M Davis wrote:std.traits doesn't actually rely on that. It does its own checks for enum, and it does so inconsistently (e.g. isSomeString doesn't allow enums, and it was a source of bugs and frustration when it did years ago, because it meant that range-based code was accepting enums with a base type of string and then not working, because they aren't actually ranges). Traits and template constraints in general need to be checking for either an exact list of types or for whether the provided type has a particular set of capabilities. Allowing implicit conversions is almost always a source of bugs. So, while it should obviously be possible to check for implicit conversions where appropriate, IMHO, it's a big mistake for Phobos to encourage it or make it the easy the default. It should not be necessary to put !is(T == enum) all over the place in code to stop enums or alias this from making it into a function and then not behaving properly, because the type wasn't actually converted, and the fact that std.traits is not principled about that is one of its biggest problems IMHO - though as with a number of things that need to be fixed in Phobos, they're mistakes that really only become clear after more experience with what we attempted the first time around. So, regardless of what __traits is doing, I will argue quite strongly that std.traits should not be treating anything as its base type unless that's truly what makes sense for that particular trait, and if __traits isn't doing that, then it should probably fixed in a future edition as well. But ultimately, __traits is a building block for other traits, so what std.traits does does not have to be the same thing, though having the same name in __traits and std.traits do something different from each other is something that should probably be avoided. So, I agree that having __traits(isIntegral, T) accept enums and std.traits.isIntegral reject them is not a good idea. But my solution at that point is to not call the trait in std.traits isIntegral but rather given a distinct name. - Jonathan M DavisThe main thing that it needs IMHO is going through it and making sure that it's doing the right thing for each trait and that the exact set of traits that it has is really what we want, since right now, several of them are doing the wrong thing (e.g. treating enum as if it were its base type with stuff like isIntegral, isNumeric, etc., which is a source of bugs).I have bad news for you. This behavior is not the fault of std.traits, but is actually baked into the language itself. For example, the spec for __traits(isIntegral) says:The integral types are: byte, ubyte, short, ushort, int, uint, long, ulong, cent, ucent, bool, char, wchar, dchar, vectors of integral types, and enums with an integral base type.https://dlang.org/spec/traits.html#isIntegral Maybe we can clean this up in a new language edition, but as long as this is how the underlying __traits work, std.traits should work the same way.
Feb 04
On Sunday, 4 February 2024 at 09:30:58 UTC, Jonathan M Davis wrote:The advantage of that is that the result is cleaner code (since __traits tends to be pretty ugly), but it also means more template instantiations. So, I expect that there is going to be some disagreement on what we should be doing thereMan this is such an easily-fixable problem. I wish Walter weren't so stubborn about having macros in D. All it would take is something like: ``` macro template isNumeric(T) { __traits(isNumeric, T) } enum isStringNumeric = isNumeric!String; assert(!isStringNumeric); ``` No symbol template instantiation or symbol generation necessary. It's like mixin templates but in reverse. Constrain macro templates to only be allowed to expand to an expression or something. It completely fixes any issues with std.traits, and is probably useful in a lot more areas as well.
Feb 04
On Friday, 2 February 2024 at 09:09:37 UTC, Adam Wilson wrote:Second, this design implies that the '2' in `std2.` is a version specifier that would be incremented with each Phobos release. This was not the intention and we agreed that it would be confusing. I proposed using `sys.` as the root name for Phobos 3 and Walter found that acceptable. We briefly discussed splitting up Phobos into multiple roots and no firm agreement was reached.And then subsequent versions get put in a package with a version number under that?The other major topic of discussion was what I've been calling the "Crippled by Default" design of editions, where the oldest edition (technically the last pre-edition release) is the default edition if no edition is specified. This poses a few challenges from an end-user standpointWhich ones?, but the argument that ended up resonating was the idea that in engineering we always want to make the "right" way the default or easiest way to do something, and then provide escape hatches where necessary.And the right way should be to not break existing code, even if they upgrade the compiler.Therefore, the compiler should default to use the latest versionThe latest version of Phobos? Of the language?and then provide the ability via a switch to set the edition, or lack thereof, of the modules an import path.I think this option is useful for trying to upgrade a project to a new edition, but I'm not sure how it applies here.This solves the problem of abandon-ware packages being accessibleAbandon-ware Phobos packages?without presenting the new user with an ever more decayed version of the compiler.I don't understand what this means.We want to put out best foot forward and presenting the last pre-editions release, which is constantly getting old as time passes, does not do that.It's unclear to me how we'd be doing that if the new Phobos version(s) is namespaced differently.When then moved on to a conversation about how Walter envisions editions actually working. Since none of have seen the document that Atila is working on, Walter shared his opinions on how it should work. Essentially, Walter would like to see a "hybrid" approach having edition attributes for specific experimental features, and then having a yearly "roll-up" edition that includes all the promoted features from the prior year. So if DIP1000 gets promoted to Edition 2025, then DIP1000 would be active by default in that edition and all subsequent editions without having to specifically enable it.I'm not sure every year is a good time interval.I did bring up that this was likely to cause another "function attribute soup" problemHow?but in general I wholeheartedly agree with the idea that something similar so it would be conceptually comfortable to users coming from those languages. Atila, if you're reading this, this is what Walter was thinking/hoping would appear,The reason for that is because I told him that's how I was thinking of doing it ;)After that we had a discussion about how to distribute Phobos. This mostly centered on what release cadence to use. I argued for linking the Phobos version to the edition release schedule. I think this is sensible and makes it easier for people to reason about which compiler/library pairing they are using. Walter was fine with that, but he does not want to use the "Edition" language to describe Phobos releases.This is the part I'm really not clear about yet.I think this makes sense as Phobos doesn't really have editions,Unless it opts in to a new one. And it should, because we want to lead by example.Finally, we touched briefly on the major changes we would like to see in Phobos 3 and these are the major changes we are committing to for Phobos 3 so far: - Promoting allocators out of experimental.This requires solving a number of thorny issues, including "does this API even make sense?", which I'm told Paul Backus is working on.- Range interface redesign (see JMD's thread [here](https://forum.dlang.org/thread/mailman.588.1705813271.3719.digitalmars-d puremagic.com)). - Fix std.traits.What does "fix" mean in this context?The above list is not exhaustive and we are open to further suggestions.- XML - JSON - YAML - SDL? - Channels - ...
Feb 05
On Friday, 2 February 2024 at 09:09:37 UTC, Adam Wilson wrote:Walter and I had a productive conversation yesterday about Phobos 3 and we felt it would be appropriate to share some notes on our discussion. Snip... Finally, we touched briefly on the major changes we would like to see in Phobos 3 and these are the major changes we are committing to for Phobos 3 so far: - Removal of Autodecoding. - Promoting allocators out of experimental. - Range interface redesign (see JMD's thread [here](https://forum.dlang.org/thread/mailman.588.1705813271.3719.digitalmars-d puremagic.com)). - Fix std.traits. The above list is not exhaustive and we are open to further suggestions. For myself, I would love to see Cryptography and Stream API's make it into Phobos, but I am sure that the list of what the community wants to add is legion so those could end up being lower priority. Snip... If you would like to participate in the design discussion on Phobos 3, I am currently hosting a repo on my GitHub with GH Discussions for unresolved/undesigned topics, and PR's for editing the actual design document. Link is here: https://github.com/LightBender/PhobosV3-DesignVery interesting! I really like the Allocator idea. Something I think will benefit D and is overdue if being honest. Curious to know how this will work for D. Will Allocators be available for BetterC as well? I certainly hope so! If so, I guess the **default** Allocator will be the GC one, and can still be disabled. Being able to change the default (or change locally like in a function or pass it as parameter) would provide a lot of flexibility. It's just I see possiblities of BetterC being able to use certain features that are not available, like dynamic or associative arrays. To be designed for allowing us to specify the Allocator to use (or default if not specified at all) and it doesn't need to be a GC one gives the programmer a lot of control for low level as well as high.
Feb 06
On Tuesday, 6 February 2024 at 14:41:27 UTC, Martyn wrote:Curious to know how this will work for D. Will Allocators be available for BetterC as well? I certainly hope so!Nothing's set in stone yet, but in the proposal I'm working on, there is nothing stopping allocators from being available in BetterC.If so, I guess the **default** Allocator will be the GC one, and can still be disabled. Being able to change the default (or change locally like in a function or pass it as parameter) would provide a lot of flexibility.In my proposal, when you use a library container (like an array, a hash table, a binary tree, etc.), you can specify what type of allocator you want to use as a template parameter (as in, `Array!(int, GC)`). It will probably default to the GC, but you can just as easily use malloc, or even a custom allocator that you write yourself. I'm not planning to include a global default allocator. Built-in language features like `new`, dynamic arrays, associative arrays, and delegate contexts will always use the GC, and there will not be an option to change this.
Feb 06
On Wednesday, 7 February 2024 at 05:55:04 UTC, Paul Backus wrote:On Tuesday, 6 February 2024 at 14:41:27 UTC, Martyn wrote:Thank you for taking the time to respond. I understand a proposal is working on, but your answers above sound very promising. Thanks again.... SnipNothing's set in stone yet, but in the proposal I'm working on, there is nothing stopping allocators from being available in BetterC.... SnipIn my proposal, when you use a library container (like an array, a hash table, a binary tree, etc.), you can specify what type of allocator you want to use as a template parameter (as in, `Array!(int, GC)`). It will probably default to the GC, but you can just as easily use malloc, or even a custom allocator that you write yourself. I'm not planning to include a global default allocator. Built-in language features like `new`, dynamic arrays, associative arrays, and delegate contexts will always use the GC, and there will not be an option to change this.
Feb 07
On Wednesday, 7 February 2024 at 05:55:04 UTC, Paul Backus wrote:On Tuesday, 6 February 2024 at 14:41:27 UTC, Martyn wrote:The problem with this approach, as C++ found out, is that `Vector!(int, MyAlloc)` is a different type from `Vector!(int, YourAlloc)`. The way I got around that is by defaulting to a global allocator. This has its drawbacks as well of course, because now everything is a virtual call.Curious to know how this will work for D. Will Allocators be available for BetterC as well? I certainly hope so!Nothing's set in stone yet, but in the proposal I'm working on, there is nothing stopping allocators from being available in BetterC.If so, I guess the **default** Allocator will be the GC one, and can still be disabled. Being able to change the default (or change locally like in a function or pass it as parameter) would provide a lot of flexibility.In my proposal, when you use a library container (like an array, a hash table, a binary tree, etc.), you can specify what type of allocator you want to use as a template parameter (as in, `Array!(int, GC)`). It will probably default to the GC, but you can just as easily use malloc, or even a custom allocator that you write yourself. I'm not planning to include a global default allocator. Built-in language features like `new`, dynamic arrays, associative arrays, and delegate contexts will always use the GC, and there will not be an option to change this.
Feb 07
On Wednesday, 7 February 2024 at 10:10:27 UTC, Atila Neves wrote:On Wednesday, 7 February 2024 at 05:55:04 UTC, Paul Backus wrote:I do that as well ```D struct Array(T) { T[] items; Allocator allocator; size_t count = 0; ``` Just store the allocator in the struct, it's no big deal, granted your allocator type is a simple and compact struct ```D struct Allocator { void* ptr; AllocatorFN* fn; } struct AllocatorFN { alloc_d alloc; resize_d resize; free_d free; } // libc enum c_allocator = Allocator(null, &CAllocator.fn); struct CAllocator { __gshared AllocatorFN fn = { alloc: &alloc_impl, resize: &resize_impl, free: &free_impl }; } ``` That's it ```D Allocator heap = c_allocator; auto entities = Array!(Entity).create(heap); ```On Tuesday, 6 February 2024 at 14:41:27 UTC, Martyn wrote:The problem with this approach, as C++ found out, is that `Vector!(int, MyAlloc)` is a different type from `Vector!(int, YourAlloc)`. The way I got around that is by defaulting to a global allocator. This has its drawbacks as well of course, because now everything is a virtual call.Curious to know how this will work for D. Will Allocators be available for BetterC as well? I certainly hope so!Nothing's set in stone yet, but in the proposal I'm working on, there is nothing stopping allocators from being available in BetterC.If so, I guess the **default** Allocator will be the GC one, and can still be disabled. Being able to change the default (or change locally like in a function or pass it as parameter) would provide a lot of flexibility.In my proposal, when you use a library container (like an array, a hash table, a binary tree, etc.), you can specify what type of allocator you want to use as a template parameter (as in, `Array!(int, GC)`). It will probably default to the GC, but you can just as easily use malloc, or even a custom allocator that you write yourself. I'm not planning to include a global default allocator. Built-in language features like `new`, dynamic arrays, associative arrays, and delegate contexts will always use the GC, and there will not be an option to change this.
Feb 07
On 07/02/2024 11:10 PM, Atila Neves wrote:On Wednesday, 7 February 2024 at 05:55:04 UTC, Paul Backus wrote:I came to a similar conclusion from my usage of std.experimental.allocator. My stuff doesn't use template parameters for things like memory allocators. My conclusion was that you really only have two use cases for composable allocators: 1. You know about memory patterns, locking, type sizes ext. Use composable directly. 2. Otherwise, use virtual. There doesn't seem to be anything in between.On Tuesday, 6 February 2024 at 14:41:27 UTC, Martyn wrote:The problem with this approach, as C++ found out, is that `Vector!(int, MyAlloc)` is a different type from `Vector!(int, YourAlloc)`. The way I got around that is by defaulting to a global allocator. This has its drawbacks as well of course, because now everything is a virtual call.Curious to know how this will work for D. Will Allocators be available for BetterC as well? I certainly hope so!Nothing's set in stone yet, but in the proposal I'm working on, there is nothing stopping allocators from being available in BetterC.If so, I guess the **default** Allocator will be the GC one, and can still be disabled. Being able to change the default (or change locally like in a function or pass it as parameter) would provide a lot of flexibility.In my proposal, when you use a library container (like an array, a hash table, a binary tree, etc.), you can specify what type of allocator you want to use as a template parameter (as in, `Array!(int, GC)`). It will probably default to the GC, but you can just as easily use malloc, or even a custom allocator that you write yourself. I'm not planning to include a global default allocator. Built-in language features like `new`, dynamic arrays, associative arrays, and delegate contexts will always use the GC, and there will not be an option to change this.
Feb 07
On Wednesday, 7 February 2024 at 11:46:11 UTC, Richard (Rikki) Andrew Cattermole wrote:My conclusion was that you really only have two use cases for composable allocators: 1. You know about memory patterns, locking, type sizes ext. Use composable directly. 2. Otherwise, use virtual. There doesn't seem to be anything in between.The relevant constraint here isn't composability, it's safety. In order to make allocators safe (which is the goal of my proposal), you have to guarantee somehow that memory blocks can only be deallocated by the same allocator that originally allocated them. It is possible to do this with a polymorphic allocator, but it incurs an enormous amount of runtime overhead, which rules out making it the default approach. Of course, if you don't care about safe, you can ignore all of this and use a much simpler design. Personally, I think Phobos V3 should support safe as much as possible, but ultimately that choice is up to project leadership.
Feb 07
On Wednesday, February 7, 2024 9:38:38 AM MST Paul Backus via Digitalmars-d wrote:On Wednesday, 7 February 2024 at 11:46:11 UTC, Richard (Rikki) Andrew Cattermole wrote:Allocators should be safe where they can be, but I think that a number of us came to the conclusion a while ago that they couldn't be safe in the general case. So, it'll be interesting to see what you can come up with, but if safe is a requirement, I would expect that certain kinds of allocators simply won't work. But that's no reason not to support safe as much as possible (particularly when code is templated). But with regards to virtual vs templated, we don't necessarily have to decide in that we could design allocators so that they can be used with either approach. The templated ones would be more flexible with regards to attributes and could be better optimized, whereas there could then be virtual ones that wrapped those in classes but put harder requirements on the attributes (be it by requiring more or allowing fewer), because they're then supposed to work with most or all of the various allocator types. Then both approaches would be available. That being said, I would expect most D code to go with the templated approach. It's what D typically does, and the kind of folks who want to use allocators are usually also the kind of folks who aren't going to be very happy about passing classes around. And based on both what has historically been done with containers in D and the few discussions that we've had on it recently, I expect that they're very much going to be taking the Design by Introspection approach and be templated based on their capabilities (of which the allocator would be only one, though one of the possible approaches there is for one of the options be to choose between a statically chosen alocator and a dynamically chosen one). - Jonathan M DavisMy conclusion was that you really only have two use cases for composable allocators: 1. You know about memory patterns, locking, type sizes ext. Use composable directly. 2. Otherwise, use virtual. There doesn't seem to be anything in between.The relevant constraint here isn't composability, it's safety. In order to make allocators safe (which is the goal of my proposal), you have to guarantee somehow that memory blocks can only be deallocated by the same allocator that originally allocated them. It is possible to do this with a polymorphic allocator, but it incurs an enormous amount of runtime overhead, which rules out making it the default approach. Of course, if you don't care about safe, you can ignore all of this and use a much simpler design. Personally, I think Phobos V3 should support safe as much as possible, but ultimately that choice is up to project leadership.
Feb 07
On 08/02/2024 11:00 AM, Jonathan M Davis wrote:That being said, I would expect most D code to go with the templated approach. It's what D typically does, and the kind of folks who want to use allocators are usually also the kind of folks who aren't going to be very happy about passing classes around.I do not. There isn't enough of a win to introducing allocators, unless you have knowledge of internals. At which point you don't need to template your container upon the composable allocator. You'll have a dedicated one internally that isn't virtual. This is one of my key take aways, don't pretend you need to customize the memory allocator to its usage if you don't know how it would be used. Go slower, go virtual, it'll keep you sane and allow you to build cool things. Remember to profile. Not guess.
Feb 07
On Wednesday, 7 February 2024 at 22:00:49 UTC, Jonathan M Davis wrote:Allocators should be safe where they can be, but I think that a number of us came to the conclusion a while ago that they couldn't be safe in the general case. So, it'll be interesting to see what you can come up with, but if safe is a requirement, I would expect that certain kinds of allocators simply won't work. But that's no reason not to support safe as much as possible (particularly when code is templated).With -preview=dip1000 and -preview=systemVariables, it is possible to make pretty much any allocator safe--although for some of them, the safety checking adds a little bit of runtime overhead. The main obstacle is that both of these -preview features are still very much unfinished, and will need a lot of work before they are ready to be used in real library code. By the way, one of the key techniques that makes this work is having the allocators wrap each void[] they return in a non-copyable struct, so that it can only be deallocated once. So you can probably understand why I'm so concerned about support for non-copyable types in Phobos v3. :)But with regards to virtual vs templated, we don't necessarily have to decide in that we could design allocators so that they can be used with either approach.Yes, that's the idea.And based on both what has historically been done with containers in D and the few discussions that we've had on it recently, I expect that they're very much going to be taking the Design by Introspection approach and be templated based on their capabilities (of which the allocator would be only one, though one of the possible approaches there is for one of the options be to choose between a statically chosen alocator and a dynamically chosen one).This is also how I'd expect containers to work.
Feb 07
On Wednesday, February 7, 2024 10:12:06 PM MST Paul Backus via Digitalmars-d wrote:On Wednesday, 7 February 2024 at 22:00:49 UTC, Jonathan M Davis wrote:Well, regardless of what we end up doing iwth non-copyable types in Phobos, it's clear that the language needs improvements with regards to moving objects, which we discussed in one of the recent DLF planning meetings. DIP 1048 (move constructors) was approved ages ago, but it still hasn't been implemented yet, and to really make moving objects around even sort of user-friendly, we need the compiler to start doing things like do a move instead of a copy when it's the last use of a variable. And in particular, if we decide that making basic input ranges non-copyable is the best approach, then that's going to put pressure on getting that sorted out. The range situation in Phobos v3 is still very much in the air though. - Jonathan M DavisAllocators should be safe where they can be, but I think that a number of us came to the conclusion a while ago that they couldn't be safe in the general case. So, it'll be interesting to see what you can come up with, but if safe is a requirement, I would expect that certain kinds of allocators simply won't work. But that's no reason not to support safe as much as possible (particularly when code is templated).With -preview=dip1000 and -preview=systemVariables, it is possible to make pretty much any allocator safe--although for some of them, the safety checking adds a little bit of runtime overhead. The main obstacle is that both of these -preview features are still very much unfinished, and will need a lot of work before they are ready to be used in real library code. By the way, one of the key techniques that makes this work is having the allocators wrap each void[] they return in a non-copyable struct, so that it can only be deallocated once. So you can probably understand why I'm so concerned about support for non-copyable types in Phobos v3. :)
Feb 08
On Thursday, 8 February 2024 at 05:12:06 UTC, Paul Backus wrote:On Wednesday, 7 February 2024 at 22:00:49 UTC, Jonathan M Davis wrote:What specifically would we need support for?[...]With -preview=dip1000 and -preview=systemVariables, it is possible to make pretty much any allocator safe--although for some of them, the safety checking adds a little bit of runtime overhead. The main obstacle is that both of these -preview features are still very much unfinished, and will need a lot of work before they are ready to be used in real library code. By the way, one of the key techniques that makes this work is having the allocators wrap each void[] they return in a non-copyable struct, so that it can only be deallocated once. So you can probably understand why I'm so concerned about support for non-copyable types in Phobos v3. :)
Feb 12
On Monday, 12 February 2024 at 17:07:21 UTC, Atila Neves wrote:On Thursday, 8 February 2024 at 05:12:06 UTC, Paul Backus wrote:It's not really any specific thing; it's more that Phobos's general attitude towards non-copyable types needs to change. Currently, there are a huge number of interfaces in Phobos that, in principle, could work with non-copyable types, but just don't, because no one ever thought of it or cared enough. Such interfaces include: - Large portions of std.range and std.algorithm - std.format in its entirety - std.typecons.Tuple - std.array.Appender - etc. From how widespread it is, it's clear that this is not an issue of specific bugs or design mistakes. It's a systemic problem in the way Phobos's code is written, tested, and reviewed. The attitude that leads to this problem is exemplified by Jonathan M. Davis's comments in the "Range Redesign" thread [1], but I do not want to single him out. Every single one of us who writes and reviews code for Phobos, and allows PRs to be merged that fail to handle non-copyable types, is a contributor to the problem (including myself!). If we're going to fix this, whoever's leading the development of Phobos V3 (you? Adam Wilson?) needs to make a policy-level decision that no PR gets merged unless it either supports non-copyable types, or has a good reason not to. [1]: https://forum.dlang.org/post/mailman.618.1705964882.3719.digitalmars-d puremagic.comBy the way, one of the key techniques that makes this work is having the allocators wrap each void[] they return in a non-copyable struct, so that it can only be deallocated once. So you can probably understand why I'm so concerned about support for non-copyable types in Phobos v3. :)What specifically would we need support for?
Feb 12
On Monday, 12 February 2024 at 19:49:39 UTC, Paul Backus wrote:On Monday, 12 February 2024 at 17:07:21 UTC, Atila Neves wrote:I see. This is an instance of a more general problem of "nasty types" that do "weird" things such as being uncopyable. Ideally we'd have one in Phobos just for testing and feed it to basically everything. FeepingCreature mentioned something like to me at DConf but I can't find it in github after googling.On Thursday, 8 February 2024 at 05:12:06 UTC, Paul Backus wrote:It's not really any specific thing; it's more that Phobos's general attitude towards non-copyable types needs to change. Currently, there are a huge number of interfaces in Phobos that, in principle, could work with non-copyable types, but just don't, because no one ever thought of it or cared enough. Such interfaces include: - Large portions of std.range and std.algorithm - std.format in its entirety - std.typecons.Tuple - std.array.Appender - etc. From how widespread it is, it's clear that this is not an issue of specific bugs or design mistakes. It's a systemic problem in the way Phobos's code is written, tested, and reviewed.By the way, one of the key techniques that makes this work is having the allocators wrap each void[] they return in a non-copyable struct, so that it can only be deallocated once. So you can probably understand why I'm so concerned about support for non-copyable types in Phobos v3. :)What specifically would we need support for?
Feb 13
On Tuesday, 13 February 2024 at 14:08:24 UTC, Atila Neves wrote:I see. This is an instance of a more general problem of "nasty types" that do "weird" things such as being uncopyable. Ideally we'd have one in Phobos just for testing and feed it to basically everything. FeepingCreature mentioned something like to me at DConf but I can't find it in github after googling.If you want some examples to crib from, check out the unittests in std.sumtype. I've done my best to put every weird type I can think of in there. :)
Feb 13
On Tuesday, 13 February 2024 at 15:27:16 UTC, Paul Backus wrote:On Tuesday, 13 February 2024 at 14:08:24 UTC, Atila Neves wrote:Nice! Now we "just" have to move them somewhere common (so that other Phobos modules don't depend on sumtype for no reason) and shove them down the rest of Phobos. Somehow.I see. This is an instance of a more general problem of "nasty types" that do "weird" things such as being uncopyable. Ideally we'd have one in Phobos just for testing and feed it to basically everything. FeepingCreature mentioned something like to me at DConf but I can't find it in github after googling.If you want some examples to crib from, check out the unittests in std.sumtype. I've done my best to put every weird type I can think of in there. :)
Feb 13
On Wednesday, 7 February 2024 at 22:00:49 UTC, Jonathan M Davis wrote:That being said, I would expect most D code to go with the templated approach. It's what D typically does,We are here, we said we don't like them templatedand the kind of folks who want to use allocators are usually also the kind of folks who aren't going to be very happy about passing classes around."classes"? the kind of people who want to use allocators are not the kind of people to make them "classes" another red flag.. Passing them around? yes, if you care about using allocators, you won't mind doing this, besides, it's limited to the places you want to control your allocations, it's not a kind of type you pass around _everywhere_
Feb 08
On Wednesday, 7 February 2024 at 10:10:27 UTC, Atila Neves wrote:On Wednesday, 7 February 2024 at 05:55:04 UTC, Paul Backus wrote:Yes, I'm aware of this problem, but I don't see a way around it. The thing is, the compiler has to know what allocator you're using at compile time in order to infer the correct function attributes for the container. If you want `Array!int` to default to using the GC, but also work in ` nogc` code when you're using `malloc`...how would that even work? I have two potential mitigations for this problem in mind. The first is to realize that D already has a solution for writing data-structure-agnostic code: ranges! If `Array` implements all of the relevant range interfaces, the rest of your code doesn't have to depend on any single concrete `Array` type--it can just depend on the range interface. If you really need a concrete type, there's always `std.range.interfaces`, although that does come with some sacrifices (virtual calls, not ` safe` or ` nogc`, etc.). The second is to have the allocator library provide a runtime-polymorphic allocator, which users can depend on if they absolutely need a single concrete container type for whatever reason. We'd have to make some serious tradeoffs between runtime overhead and attribute compatibility, and it's possible that no one-size-fits-all solution exists, but in principle, it can be done. Finally, on the subject of global allocators: I don't think having a global allocator is a good idea, period, whether it's used as a default or not. Containers generally cannot tolerate having their allocators mutated "behind their backs," and a user-accessible global variable would make it very easy and tempting to write code that does this.In my proposal, when you use a library container (like an array, a hash table, a binary tree, etc.), you can specify what type of allocator you want to use as a template parameter (as in, `Array!(int, GC)`). It will probably default to the GC, but you can just as easily use malloc, or even a custom allocator that you write yourself.The problem with this approach, as C++ found out, is that `Vector!(int, MyAlloc)` is a different type from `Vector!(int, YourAlloc)`. The way I got around that is by defaulting to a global allocator. This has its drawbacks as well of course, because now everything is a virtual call.
Feb 07
On Wednesday, 7 February 2024 at 16:20:31 UTC, Paul Backus wrote:On Wednesday, 7 February 2024 at 10:10:27 UTC, Atila Neves wrote:All good points, thanks. I like the "just use ranges" approach, algorithms really shouldn't have to care what allocation strategy is backing the range they just got, and this is an insight I won't soon forget. Appending from a "different" vector will mean element copies, I guess. Or OOP. Trade offs. Trade offs everywhere.[...]Yes, I'm aware of this problem, but I don't see a way around it. [...]
Feb 07
On Wednesday, February 7, 2024 9:54:49 AM MST Atila Neves via Digitalmars-d wrote:On Wednesday, 7 February 2024 at 16:20:31 UTC, Paul Backus wrote:Well, stuff that actually has to operate on the container itself is likely going to care about the exact container type (particularly things like removing an element or a range of elements based on an iterator/cursor/range), but algorithm code generally isn't going to care, because it's all going to be templatized anyway, and it'll infer the attributes as appropriate. While our container situation in Phobos needs work, I wouldn't expect things to change much with regards to algorithms. If you want to operate on the elements of a container, then you get a range from it and then all of the algorithm stuff doesn't care what kind of container you're dealing with. But egardless of what exactly we do with allocators, I would fully expect that we're going to end up with container types that are not just templated on the element type but which are also templated on requirements that you've placed on them (i.e. Design by Introspection), and that's clearly what Robert is proposing with what he's discussed on the topic in the DLF meetings and will be talking about in his dconf online talk. There will probably be a default choice where you don't tell the container much of what you want and just get the default (e.g. GC-allocated, safe, etc.), but I don't think that code in general is going to be passing around specific container types. Most of the time, what you really want is to pass around ranges - and when you do need to pass around an actual container, well, that's probably specific to what you're doing in your code, and then you can assume that you're using whatever it is you're using without templatizing the code using it. But in general, I wouldn't expect a library like Phobos to be passing containers around. - Jonathan M DavisOn Wednesday, 7 February 2024 at 10:10:27 UTC, Atila Neves wrote:All good points, thanks. I like the "just use ranges" approach, algorithms really shouldn't have to care what allocation strategy is backing the range they just got, and this is an insight I won't soon forget. Appending from a "different" vector will mean element copies, I guess. Or OOP. Trade offs. Trade offs everywhere.[...]Yes, I'm aware of this problem, but I don't see a way around it. [...]
Feb 07
On Wednesday, 7 February 2024 at 10:10:27 UTC, Atila Neves wrote:[snip] The problem with this approach, as C++ found out, is that `Vector!(int, MyAlloc)` is a different type from `Vector!(int, YourAlloc)`. The way I got around that is by defaulting to a global allocator. This has its drawbacks as well of course, because now everything is a virtual call.If you need to allocate or deallocate, then it's useful to treat them as separate types. Otherwise it's not. Ideally the compiler (or maybe LTO?) would know when this leads to template bloat and fix it for you. What about an `alias this` approach? For instance: ```d struct BaseVector(T) { T* ptr; size_t length; // member functions that are common to all vectors } struct Vector(T, Alloc) { BaseVector!T baseVector; alias this = baseVector; // member functions to handle allocation and de-allocation } ``` If you want to write functions that don't concern themselves with allocation, you can write them in terms of `BaseVector`. You avoid unnecessary template bloat because of implicit conversions. You can say that both `Vector!(int, MyAlloc)` and `Vector!(int, YourAlloc)` are both `BaseVector!int`s. Is there a downside to this?
Feb 07
On Wednesday, 7 February 2024 at 21:26:51 UTC, jmh530 wrote:On Wednesday, 7 February 2024 at 10:10:27 UTC, Atila Neves wrote:alias MyVec = Vector(MyType, Mallocator); void fun(MyVec vec) { // just before the curly brace, the elements and storage for them get deallocated. }[snip] The problem with this approach, as C++ found out, is that `Vector!(int, MyAlloc)` is a different type from `Vector!(int, YourAlloc)`. The way I got around that is by defaulting to a global allocator. This has its drawbacks as well of course, because now everything is a virtual call.If you need to allocate or deallocate, then it's useful to treat them as separate types. Otherwise it's not.
Feb 12
On Monday, 12 February 2024 at 17:00:01 UTC, Atila Neves wrote:On Wednesday, 7 February 2024 at 21:26:51 UTC, jmh530 wrote:I assume you mean `alias MyVec = Vector!(MyType, Mallocator);`. I'm not completely sure I'm getting to the heart of what you're saying since your post is a bit sparse...but I'm doing my best. Your `fun` function only works for `MyVec`, which depends on `MyType` and `Mallocator`. It isn't general across either types or allocators. It's kind of the essence of your complaint about C++ and treating `Vector!(int, MyAlloc)` and `Vector!(int, YourAlloc)` as different types, except you are pushing all the work downstream to functions. In other words, you have to have separate `fun` for all the different types and allocators you pass, and then have different allocation strategies for each. Multiply that across all the other functions. If all the allocators are consistent with the interface from `std.experimental.allocator`, then you might be able to make the allocation more general. But, it becomes frustrating to rely on template aliases. The compiler can't see through them due to issue 1807 [1]. The more general approach is to use template constraints (see example below). The problem with the template constraint approach is that it leads to template bloat, which is why I suggested the `alias this` approach above. Another approach would be to pass the allocator to the function instead of making it part of the type. The problem with this is that for some allocators you need to know what did the allocating in order to free it safely. ```d import std.stdio; struct Vector(T, U) { T x; U y;} alias MyVec = Vector!(double, int); void fun(MyVec vec) { writeln("works"); } alias MyVec2(T) = Vector!(T, int); void fun2(T)(MyVec2!T vec) { writeln("works2"); } void fun3(T)(T vec) if (is(T : Vector!(U, int), U)) { writeln("works3"); } void main() { MyVec vec = MyVec(1.0, 1); fun(vec); // prints works //fun2(vec); //error fun2!double(vec); // prints works2 fun3(vec); // prints works3 } ``` [1] https://issues.dlang.org/show_bug.cgi?id=1807On Wednesday, 7 February 2024 at 10:10:27 UTC, Atila Neves wrote:alias MyVec = Vector(MyType, Mallocator); void fun(MyVec vec) { // just before the curly brace, the elements and storage for them get deallocated. }[snip] The problem with this approach, as C++ found out, is that `Vector!(int, MyAlloc)` is a different type from `Vector!(int, YourAlloc)`. The way I got around that is by defaulting to a global allocator. This has its drawbacks as well of course, because now everything is a virtual call.If you need to allocate or deallocate, then it's useful to treat them as separate types. Otherwise it's not.
Feb 12
On Monday, 12 February 2024 at 18:13:45 UTC, jmh530 wrote:On Monday, 12 February 2024 at 17:00:01 UTC, Atila Neves wrote:My point is that things going out of scope can trigger deallocations. You're right that passing the allocator is error-prone. That's why automem, unlike C++'s smart pointers, doesn't let you construct the thing and pass it in; it's more "tell me what you want and I'll construct it for you".[...]I assume you mean `alias MyVec = Vector!(MyType, Mallocator);`. I'm not completely sure I'm getting to the heart of what you're saying since your post is a bit sparse...but I'm doing my best. [...]
Feb 13