Re: Ownership and Borrowing in D
On Tuesday, 23 July 2019 at 22:01:56 UTC, Sebastiaan Koppe wrote: So in a nutshell, a variable with the unique qualifier ensures that there are no other references to that data during the lifetime of said variable? In other words, you can only take 1 addressOf/ref at a time? Does it prevent more that just use-after-free? Can you ask again on the Github thread? I don't want to hijack this thread for 12 pages. (also, can you expand your question? I don't get what you're asking)
Re: Ownership and Borrowing in D
On Tuesday, 23 July 2019 at 14:18:27 UTC, Timon Gehr wrote: I think tying ownership/borrowing semantics to pointers instead of structs makes no sense; it's not necessary and it's not sufficient. Your use case illustrates why it is not sufficient. That's as good a time as any to plug my own proposal draft: https://gist.github.com/PoignardAzur/9896ddb17b9f6d6f3d0fa5e6fe1a7088 Any thoughts?
Re: Ownership and Borrowing in D
On Wednesday, 17 July 2019 at 20:59:27 UTC, Walter Bright wrote: I'm interested to see your design. But I suggest you move quickly, as I've suggested people who talked about this propose a design for the last 10 years, nothing has happened, and we can't wait any longer. For the record, I've been busy with WebAssembly proposals and haven't had the time to write a proper DIP this week. That said, here's a **very, very rough** draft that conveys what the proposed design is about: https://gist.github.com/PoignardAzur/9896ddb17b9f6d6f3d0fa5e6fe1a7088 I'll try to make a PR before next week-end.
Re: Ownership and Borrowing in D
On Tuesday, 16 July 2019 at 06:12:42 UTC, Walter Bright wrote: Now I just have to deliver the goods! Lately, I've been thinking about the possibility of an alternative ownership system for D, one that would be radically different from what you're considering, but still aim for the same features (memory safety, compile-time checking, zero-cost abstraction), based on a `unique` qualifier. If I were to write a formal proposal for it, how interested would you be in comparing the two schemes (DIP 1021 and eventually Rust "one mutable ref" rule, vs unique qualifier)? Like, I want to make my pitch, but I don't want to spend huge amount of effort on it if you're just going to go with DIP 1021 anyway.
Re: Ownership and Borrowing in D
On Monday, 15 July 2019 at 14:58:55 UTC, Mike Parker wrote: some folks asked for some information about the bigger picture. As one of the folks that asked for that information, thank you Walter for posting this :) The system described is a little rough around the edges, but it's really helpful to inform the discussion around DIP 1021!
Re: Priority DIP for Draft Review: Argument Ownership and Function Calls
On Wednesday, 26 June 2019 at 10:51:33 UTC, Mike Parker wrote: https://github.com/dlang/DIPs/pull/158 I'm going to be candid here: Based on past experience, I'm worried that: - This DIP will generate a lot of negative feedback. - Walter will ignore most of that feedback, or cherry-pick a few arguments that resonate with him, and ignore the others. - People will ask for a more formal specification, and Walter will refuse on the ground that he isn't a PL theorist / that the DIP is only a first step towards a more complete borrowing scheme. - Walter will not lay out what that complete borrowing scheme looks like, on the grounds that it's too early to tell. - Because of its importance for future features, the DIP is going to be rushed despite the unnadressed criticisms. Can we get some assurance this isn't going to be the case? I'm particularly interested in flow analysis features, and I think I have something to contribute, but I don't want to spend a large amount of effort debating and suggesting alternatives if I expect to be stonewalled.
Re: Phobos is now compiled with -preview=dip1000
On Saturday, 18 May 2019 at 19:44:37 UTC, Walter Bright wrote: If all access to internals is returned by ref, those lifetimes are restricted to the current expression. Oh my god, I try my best to be open-minded, but talking about dip1000 design with you is like pulling teeth *at best*. Yes, containers work perfectly if you allocate them on the stack and use their contents during the current stack frame, and then de-allocate them statically. By definition, this represents 0% of the use cases of dynamic containers. Dynamic containers need methods like "push_back", "reserve", "resize", "concatenate" or "clear", which are all impossible to implement with dip1000 without making their implementations trusted, which in turns opens up the program to use-after-free memory corruption. See also: https://forum.dlang.org/post/qbbipvkjqjeweasxk...@forum.dlang.org https://forum.dlang.org/post/rxmwjjphnmkszaxon...@forum.dlang.org Have you talked to Atila Neves at all for the past six months? Why the hell are we having this discussion? This is not a new issue. I have raised it repeatedly in the past (I can even dig up the posts if you're interested; I remember writing a fairly in-depth analysis at some point). Atila's automem and Skoppe's spasm have the same limitation: you can't reallocate memory without writing unsafe code (I'm told spasm gets around that by never deallocating anything). Honestly, the fact that you're the only person with a coherent vision of dip1000, and yet you keep ignoring problems when they're pointed out to you is both worrying and infuriating. Eg: So far, the only real shortcoming in the initial design was revealed by the put() semantics, and was fixed with that PR that transmitted scope-ness through the first argument. Like, yes, I understand that dip1000 is an achievement even if it doesn't allow for resizable containers, and that immutable already allow for functional programming patterns and that's great, but you need to stop acting like everything's going perfect when community members (including highly involved library writers) have complained about the same things over and over again (imprecise semantics, lack of documentation, the resize() use case) and you've kept ignoring them. Seriously, I'm not asking for much. I'm not demanding you take any architecture decision or redesign the language (like some people are prone to demanding here). But it would be nice if you stopped acting like you didn't read a word I wrote, over and over again.
Re: Phobos is now compiled with -preview=dip1000
On Friday, 17 May 2019 at 20:04:42 UTC, Walter Bright wrote: Dip1000 is key to enable containers to control access to pointers to their innards that they expose. I haven't looked at the subject for a while, but every time I did the takeaway was the same: dip1000 works great for containers until you need to reallocate or free something, at which point it's back to @trusted code with you. I think you said at some point "It's still useful, because it reduces the surface of code that needs to be checked", but even then saying containers can "control access to the data they expose" is a little optimistic. They only control that access as long as you don't need to call resize(). I'd wager that a large fraction of dangling pointer errors made by non-beginner C++ developpers come specifically from this use case.
Re: DIP 1000--Scoped Pointers--Superseded
On Thursday, 7 March 2019 at 14:24:29 UTC, Mike Parker wrote: The implementation supersedes the DIP. I think the question a lot of people have in mind is "Is there any plan to formally organize a discussion about the future of scoped pointers?" More specifically, are you planning a new DIP discussing the semantics of scope and return scope, ideally one that would take into account previous feedback, address concerns that DIP-1000 had originally inspired, and include an analysis of the pros and cons of -dip1000's implementation, as reported by its current users? Less formally, what I mean is that a lot of people had concerns at the time DIP-1000 was discussed; many of these concerns (including mine) weren't really addressed, and Walter's reaction gave the impression that he didn't understand them, and as a result, considered them unimportant, which led to a lot of frustration (including, if I remember correctly, Dicebot stepping down as DIP manager) and a general break in communication between Walter and the community. So, considering how important scoped pointers are to the language (betterC, webasm, video games, C++ interop, competing with Rust), I think (and I realize this is a lot to ask) that this is an area where Walter needs to bite the bullet and make a sustained effort to interact with the community and address DIP-1000's problems, whether by starting another DIP or through some other mean. If nothing else, we should probably have a "Who here uses -dip1000, and does it work for you?" thread.
Re: DIP 1018--The Copy Constructor--Formal Review
On Thursday, 28 February 2019 at 01:42:13 UTC, Andrei Alexandrescu wrote: Such sharing of resources across objects is a common occurrence, which would be impeded by forcing `const` on the right-hand side of a copy. (An inferior workaround would be to selectively cast `const` away inside the copy constructor, which is obviously undesirable.) For that reason this DIP proposes allowing mutable copy sources. There's an argument to be made that a copy constructor isn't the best way to share resources between two variables in a way that might affect code using the variable being copied.
Re: Project Highlight: Spasm
On Friday, 1 March 2019 at 14:27:36 UTC, Sebastiaan Koppe wrote: That would be awesome. I initially tried very hard to stick to React/JSX functional rendering. I could not find a way to make it a zero-cost abstraction, but maybe you have more success! I'll create an issue once I've written down my thoughts on the subject.
Re: Project Highlight: Spasm
On Thursday, 28 February 2019 at 12:24:27 UTC, Mike Parker wrote: The Blog: https://dlang.org/blog/2019/02/28/project-highlight-spasm/ Reddit: https://www.reddit.com/r/programming/comments/avqioi/spasm_d_to_webassembly_for_single_page_apps/ I've seen spasm around quite a few times, but reading this article has made me want to actually take a look at the documentation and try to understand how the library works. Would the author be interested in structural level-feedback? As in, not "I wish there was this feature", but "I think the way you're doing X and Y is wrong, and the project would probably benefit from a complete refactoring". I realize this kind of feedback is pretty irritating to get and hard to act on several months into the project, hence why I'm asking. The short version is, it's pretty clear Sebastiaan has designed spasm with the goal of giving the library compile-time information on the structure of the widgets to render, to avoid React's superfluous updates and prop comparison; that said, I think it's possible to give the library that information without losing React's "your components are all functions, don't worry about how the data is updated" simplicity, which I think is an area where spasm comes up short. Anyway, I'm ready to spend more time documenting for a deeper analysis if Sebastiaan is interested.
Re: DIP 1018--The Copy Constructor--Formal Review
On Monday, 25 February 2019 at 22:45:38 UTC, Olivier FAURE wrote: For the same reason C++'s std::shared_pointer uses a non-const copy constructor. Wait, no, I just checked, std::shared_pointer's copy constructor is const, even though it changes shared data. Ugh, that's just wrong. (I kind of agree with Walter's point; I totally assumed the constructor would be non-const, since it mutates data it receives)
Re: DIP 1018--The Copy Constructor--Formal Review
On Monday, 25 February 2019 at 16:00:54 UTC, Andrei Alexandrescu wrote: Thorough feedback has been given, likely more so than for any other submission. A summary for the recommended steps to take can be found here: https://forum.dlang.org/post/q2u429$1cmg$1...@digitalmars.com It is not desirable to demand reviewers to do more work on the review or to defend it. Acceptance by bullying is unlikely to create good results. The target of work is squarely the proposal itself. Agreed. Honestly, I am not impressed with the behavior of several members here. I understand that the rvalue DIP went through a long process, that some people really wanted it to be accepted, and that it was frustrating to wait so long only for it to be refused, but at some point, you guys have to accept that the people in charge refused it. They explained why they did, their reasons matched concerns other users had, and they explained how to move the proposal forward. So again, I get that this is frustrating, but repeatedly complaining and asking for an appeal and protesting about other DIPs being accepted is *not* professional behavior. Reviewers are entitled to refuse contributions for any reasons, and if a reviewer rejects a proposal, too bad; you don't get to ask again and again and complain and bring it up in every other thread until they say yes. Yes, this DIP was fast-tracked. Yes, this can feel unfair. And yet, it makes sense that it was fast-tracked, because it fits a priority of the project owners (C++ interoperability + reference counting) and project owners are allowed to have priorities. It's not like this DIP was rushed or has major vulnerabilities (the "mutable copy constructor" thing is necessary for reference counting).
Re: DIP 1018--The Copy Constructor--Formal Review
On Monday, 25 February 2019 at 20:41:58 UTC, Paolo Invernizzi wrote: Honestly, I've not understood the rationale or the covered use case in letting the copy ctor mutate the ref source parameters... Sincerely, without polemical intent. - P For the same reason C++'s std::shared_pointer uses a non-const copy constructor.
Re: DIP 1018--The Copy Constructor--Formal Review
On Sunday, 24 February 2019 at 12:57:06 UTC, ag0aep6g wrote: On 24.02.19 11:46, Mike Parker wrote: Walter provided feedback on Razvan's implementation. When it reached a state with which he was satisfied, he gave the green light for acceptance. Sounds like it might be a "worst acceptable proposal" [1] which Andrei says the DIP process is supposed to avoid. [1] https://forum.dlang.org/post/q2ndr8$15gm$1...@digitalmars.com If I'm understanding correctly, Andrei said that about the proposals, while Walter gave feedback on the implementation, which is a little different. But yeah, the proposal was clearly fast-tracked, probably because it's needed for reference counting and better C++ integration.
Re: DIP 1016--ref T accepts r-values--Formal Assessment
On Friday, 1 February 2019 at 09:10:15 UTC, aliak wrote: Shouldn't doubleMyValue(pt.x) be a compiler error if pt.x is a getter? For it not to be a compile error pt.x should also have a setter, in which case the code needs to be lowered to something else: The thing is, D doesn't really differentiate between a getter and any other method. So with DIP-1016, when given doubleMyValue(pt.x); The compiler would assume the programmer means - Call pt.x() - Store the result in a temporary - Pass that temporary as a ref parameter to doubleMyValue At no point is the compiler aware that the user intends for x to be interpreted as a getter.
Re: DIP 1016--ref T accepts r-values--Formal Assessment
On Thursday, 31 January 2019 at 21:50:32 UTC, Steven Schveighoffer wrote: How is the problem not in doubleMyValue? It's sole purpose is to update an lvalue. It is the perfect candidate to mark with @disable for rvalues. But right now, updating an rvalue is what ref is supposed to be used for. Besides, the fact remains that accepting DIP 1016 would add a new corner case with the potential to create hard-to-detect bugs, which feels to me like it should be a dealbreaker. The fact that this corner case can be patched using @disable isn't good enough, because: - Existing codebases that use ref won't have the @disable patch, which means using them will become (slightly) dangerous because of DIP 1016. - Making libraries that behave predictably should be the default path (the "pit of success" philosophy), not require an additional construct. Besides, D's type system should be more than capable of consistently telling the user "Be careful, you're modifying a temporary when it's probably not what you meant". --- An alternate proposal that just came to mind: allowing the user to pass rvalues to ref arguments with the following syntax: y = doubleMyValue(cast(ref)10); This syntax would avoid creating ambiguous situations where the compiler thinks you're passing it a getter's return as a temporary when you're trying to pass the attribute that the getter maps to. Eg, the following code: y = doubleMyValue(pt.x); would still fail the same way it currently does when Point.x() is a getter.
Re: DIP 1016--ref T accepts r-values--Formal Assessment
On Thursday, 31 January 2019 at 21:57:21 UTC, Steven Schveighoffer wrote: That being said, you can look at the fact that most people don't even know about this problem, even seasoned veterans, as a sign that it's really not a big problem. Isn't it a recurring theme on this forum that D is really cool but also kind of obnoxious because of weird corner cases that veterans know, but aren't documented anywhere?
Re: DIP 1016--ref T accepts r-values--Formal Assessment
On Thursday, 31 January 2019 at 21:44:53 UTC, jmh530 wrote: It doesn't compile with dip1000 without first giving the getter functions a return attribute for this. But it still compiles with -dip1000 once you give x() and y() return attributes, even though what's happening is clearly different from what the user wants (and the compiler has enough info to know that).
Re: DIP 1016--ref T accepts r-values--Formal Assessment
On Thursday, 31 January 2019 at 18:31:22 UTC, Steven Schveighoffer wrote: BTW, the DIP discusses how to annotate these rare situations: int doubleMyValue(ref int x) { ... } @disable int doubleMyValue(int x); -Steve I don't think that's a solution. The problem is in the getter method, not in doubleMyValue. If nothing else, since the DIP is designed to work on existing functions, it could happen on doubleMyValue functions which would be both designed by and used by people completely unaware of DIP-1016.
Re: DIP 1016--ref T accepts r-values--Formal Assessment
On Thursday, 31 January 2019 at 16:38:42 UTC, Steven Schveighoffer wrote: Yeah, that's already a thing that ref in D doesn't protect against: It took me a while to understand what the compiler was doing. This really feels like something that shouldn't compile.
Re: DIP 1016--ref T accepts r-values--Formal Assessment
On Thursday, 31 January 2019 at 02:10:05 UTC, Manu wrote: I still can't see a truck-sized hole. I don't know if it's truck-sized, but here's another corner case: int doubleMyValue(ref int x) { x *= 2; return x; } Point pt; pt.x = 5; pt.y = foobar(); doubleMyValue(pt.x); assert(pt.x == 10); Question: in the above code, will the assertion pass? Answer: it depends on Point's implementation. If x is a member variable, then yes. If it's a getter, then doubleMyValue will take a rvalue and x won't be mutated and the assertion will fail. I think this is a non-trivial conceptual problem.
Re: DIP 1016--ref T accepts r-values--Formal Assessment
On Monday, 28 January 2019 at 17:23:51 UTC, Andrei Alexandrescu wrote: * Regarding the argument "why not make this an iterative process where concerns are raised and incrementally addressed?" We modeled the DIP process after similar processes - conference papers, journal papers, proposals in other languages. There is a proposal by one or more responsibles, perfected by a community review, and submitted for review. This encourages building a strong proposal - as strong as can be - prior to submission. Washing that down to a negotiation between the proposers and the reviewers leads to a "worst acceptable proposal" state of affairs in which proposers are incentivized to submit the least-effort proposal, reactively change it as issues are raised by reviewers. Fair enough.
Re: DIP 1016--ref T accepts r-values--Formal Assessment
On Friday, 25 January 2019 at 11:56:58 UTC, Walter Bright wrote: All that criticism aside, I'd like to see rvalue references in D. But the DIP needs significant work. I haven't participated to writing this DIP, but I personally appreciate this level of feedback. I think it would have been more appreciated if the original answer had that level of detail. Otherwise, I don't think this should be an all-or-nothing situation. It would make sense to bump the DIP back one stage or two for minor adjustments, and if the author decide that they need to make major changes to get past the problems you mention, require these changes to go through the entire process again (through another DIP).
Re: A brief survey of build tools, focused on D
On Sunday, 16 December 2018 at 00:17:55 UTC, Paul Backus wrote: There's something important you're glossing over here, which is that, in the general case, there's no single obvious or natural way to compose two DAGs together. For example: suppose project A's DAG has two "output" vertices (i.e., they have no outgoing edges), one corresponding to a "debug" build and one corresponding to a "release" build. Now suppose project B would like to depend on project A. For this to happen, our hypothetical DAG import function needs to add one or more edges that connect A's DAG to B's DAG. The question is, how many edges, and which vertices should these edges connect? That doesn't seem right. Surely you could write externalDependencies = [ someSubmodule.release ] in your language-specific build tool, and have it convert to an equivalent import edge targeting the correct vertice in the standardized dependency graph? It might be inconvenient in some cases (eg you have to manually tell your tool to import someSubmodule.release in release mode and someSubmodule.debug in debug mode), but it would still be infinitely more convenient and elegant than the current "multiple incompatible build tools per language, and shell/make scripts to link them together" paradigm. Especially with the increasing usability of WebAsm, it would be nice to have a standard build model to link multiple modules in different languages together into a single wasm binary. A standardized DAG model would also help making a project-wide equivalent to the Language Server Protocol. (I'm not convinced by BSP)
Re: DIP 1003 (Remove body as a Keyword) Accepted!
On Friday, 2 June 2017 at 14:17:10 UTC, Mike Parker wrote: https://github.com/dlang/DIPs/blob/master/DIPs/DIP1003.md The "See the previous version" link at the end of the document is currently broken and leads to a 404. Thank you for your efforts and congratulations to Jared Hanson!
Re: Release D 2.073.0
Continuing on a new thread because this is getting kinda off-topic. http://forum.dlang.org/post/jhtvuvhxsayjatsdb...@forum.dlang.org
Re: Release D 2.073.0
On Saturday, 28 January 2017 at 22:31:23 UTC, Walter Bright wrote: It only addresses cases where a reference might be escaped through a single return value; it doesn't address escaping through 'out' parameters, Yes it does (the general case is storing a value into any data structure pointed to by an argument). I don't understand. Let's say I have an arbitrary class 'Container', and I want a function that stores a pointer to an int in this container, in a way that lets the function's caller know that the int* given to it will last only as long as the container, and I want to do it without return values. The prototype would be akin to void store(ref Container cont, int* ptr); And the code it would be used in would look like: { scope Container c; scope int* ptr = ...; store(c, ptr); } What would the syntax be? or through a returned tuple. Yes it does (it's as if the tuple elements were fields of a struct). I meant a little more specific. You have no way to do this Pair!(int*, float*) makePair( int*, float*); You can declare them both a scope return, but then their scope is "merged" into the return value, which may be undesirable if you want to treat them differently. Although it's not that important, because this particular case would rarely appear in actual practical code, unlike swap and out parameters. There will be a need for @system code for some things, that is correct. That's also true of Rust, where cyclic data structures have to be marked as unsafe, and functions cannot access mutable global data. Yeah, but cyclic data structures and complex types are one thing. I'm just talking about having a (scope int*)[] type, and a swap function. Those should be covered in the scope system, and shouldn't need GC or RC. Nobody has come up with a better plan. A Rust-like system would require users to not just add annotations, but redesign all their code and data structures. It's out of the question. There has been off and on for about 10 years. Little has come of it. Then came -dip25, which addressed the return ref problem. It worked surprisingly well. There was some severe criticism of it last year as being unusable, but those turned out to be implementation bugs that were not difficult to resolve. Well, I liked Schultz's original proposal. It seemed easier to theorize formally, and didn't need major redesign the way Rust's templates do. And having read the thread it was proposed in... I didn't see any brainstorming? It seems to me that dip25 replaced Schult's proposal without transition, or without debate about the merits and trade-offs of either proposition, or any rationale explaining why Schultz's proposition was abandoned. It's fair if you don't agree with my rationale, but that isn't the same as not addressing them at all. I believe I have addressed the issues you brought up here. If you'd like further clarification, please ask. I'll probably have more to say on that later, but I think THIS is the major point of contention. I don't feel like you've addressed my concerns, because I'm pretty sure you haven't understood my concerns. You interpreted my remarks as obstacles to be overcome, not as information I was trying to communicate to you. I feel like your opinion is that the reason I'm arguing against dip1000 is that I don't understand it or its context well enough. I feel you have the same opinion of others people who argue against the dip. This is what I meant by "not being taken seriously". I didn't write that. Sorry, I was replying another poster above in the thread. I'm not used to mailing list forums.
Re: Release D 2.073.0
On Saturday, 28 January 2017 at 03:40:43 UTC, Walter Bright wrote: If you've got a case, make it. If you see problems, explain. If you want to help, please do. For what it's worth, here are my problems with 'return scope': - As far as I can tell, it's not properly documented. The github page for DIP-1000 is apparently pending a rewrite, and I can't find a formal definition of 'return scope' anywhere (the D reference 'Functions' page only mentions 'return ref', and in passing). - I personally don't like using the return keyword as anything but an instruction; when I'm reading code, I can have a good feeling of the code's flow by just looking at the indentation, the if/while/for blocks, and the break/throw/return instructions. I'll be the first to admit it's kind of minor though. - It's an obvious monkey patch, and it will clearly have to be replaced at some point. It only addresses cases where a reference might be escaped through a single return value; it doesn't address escaping through 'out' parameters, or through a returned tuple. - It fails to enable useful features like the swap function, or storing a scoped value in a container (well, outside of @trusted code, but that's beside the point). - Because it isn't an integral part of the type system, but more of an external addition, it has a ton of special cases and little gotcha's when you try to do something complex with it. (ref parameters can't be scope, can't have pointers on scope values, which means you can't pass any kind of scope value by reference, you can't have scope types as template parameters, etc) The two last ones feel like the most important problems to me. If all you want to do is variants of the identity function, and returning references to attributes, then return ref and return scope is everything you need (arguably). If you want to store containers of scoped values, swap scope values, and generally treat scope as a first-class citizen, then return scope and return ref seem like a step in the wrong direction. The meta problem people seem to have with 'return scope' seems more of a social problem. Apparently a lot of people feel like you haven't treated their concerns seriously; part of it is that as far as I'm aware there hasn't been a proper, open brainstorming on how to address lifetime analysis in D. My reading of the situation, which may be completely off-base, is that you took inspiration from Marc Schütz's proposal, and wrote something simpler, easier to understand and to code with, and following the model you developed when coming up with inout (no templates, KISS, don't use up too much language complexity estate on an optional feature), then entered a cycle of gradually improving it, eventually making DIP-1000. People who don't like the direction DIP-1000 goes towards are upset because they feel way too much effort is going towards refining an idea they don't agree with in the first place. To speak bluntly, I don't think you've addressed their concerns at all, and I hope you do so before 'scope return' is set in stone. So, do what numerous people have done numerous times already, to no great effect? Please don't be hostile. When you have a communication problem, being passive-aggressive will only makes it worse.