Re: DIP 1014
On 10/2/18 1:51 PM, Manu wrote: But dangling pointer is an instant crash/memory corruption... it's a pretty bad 'bug'. Yeah doesn't sound very brilliant. I think such a workaround wouldn't fare well. To keep momentum while we mull over a solution to this I suggest you look at porting other data structures.
Deep nesting vs early returns
Kate Gregory makes a good argument on something I've often commented in code reviews: https://youtu.be/n0Ak6xtVXno?t=2682
Fwd: Copy Constructor DIP and implementation
This should probably have been posted here. -- Andrei Forwarded Message Subject: Copy Constructor DIP and implementation Date: Tue, 11 Sep 2018 15:08:33 + From: RazvanN Organization: Digital Mars Newsgroups: digitalmars.D.announce Hello everyone, I have finished writing the last details of the copy constructor DIP[1] and also I have published the first implementation [2]. As I wrongfully made a PR for the DIP queue in the early stages of the development of the DIP, I want to announce this way that the DIP is ready for the draft review now. Those who are familiar with the compiler, please take a look at the implementation and help me improve it! Thanks, RazvanN [1] https://github.com/dlang/DIPs/pull/129 [2] https://github.com/dlang/dmd/pull/8688
Re: More fun with autodecoding
On 9/10/18 12:46 PM, Steven Schveighoffer wrote: On 9/10/18 8:58 AM, Steven Schveighoffer wrote: I'll have to figure out why my specialized range doesn't allow splitting based on " ". And the answer is: I'm an idiot. Forgot to define empty :) Also my slicing operator accepted ints and not size_t. I guess a better error message would be in order.
Re: Java also has chained exceptions, done manually
On 9/7/18 7:15 PM, Tobias Mueller wrote: On Thursday, 6 September 2018 at 14:39:12 UTC, Andrei Alexandrescu wrote: Second, it does pay to keep abreast other languages. I had no idea (and am quite ashamed of it) that Java also has chained exceptions: https://www.geeksforgeeks.org/chained-exceptions-java/ Now I'm surprised... is there a language (except C++) that supports exceptions that does _not_ have it? Java: getCause() C#: InnerException PHP: getPrevious() ... David Nadlinger wrote that Python also has them. I think chained exception in D is semantically very different from other languages like Java. In languages like Java or C# the exception chain has nothing to do with saving exceptions that are thrown in finally blocks. Instead the chain is used for a layer model. The "outer" exception is the higher level exception and the "inner" exception is the lower level cause of the higher level exception. Often a low level exception is quite meaningless when thrown over multiple levels in the call stack. For example, imagine a program that uses a configuration file. While parsing the configuration, a misformatted number is encountered. If the NumberFormatException is propagated to the top level, it is basically useless for programmatic error handling. This is much better: ConfigurationException -> JsonParsingException -> NumberFormatException The higher level exceptions are therefore directly caused by the lower level exception and always thrown _directly_ in the catch block where the lower level exception is catched and readily available. Not in a finally block and not indirectly in a function called from the catch block. Manually passing the inner exception to the constructor of the outer exception is trivial and IMO the right thing, because it's probably not always wanted. Now in D, chained exceptions work differently. The first exception that is thrown is deemed the "important" exception and later exceptions are simply chained to it. A direct semantic connection between the exceptions is not possible at all, since the later exception has no knowledge about the first exception at all. It also means that the order of the exceptions is reversed. The first exception is the "outer" exception which is the exact opposite of how it is meant in Java. When handling an exception, it's not clear at all what those additional exceptions mean and how they should be handled. Personally I find the Java/C# model much more useful. Well indeed the upper you are on the stack, the more likely you are in a high-level function. It's a good heuristic. Sadly we cannot change chaining semantics now, but it does stand to reason to print the last exception in a chain, instead of the head, as the most relevant cause. Guess we'd do good to have such functionality in the stdlib. Andrei
Re: Java also has chained exceptions, done manually
On 9/6/18 1:13 PM, Neia Neutuladh wrote: The actual structure of the exceptions: `primary` has children `scope 2` and `scope 1`; `scope 2` has child `cause 2`; `scope 1` has child `cause 1`. A tree. No, it's a list. The encoded structure: a linked list where only the first two positions have any structure-related meaning and the rest are just a sort of mish-mash. This isn't a situation you get in Java because Java doesn't have a way to enqueue multiple independent actions at the end of the same block. You just have try/finally and try(closeable). (As an aside, it does seem we could allow some weird cases where people rethrow some exception down the chain, thus creating loops. Hopefully that's handled properly.) Not if you semi-manually create the loop: auto e = new Exception("root"); scope (exit) throw new Exception("scope 1", e); throw e; Filed as https://issues.dlang.org/show_bug.cgi?id=19231 Thanks! Andrei
Java also has chained exceptions, done manually
In an earlier post, Don Clugston wrote: When I originally implemented this, I discovered that the idea of "chained exceptions" was hopeless naive. The idea was that while processing one exception, if you encounter a second one, and you chain them together. Then you get a third, fourth, etc. The problem is that it's much more complicated than that. Each of the exceptions can be a chain of exceptions themselves. This means that you don't end up with a chain of exceptions, but rather a tree of exceptions. That's why there are those really nasty test cases in the test suite. The examples in the test suite are very difficult to understand if you expect it to be a simple chain! On the one hand, I was very proud that I was able to work out the barely-documented behaviour of Windows SEH, and it was really thorough. In the initial implementation, all the complexity was covered. It wasn't the bugfix-driven-development which dmd usually operates under . But on the other hand, once you can see all of the complexity, exception chaining becomes much less convincing as a concept. Sure, the full exception tree is available in the final exception which you catch. But, is it of any use? I doubt it very much. It's pretty clearly a nett loss to the language, it increases complexity with negligible benefit. Fortunately in this case, the cost isn't really high. First off, there's no tree of exceptions simply because... well it's not there. There is on field "next", not two fields "left" and "right". It's a linear list, not a tree. During construction there might be the situation whereby two lists need to be merged. But they will be merged by necessity into a singly-linked list, not a tree, because we have no structural representation of a tree. (As an aside, it does seem we could allow some weird cases where people rethrow some exception down the chain, thus creating loops. Hopefully that's handled properly.) Second, it does pay to keep abreast other languages. I had no idea (and am quite ashamed of it) that Java also has chained exceptions: https://www.geeksforgeeks.org/chained-exceptions-java/ They implement them manually, i.e. the user who throws a new exception would need to pass the existing exception (or exception chain) as an argument to the new exception's constructor. Otherwise, an exception thrown from a catch/finally block obliterates the existing exception and replaces it with the new one: https://stackoverflow.com/questions/3779285/exception-thrown-in-catch-and-finally-clause So chaining exceptions in Java is a nice complementary mechanism to compensate for that loss in information: when you throw, you have the chance to chain the current exception so it doesn't get ignored. Because of that, D's chained exceptions mechanism can be seen as an automated way of doing "the right thing" in Java. We should study similarities and distinctions with Java's mechanism and discuss them in our documentation. Andrei
[OT] Leverage Points
A friend recommended this article: http://donellameadows.org/archives/leverage-points-places-to-intervene-in-a-system/ I found it awesome and would recommend to anyone in this community. Worth a close read - no skimming, no tl;rd etc. The question applicable to us - where are the best leverage points in making the D language more successful. Andrei
Re: Signed DMD binaries
On 8/15/18 7:44 PM, Manu wrote: Indeed, it's the installer that's in critical need of being signed... but all the binaries are worth signing if that's convenient. But the installer is definitely priority #1!:) Any chance we could delegate some of the effort of working on this to you? Are other Windows users interested in helping? Martin has spent a fair amount of time dealing with this, and he's not a Windows expert. We could definitely use some help here.
Re: High-level vision for 2018 H2?
On 8/13/18 10:06 AM, walker wrote: I am curious about the plan of 2018/H2 version also, the H1 is very promising and may be hard to summarize its output. Thanks for the interest. We're behind this mainly because we're working on a HOPL submission. I'll try to delegate.
Re: Found on proggit: Nim receives funding from a company (D should be doing something like this)
On 8/15/18 5:31 PM, Matheus wrote: On Wednesday, 15 August 2018 at 20:45:34 UTC, Andrei Alexandrescu wrote: ... We are in talks with a few more students from Romania and Brazil... I'm from Brazil and I use D for hobby projects. It would be nice to present them later, in fact I was interested to create D group around here and maybe these Brazilian students may help. Matheus. Will keep that in mind. BTW there's a fledgling idea to hold a C++/D/systems programming conference in Belo Horizonte.
Re: Found on proggit: Nim receives funding from a company (D should be doing something like this)
On 8/13/18 5:50 AM, Joakim wrote: Announced last week, the Nim team will be adding two full-time paid devs and setting up grants for needed projects with this new funding: https://our.status.im/status-partners-with-the-team-behind-the-programming-language-nim/ https://nim-lang.org/blog/2018/08/07/nim-partners-with-status.html D should also be trying to raise resources like this, though it doesn't have to be corporate funding from one source. This company funding Nim raised $100 million in an ICO last year to build some kind of cryptocurrency-oriented mobile apps platform: https://www.inc.com/brian-d-evans/status-ico-raised-over-100-million-for-ethereum-powered-dapps-on-ios-and-androi.html There are risks, of course. This company could flame out, like many of these new cryptocurrency companies do, leaving Nim without ongoing funding. Their priorities may not align with the Nim core team. However, there are other ways to raise funds. Companies using D could use the existing bountysource page to put up bounties for features/fixes or projects they need, to which community members who need some particular feature/fix could also donate: https://www.bountysource.com/teams/d There are two primary factors in the success of any project, design and resources. I'm reasonably happy with the design of D and how technical decisions are being made. I think this is a core strength of D. However, it appears the D core team has so far been doing a horrible job in gathering resources for the project. I'm not privy to any internal discussions or if this is being discussed at all. But it needs to be a priority for the ongoing growth of this project. Thanks for the info. That's good for Nim and something we could definitely benefit from as well. Currently, Sebastian Wilzbach and Razvan Nitu, both students, are working full time with the Foundation. Mike is our publishing and general PR person, working a reliable part time. We are in talks with a few more students from Romania and Brazil. Our early experiments with bountysource were sadly unsuccessful. I'm not writing it off but we'd probably need a new angle for a new round of experimentation. Suggestions are welcome. Regarding corporate sponsorship, we have been public about being interested, but we haven't exactly beaten off offers with a stick. I have personally asked our top users in several instances for assistance. There has been some, but not to the extent of allocating one or more full-time engineers. Shout out to Laeeth Isharc whose enterprise has been far and away the most generous, and to Weka as well for sharing with us some time and resources at a crucial juncture for the company. We've always been glad to take suggestions from individual collaborators. Mike Parker would be the person to reach out to. What would be best is to get some concrete action; historically, the typical suggestion came in the form "here's this great idea, you go work on it". Even that is fine if the idea is fleshed out and argued convincingly. Better yet, there's no better proof that an idea is good than to actually execute it to demonstrable benefit. Thanks, Andrei
Re: std.experimental.collections.rcstring and its integration in Phobos
On 7/17/18 12:58 PM, Jonathan M Davis wrote: If it's not a range by default, why would you expect_anything_ which operates on ranges to work with rcstring directly? Many functions do not care about the range aspect, but do care about the string aspect. Consider e.g. chdir.
Re: Anyone can contact Dmitry Olshansky?
Thanks, Dave, for the good points. All: please refrain from commenting on the mental disposition of community members publicly. Thanks, Andrei
Re: Copy Constructor DIP
On 7/17/18 12:04 AM, Manu wrote: But that's the point, and the key advantage of the name ;) [:nod:]
Shopping on Amazon on Prime Day (and beyond)? Support the D language!
Amazon has a nonprofit arm: https://smile.amazon.com Go there and choose The D Language Foundation as your charity of choice, then shop normally through smile.amazon.com. A fraction of your expenditure will go to the Foundation. Thanks, Andrei
Re: Copy Constructor DIP
On 7/16/18 8:57 PM, docandrew wrote: I think in this case, a more obscure name like @copyctor is more descriptive. On the contrary, it is redundant and uninformative. It applies to exactly a constructor that copies, so it adds no information. "@implicit" describes precisely what the attribute does.
Re: Copy Constructor DIP
On 7/16/18 3:12 PM, ag0aep6g wrote: On 07/16/2018 09:06 PM, Andrei Alexandrescu wrote: On 7/14/18 11:26 AM, Jacob Carlborg wrote: [...] That's easily fixed by implementing a compiler recognized UDA. That would mean that it would only be a copy constructor if "implicit" is defined in core.attribute. This would also avoid any special syntax in the parser. The already existing @selector is implemented like this. Affirmative. We're going that route, similar to "@safe" and "@nogc". @safe and @nogc are not compiler recognized UDAs. If you implement @implicit like them, then you're not doing what Jacob suggests. Then "negative" :o). In brief @implicit follows the same implementation as @safe and @nogc/
Re: Copy Constructor DIP
On 7/14/18 11:26 AM, Jacob Carlborg wrote: On Friday, 13 July 2018 at 01:18:48 UTC, Andrei Alexandrescu wrote: On 7/12/18 2:30 PM, ag0aep6g wrote: You're still potentially changing the semantics of existing code. `@implicit` can be a UDA today: enum implicit = 0; struct C { @implicit this(ref C another) {} } Today, that's a normal constructor. With the DIP, it becomes a copy constructor. That is correct and a liability of the current DIP. That should be mentioned in it. That's easily fixed by implementing a compiler recognized UDA. That would mean that it would only be a copy constructor if "implicit" is defined in core.attribute. This would also avoid any special syntax in the parser. The already existing @selector is implemented like this. Affirmative. We're going that route, similar to "@safe" and "@nogc".
Re: What determines if an algorithm goes in std.algorithm or std.range
On 7/14/18 5:32 PM, aliak wrote: Alo, I'm wondering how phobos devs view or determine what goes in to std.algorithm and what goes in to std.range. To me some of them are quite obvious - well, most things can arguably be an algorithm. But for example "refRange" is clearly a range specific thing, but "transpose" is not. And things that create ranges from nothing also may "clearly" belong in the range module? (e.g. iota, generate and recurrence) Also curious, are there any github PRs in phobos where certain algorithms were discussed as going in to where and what the reasonings were? cheers - Ali There is no hard and fast rule. If it does something one would naturally associate with an algorithm (e.g. it would belong in a book on algorithms etc), it belongs in std.algorithm even if it processes ranges. If something is algorithmically trivial but support ranges, then it belongs in std.range. Without looking: where should "chain" belong? It's a trivial algorithm but has a variety of intricacies for supporting different kinds of ranges. So it's in std.range. Andrei
Re: Copy Constructor DIP
On 7/14/18 5:03 AM, Luís Marques wrote: If there is "no other meaning of @implicit" (other than the intersection of those two properties) why don't you just call it something like @copyctor? I'm totally cool with giving the attribute a more obscure name such as @copyctor or anything people want really. (What follows is a personal opinion. I think it's better to choose a more general attribute name with reduced initial applicability. Then application of said attribute can be extended to other functions with ease. In contrast, an obscure attribute name is sure to be followed by more obscure attribute names. And don't get me started about inventing new syntax. Regarding the hand-wringing over generality: we have an exceedingly poor record of paralysis of analysis, whereby we'd worry that every design decision potentially locks us out from all other as-of-yet-unchosen design decisions. If history is any indication, this sudden worry about vaguely-promising green pastures of the future is a sign of malady. We want copy construction. Conflating this with a very general schemata for implicit conversion would not be a wise decision in my opinion. I now deeply regret ever telling Razvan to mention future possible directions. This DIP must do implicit copy constructors and do it well, nothing less and nothing more.) Andrei
Re: Copy Constructor DIP
On 7/13/18 5:49 PM, rikki cattermole wrote: On 14/07/2018 9:28 AM, Manu wrote: I've already contributed other points to this DIP in the way you describe. This one however is very strange, and I'm surprised you can find the hand-wavy introduction of a new attribute without any sense of where it's going to be okay. Or maybe, I'm surprised I'm the only one that finds problem with that. You are very much not alone. I didn't articulate it very clearly, but I am super not happy with such a new attribute. It's a very simple process - @implicit is not invented as much as a given. We need to distinguish a constructor from other constructors. The constructor supports attributes. Attributes are a mechanism for distinguishing declarations from other declarations. Ergo, an attribute is the mechanism of choice. Done deal. = If we don't like the use of an attribute, it means we somehow failed in defining attributes in the first place. (I don't think we did; attributes as defined in D are brilliant and currently underused.) It's poor language design to define a mechanism for doing a category of Xs and then explicitly avoiding it exactly when the opportunity of doing X arises. From that vantage point, the choice of an attribute to identify implicit copy construction is unassailably obvious, and elucubrated syntax inventions such as "@this", "this(ref this x)" are chucklesomely profligate and ridiculously baroque. Andrei
Re: Copy Constructor DIP
On 7/13/18 5:28 PM, Manu wrote: As I originally said, my feedback is concrete: specify @implicit, this DIP depends on it. The specification of @implicit is in the DIP in full: a constructor that takes by reference a qualified typeof(this) and has the @implicit attribute will be callable implicitly by the compiler. There is no other meaning of @implicit. That completes the spec of @implicit. Sadly we got to irreducible positions once again: you and I used different definitions for common terms like "define", "specify", "explain", "contribute", and then you use them to ask questions or make demands, all of which I'm sure you find reasonable. But I am unable to understand them, let alone take them under advisement when working on the DIP. (I did understand your reference to the assignment and will work on that, thanks much.) You will need to forgive me for the scarcity of my future answers - but believe me I will do my best to derive value from your feedback. Andrei
Re: Copy Constructor DIP
On 7/13/18 12:06 PM, xenon325 wrote: From the DIP: The copy constructor declaration will be recognized by the parser when the tokens @, implicit, this are encountered exactly in this order Regarding "exactly in this order". The code below would be allowed and define copy c'tor for `A` and usual c'tor for `B` ? struct implicit{} struct A { @safe @implicit this(ref A) {} } struct B { @implicit @safe this(ref B) {} } We'll change that part to accept the standard attribute syntax.
Re: Copy Constructor DIP
On 7/13/18 11:14 AM, Atila Neves wrote: On Friday, 13 July 2018 at 14:12:59 UTC, Andrei Alexandrescu wrote: On 7/13/18 8:31 AM, Atila Neves wrote: On Friday, 13 July 2018 at 03:01:25 UTC, Manu wrote: [...] https://github.com/search?q=%22this%5C%28ref%22+language%3AD&type=Code The answer seems to be: not many. Most of the results above are false positives because github won't let me escape the left parenthesis. A proposal that just works without any user intervention would definitely be attractive. The drawback is silent modification of code behavior. Consider: import std.stdio; struct A { this(ref immutable A obj) { writeln("x"); } } void main() { immutable A a1; A a2 = A(a1); A a3 = a1; } With the current language, "x" is printed once. If we make the ctor implicit, "x" is printed twice. In the "levels of hell" of semantics changes, probably the nicest is allowing code to compile that previously didn't. Then, refusing to compile code that previously did would be definitely bad. But if you want to drink the cup of disgrace to the bottom, you must reach for silent change of behavior. I agree on the levels of hell. I wasn't aware the kind of change above would happen - methinks it should be in the DIP. Great. Razvan, can you please add this example with discussion to the DIP (probably at the end of the Motivation section as an explanation why we need the addition of @implicit). Thanks. I think I now even understand why `@implicit` is there to begin with. I still think it's confusing, so imagine someone new to the language. Interesting. Coming from a C++ background makes the matter obvious because there's plenty of implicit vs. explicit discussion. To compensate for my bias - what do you think would be a better attribute name? Andrei
Re: Copy Constructor DIP
On 7/12/18 11:01 PM, Manu wrote: What existing code are you changing the semantics of? It's still not clear to me how accepting `this(ref T)` as a magic signature that is a copy constructor can break existing code? Is it the unlikely^^2 case that the function exists somewhere and doesn't perform copy construction? 1. the function is highly unlikely to exist because postblit; it's a meaningless function to write. are there any known instances of that signature in the wild? 2. if the function does exist, it's highly unlikely that it doesn't perform a valid copy construction; what else could it possibly do? 3. remaining cases are broken by this DIP, but they are probably crazy and deserve to be deprecated! Is there any reasonable existing use of the signature that would be legitimately broken by being invoked implicitly? I feel like there's something that I'm missing... but if there's not, then just change the semantic. I reason; copy construction is something so fundamental. It will be written by basically every programmer with relative high frequently, and adding awkward syntax or weird language baggage to the concept feels like a very poor choice. By contrast, if there's 1 user out there who used the copy-constructor signature to do some weird thing other than copy construction, and their code is broken by this change, his use case does not balance the imposition applied to every implementation of copy constructor forever from this time forward. This is so much more important than that, it's extremely fundamental language stuff, and needs to be as friction-less as possible, and it should certainly not reek of legacy drama. Noted. So in summary you would be okay with changing semantics of existing code, under the intuition that the change is unlikely to be destructive anyway.
Re: Copy Constructor DIP
On 7/12/18 11:45 PM, Manu wrote: On Thu, 12 Jul 2018 at 20:15, Meta via Digitalmars-d wrote: On Friday, 13 July 2018 at 02:32:59 UTC, Manu wrote: Seriously, if I was making this proposal to you, and you were in my position... there is no way in hell that you'd allow any of us to slip something so substantial by like that with the wave of a hand. This DIP depends on @implicit. How can you argue otherwise? Nothing is being slipped by as far as I'm concerned. @implicit is solely introduced in the DIP as a marker for the copy constructor, and it doesn't seem like it's intended for anything further than avoiding breaking code. It feels to me like you're making a mountain out of an ant hill. That's the whole point though. We're debating whether "@implicit" is a good idea. And it's the only detail of the DIP that feels noteworthy or contentious to me. The rest is pretty much common-sense, and long overdue. I can see myself getting behind 2 possibilities, no @implicit, or @implicit done right. A couple of simple ideas are making the process productive. One is to rely on facts instead of feelings. "It's weird" or "I don't like it" are less helpful than "semantics of this or that case are not covered". Another is precision. Stating vague goals and standards ("I want @implicit done well") and systematically asking others to actually put in the work is less desirable than providing concrete, motivated, actionable feedback. To the second point: we have a history of defining features too permissively, to then regret not having waited to accumulate experience. Starting with a restricted version then building on experience with it seems to be a much better strategy. From that perspective, introducing implicit only for restricted copy construction seems like a good step that doesn't take others, without precluding them. I don't see myself getting behind introduction of @implicit on such terms that it's nothing but "a marker for the copy constructor". So this 'mountain' is critical to understanding whether I can support this DIP as proposed or not. I'd put it a slightly different way. "Getting behind" and "supporting or not" suggests a position of power and an emphasis on the politics of the process. The natural counter to this would be asking whether your support is necessary, which put us all in a very unproductive position. The right emphasis is not getting your support on a given DIP, but instead us all benefiting of your active contribution to a better DIP. Thanks, Andrei
Re: Copy Constructor DIP
On 7/13/18 8:31 AM, Atila Neves wrote: On Friday, 13 July 2018 at 03:01:25 UTC, Manu wrote: On Thu, 12 Jul 2018 at 19:15, Andrei Alexandrescu via Digitalmars-d wrote: On 7/12/18 6:34 PM, Manu wrote: > On Thu, 12 Jul 2018 at 06:50, Andrei Alexandrescu via > Digitalmars-d wrote: >> [..] doesn't perform copy construction? 1. the function is highly unlikely to exist because postblit; it's a meaningless function to write. are there any known instances of that signature in the wild? https://github.com/search?q=%22this%5C%28ref%22+language%3AD&type=Code The answer seems to be: not many. Most of the results above are false positives because github won't let me escape the left parenthesis. A proposal that just works without any user intervention would definitely be attractive. The drawback is silent modification of code behavior. Consider: import std.stdio; struct A { this(ref immutable A obj) { writeln("x"); } } void main() { immutable A a1; A a2 = A(a1); A a3 = a1; } With the current language, "x" is printed once. If we make the ctor implicit, "x" is printed twice. In the "levels of hell" of semantics changes, probably the nicest is allowing code to compile that previously didn't. Then, refusing to compile code that previously did would be definitely bad. But if you want to drink the cup of disgrace to the bottom, you must reach for silent change of behavior.
Re: Copy Constructor DIP
On 7/12/18 10:05 PM, Manu wrote: On Thu, 12 Jul 2018 at 18:25, Andrei Alexandrescu via Digitalmars-d wrote: On 7/12/18 4:29 PM, Manu wrote: Being able to implement them both independently is*occasionally* useful, but 95% of the time, destruct + copy-construct is an equally efficient implementation for assignment. I'd suggest that this destruct+copy-construct pattern is a perfectly good substitute for assignment in most cases, and maybe the compiler should deploy the pattern as an implicit copy constructor in lieu of an explicit one? So, if the user specifies a complex copy constructor, but no assignment operator (which just blits on copy), then they've almost certainly introduced a bug on copying! Perhaps the compiler should automatically emit an assignment operator implemented as above in presence of a (suite of? [const/immutable/etc permutations]) 'complex' copy constructor? Not the charter of the current DIP. In a post-blit world, with no opAssign specified, postblit will call for copy construction AND for assignment, thereby assignment is always correct. Once postblit is swapped for a copy-constructor, absence of opAssign will result in invalid behaviour on assignment. Introduction of copy constructor breaks default assignment, it needs to address it somehow. I think my suggestion is the only practical solution. Affirmative. The DIP needs to specify how assignment is handled if no opAssign is present but a copy ctor is present. Thanks!
Re: Copy Constructor DIP
On 7/12/18 6:37 PM, Manu wrote: On Thu, 12 Jul 2018 at 07:15, Andrei Alexandrescu via Digitalmars-d wrote: On 07/12/2018 09:49 AM, Atila Neves wrote: On Thursday, 12 July 2018 at 06:54:37 UTC, RazvanN wrote: [...] If by "come in pairs" you mean that you can define them both, then yes, that is the case. Will add a paragraph in the DIP to specify this. You mentioned that it's terrible that the assignment operator and the copy constructor come in pairs. Why is that? Would you rather have a copy constructor that is used also as an assignment operator? Because, like in C++, now you have to implement both and make sure they do the same thing. Boilerplaty and a recipe for disaster. Atila There's no meaningful way to avoid that. The two operations are fundamentally different, are typechecked differently, and actually are different in the presence of qualifiers on fields. Introspection is a key helper here compared to C++. As I've said elsewhere, opAssign() can be fabricated by: this.destroy(); emplace(&this, copyFrom); Not if the object has immutable fields, is immutable itself, is assigned from an immutable object and has non-immutable indirections, etc. One issue the DIP is addressing carefully is copying across qualifier combinations. It also emphasizes how the current postblit fails at that. We should consider fabricating an implicit assignment operator in the presence of an elaborate copy constructor. Not in this DIP. As you say, this interacts with qualifiers... I don't think it's trivial, but I think it should be explored. Otherwise whenever anyone forgets to implement an assignment operator, it'll just blit, which is almost certainly incorrect. Exploring is of course welcome. Are you talking about the D language? Assignment never did just blit, and this DIP does not propose that. Andrei
Re: Copy Constructor DIP
On 7/12/18 6:34 PM, Manu wrote: On Thu, 12 Jul 2018 at 06:50, Andrei Alexandrescu via Digitalmars-d wrote: On 07/11/2018 11:11 AM, Atila Neves wrote: On Wednesday, 11 July 2018 at 07:40:32 UTC, RazvanN wrote: But there's a super explicit `@implicit` thing written right there... so should we expect that an *explicit* call to the copy constructor is not allowed? Or maybe it is allowed and `@implicit` is a lie? The @implicit is there to point out that you cannot call that method explicitly; it gets called for you implicitly when you construct an object as a copy of another object. How is this different from other types of constructors or destructors? The main difference is that the compiler may insert calls to it implicitly. You mean like ~this(), and op[Anything](), and front() and popFront() and empty()? I don't think we need this attribute. I mentioned this, and patiently will mention it again: we need to introduce the attribute so as to avoid silently changing the semantics of existing code.
Re: Copy Constructor DIP
On 7/12/18 7:15 PM, Manu wrote: On Thu, 12 Jul 2018 at 08:36, Andrei Alexandrescu via Digitalmars-d wrote: On 07/12/2018 11:14 AM, Luís Marques wrote: On Thursday, 12 July 2018 at 14:56:33 UTC, Luís Marques wrote: When designing D libraries than lean towards DSL style, I've frequently felt impaired by the lack of implicit conversions in D. In my experience, it's not that all types need to be implicitly convertible to other types. Just being able to mark a few types as implicitly convertible to some other specific types would go a long way to alleviate the limitations I felt. It would also solve problems like an arbitrary limit on the depth of implicit conversions. I had imagined that maybe one day an implicit keyword could be introduced to mark such permissible implicit conversions. Seeing an implicit "keyword" being introduced here with different semantics than I envisioned makes me even less hopeful that some day such implicit conversions annotations could be introduced. So... maybe consider choosing some other syntactic notation? Besides, the fact that the compiler can implicitly introduce calls to the copy ctor doesn't strike me as something particularly central to the concept, so it seems like an odd choice for something to distinguish a copy ctor. More details. The DIP says: "The structName type needs to be identical to typeof(this); an error is issued otherwise. This requirement may be relaxed in the future in order to accomodate copying from objects of a different type" (BTW, typo in "accomodate") That would mean that if such a relaxation were introduced, then suddenly *all* copy ctors would imply implicit conversion between the respective types. No, only constructors annotated with @implicit would be implicit. But that's only a possible future direction not part of this DIP. Also there are many complications related to allowing implicit conversions across distinct types, and this DIP should not get embroiled in those. That would be a different pursuit that I encourage you to consider. I feel like this DIP depends on an @implicit DIP, and that one needs to come first... Negative.
Re: Copy Constructor DIP
On 7/12/18 4:29 PM, Manu wrote: Being able to implement them both independently is*occasionally* useful, but 95% of the time, destruct + copy-construct is an equally efficient implementation for assignment. I'd suggest that this destruct+copy-construct pattern is a perfectly good substitute for assignment in most cases, and maybe the compiler should deploy the pattern as an implicit copy constructor in lieu of an explicit one? So, if the user specifies a complex copy constructor, but no assignment operator (which just blits on copy), then they've almost certainly introduced a bug on copying! Perhaps the compiler should automatically emit an assignment operator implemented as above in presence of a (suite of? [const/immutable/etc permutations]) 'complex' copy constructor? Not the charter of the current DIP.
Re: Copy Constructor DIP
On 7/12/18 2:30 PM, ag0aep6g wrote: On 07/12/2018 03:40 PM, Andrei Alexandrescu wrote: On 07/10/2018 04:58 PM, Manu wrote: [...] 1. Explain the need and reasoning behind `@implicit`. Razvan: I think it would help to explain that the attribute is necessary to avoid changing semantics of existing code. Thanks. You're still potentially changing the semantics of existing code. `@implicit` can be a UDA today: enum implicit = 0; struct C { @implicit this(ref C another) {} } Today, that's a normal constructor. With the DIP, it becomes a copy constructor. That is correct and a liability of the current DIP. That should be mentioned in it.
Re: Copy Constructor DIP
On 7/12/18 11:42 AM, Luís Marques wrote: On Thursday, 12 July 2018 at 15:33:03 UTC, Andrei Alexandrescu wrote: Again: not the charter of this DIP, so you should ask yourself, not us, this question. Look, I understand it can be frustrating to have a concrete design proposal derailed by a myriad of speculative questions. But if we suspect that design decision of a DIP might interact poorly with other plausible future D features, should we not at least express our concerns and hopes? By the time the other DIPs come out it might be too late to address the concerns. In any case, I hope my comments were not too out of bounds of the discussion. If so, I'm sorry. Definitely good topics to discuss. This is a collaborative process, not a confrontational one. If this DIP precludes good future decisions, that's definitely a meaningful discussion.
Re: Copy Constructor DIP
On 07/12/2018 11:14 AM, Luís Marques wrote: On Thursday, 12 July 2018 at 14:56:33 UTC, Luís Marques wrote: When designing D libraries than lean towards DSL style, I've frequently felt impaired by the lack of implicit conversions in D. In my experience, it's not that all types need to be implicitly convertible to other types. Just being able to mark a few types as implicitly convertible to some other specific types would go a long way to alleviate the limitations I felt. It would also solve problems like an arbitrary limit on the depth of implicit conversions. I had imagined that maybe one day an implicit keyword could be introduced to mark such permissible implicit conversions. Seeing an implicit "keyword" being introduced here with different semantics than I envisioned makes me even less hopeful that some day such implicit conversions annotations could be introduced. So... maybe consider choosing some other syntactic notation? Besides, the fact that the compiler can implicitly introduce calls to the copy ctor doesn't strike me as something particularly central to the concept, so it seems like an odd choice for something to distinguish a copy ctor. More details. The DIP says: "The structName type needs to be identical to typeof(this); an error is issued otherwise. This requirement may be relaxed in the future in order to accomodate copying from objects of a different type" (BTW, typo in "accomodate") That would mean that if such a relaxation were introduced, then suddenly *all* copy ctors would imply implicit conversion between the respective types. No, only constructors annotated with @implicit would be implicit. But that's only a possible future direction not part of this DIP. Also there are many complications related to allowing implicit conversions across distinct types, and this DIP should not get embroiled in those. That would be a different pursuit that I encourage you to consider.
Re: Copy Constructor DIP
On 07/12/2018 11:29 AM, Luís Marques wrote: On Thursday, 12 July 2018 at 15:25:10 UTC, Luís Marques wrote: On Thursday, 12 July 2018 at 15:14:19 UTC, Luís Marques wrote: BTW: Multiple alias this is still planned for inclusion in D, right? If so, what would be the (pratical?) difference between having copy ctors with such a relaxed type requirement and just defining an equivalent alias this method? In case the answer is that there's no significant difference, why not drop multiple alias this, then? Sorry for the stream-of-conscience type posts. But, to clarify further: if alias this provides access to the members of the converted type (besides type conversion), couldn't that feature be folded into the same mechanism of the copy ctor (or vice-versa), to avoid mostly redundant features in the language, with subtle interactions? The DIP mentions the interaction of @implicit with alias this.
Re: Copy Constructor DIP
On 07/12/2018 11:25 AM, Luís Marques wrote: On Thursday, 12 July 2018 at 15:14:19 UTC, Luís Marques wrote: More details. The DIP says: "The structName type needs to be identical to typeof(this); an error is issued otherwise. This requirement may be relaxed in the future in order to accomodate copying from objects of a different type" (BTW, typo in "accomodate") That would mean that if such a relaxation were introduced, then suddenly *all* copy ctors would imply implicit conversion between the respective types. Given D's stance on implicit conversions, I suspect that's not going to pass mustard. So I would prefer the any "implicit" keyword-like annotation to be reserved for explicitly approved implicit conversions. BTW: Multiple alias this is still planned for inclusion in D, right? If so, what would be the (pratical?) difference between having copy ctors with such a relaxed type requirement and just defining an equivalent alias this method? In case the answer is that there's no significant difference, why not drop multiple alias this, then? Again: not the charter of this DIP, so you should ask yourself, not us, this question.
Re: Copy Constructor DIP
On 07/12/2018 11:22 AM, Timon Gehr wrote: On 12.07.2018 15:29, Andrei Alexandrescu wrote: On 07/11/2018 05:55 AM, Nick Treleaven wrote: ... Removing `static` works. Otherwise I tried changing `ref` to `alias`: Error: variable src cannot be read at compile time But this shorter code seems to work fine: this.tupleof = src.tupleof; Odd. Timon, what would be the reason for that error? Razvan, can you please look into removing "static" for now. Thanks! The reason for this specific error is that `src.i` is neither a symbol nor a constant value. tupleof is a case of built-in compiler magic, because it can produce an expression tuple that contains run-time values that are not symbols. The following (manually unrolled) code also does not work: alias field0 = s.tupleof[0]; t.tupleof[0] = field0; alias field1 = s.tupleof[1]; t.tupleof[1] = field1; alias field2 = s.tupleof[2]; t.tupleof[2] = field2; Error: alias `a` cannot alias an expression `tuple(s.a, s.b, s.c)[0]` Error: alias `b` cannot alias an expression `tuple(s.a, s.b, s.c)[1]` Error: alias `c` cannot alias an expression `tuple(s.a, s.b, s.c)[2]` It could be argued that the `static foreach` implementation should produce the same error message. (The fact that the AliasDecl constructor takes a Dsymbol instead of an Expression has led to multiple reimplementations of parts of the aliasing logic in different parts of the DMD code, `static foreach` is using the same implementation also used by unrolled foreach, and it requires that all loop variables are either symbols or constant values, while unrolled foreach can fall back to introducing runtime variables for this special case.) One way to fix is to lift all the unnecessary limitations that are introduced by the fact that the AliasDecl constructor takes a Dsymbol. I.e. that "you can only alias symbols". Alternatively, it would be possible to redefine `static foreach` statements such that they work for any aggregate with statically known length and element types, and to allow run-time loop variables to be generated when iterating over run-time values. Thanks!
Re: Copy Constructor DIP
On 07/12/2018 10:54 AM, Jonathan M Davis wrote: On Thursday, 12 July 2018 07:45:30 MDT Andrei Alexandrescu via Digitalmars-d wrote: I also very much dislike the syntax - it makes no sense to me at all. I commented on the PR itself asking why it differs so much from C++ - specifically, what's bad about the C++ way of doing things there that we want to avoid? C++ is at the other end of the spectrum - constructors are too implicit, so the "explicit" keyword has been introduced with the advice to use it in the vast majority of cases. If C++ could do it again, it would make everything explicit and add an "implicit" keyword. That's only an issue in C++, because C++ uses constructors for implicit conversions unless you mark them with explicit. D doesn't ever do implicit conversions like that. All constructors are effectively explicit. Is this DIP proposing that we add such implicit conversions? The DIP is proposing what's in the DIP :o). We actually clarify this in text: "The type of the parameter to the copy constructor needs to be identical to typeof(this); an error is issued otherwise. This requirement may be relaxed in the future in order to accomodate implicit copying from objects of a different type:" [example follows] I really don't understand what the purpose of @implicit is here. What's the problem of just going off of the type of the constructor's single parameter to determine whether it's a copy constructor? That would silently change semantics of existing code, which is to be avoided. Andrei
Re: Copy Constructor DIP
On 07/12/2018 09:49 AM, Atila Neves wrote: On Thursday, 12 July 2018 at 06:54:37 UTC, RazvanN wrote: [...] If by "come in pairs" you mean that you can define them both, then yes, that is the case. Will add a paragraph in the DIP to specify this. You mentioned that it's terrible that the assignment operator and the copy constructor come in pairs. Why is that? Would you rather have a copy constructor that is used also as an assignment operator? Because, like in C++, now you have to implement both and make sure they do the same thing. Boilerplaty and a recipe for disaster. Atila There's no meaningful way to avoid that. The two operations are fundamentally different, are typechecked differently, and actually are different in the presence of qualifiers on fields. Introspection is a key helper here compared to C++.
Re: Copy Constructor DIP
On 07/11/2018 12:19 PM, vit wrote: On Wednesday, 11 July 2018 at 07:40:32 UTC, RazvanN wrote: But there's a super explicit `@implicit` thing written right there... so should we expect that an *explicit* call to the copy constructor is not allowed? Or maybe it is allowed and `@implicit` is a lie? The @implicit is there to point out that you cannot call that method explicitly; it gets called for you implicitly when you construct an object as a copy of another object. Can be explicit constructor overloaded with implicit constructor when both have same signature? Thanks for this. Yes we need to add a mention.
Re: Copy Constructor DIP
On 07/11/2018 05:28 PM, Manu wrote: What's wrong with: struct S { this(ref S copyFrom); } That looks like a perfectly good copy constructor declaration ;) I'm just saying, the DIP needs to explain this. Thanks, worth a paragraph discussing silent semantics change. Right. This is all obvious and intuitive. What I'm hearing is that under this proposal, copy constructors and assignment operators DO come in pairs (just like in C++), but that's not mentioned here in this DIP. Since this proposal will introduce that recommended pattern from C++, it may be worth mentioning. Shouldn't hurt to add 1-2 sentences to the effect. (Also an example.)
Re: Copy Constructor DIP
On 07/12/2018 02:54 AM, RazvanN wrote: What's wrong with: struct S { this(ref S copyFrom); } That looks like a perfectly good copy constructor declaration ;) I'm just saying, the DIP needs to explain this. That is actually a valid constructor, according to today's compiler. There might be code out there that uses this syntax for the constructor and overnight it will be turned into a copy constructor. I agree that the current syntax is lacking. This was Andrei's proposition and I was initially against it, but he said to put it in the DIP so that we can discuss it as a community. Maybe this syntax is better: @this(ref S a another) It looks like the c++ copy constructor but the `@` makes it different from a constructor, so we're good. What do you think? We will not add syntax if we can help it.
Re: Copy Constructor DIP
On 07/11/2018 11:11 AM, Atila Neves wrote: On Wednesday, 11 July 2018 at 07:40:32 UTC, RazvanN wrote: But there's a super explicit `@implicit` thing written right there... so should we expect that an *explicit* call to the copy constructor is not allowed? Or maybe it is allowed and `@implicit` is a lie? The @implicit is there to point out that you cannot call that method explicitly; it gets called for you implicitly when you construct an object as a copy of another object. How is this different from other types of constructors or destructors? The main difference is that the compiler may insert calls to it implicitly. I also very much dislike the syntax - it makes no sense to me at all. I commented on the PR itself asking why it differs so much from C++ - specifically, what's bad about the C++ way of doing things there that we want to avoid? C++ is at the other end of the spectrum - constructors are too implicit, so the "explicit" keyword has been introduced with the advice to use it in the vast majority of cases. If C++ could do it again, it would make everything explicit and add an "implicit" keyword.
Re: Copy Constructor DIP
On 07/10/2018 06:50 PM, Manu wrote: On Tue, 10 Jul 2018 at 15:23, Jonathan M Davis via Digitalmars-d wrote: On Tuesday, 10 July 2018 14:58:09 MDT Manu via Digitalmars-d wrote: 2. It looks like copy constructors are used to perform assignments (and not constructions)... but, there is also opAssign. What gives? Eg: S b = a; // <- copy construction? looks like an assignment. And not: S b = S(a); // <- actually looks like a construction, but this syntax seems to not be intended (and rightly so, it's pretty terrible) S b = a; has never been assignment in either C++ or D. It's initialization / construction, which means that it calls a constructor - be that a postblit constructor or a copy constructor. Assignment only occurs when you're giving an existing object a new value. I know this, but it's not syntactically obvious, it just depends on the fact that you already know that fact... I feel a DIP about copy construction needs to have some text explaining that, and where the edges are. The DIP is not a tutorial on existing related parts of the language. Copy initialization has been distinct from assignment for a long time in both C++ and D languages. Is an initialisation assignment can use a copy constructor, why can't a normal assignment implicitly use a copy constructor? (implicit destruct then copy-construct) Because assignment and construction were, and are, distinct operation. There is no need for the DIP to explain. And why would S b = S(a); not be intended? Sure, it's kind of pointless if a is an S, but if you have a copy constructor, it makes perfect sense that S(a) would work and would be pretty bizarre if it didn't, since it's explicitly calling the copy constructor. But there's a super explicit `@implicit` thing written right there... so should we expect that an *explicit* call to the copy constructor is not allowed? Or maybe it is allowed and `@implicit` is a lie? The "@implicit" attribute does not preclude explicit calls. Razvan: you may want to mention that. It even works right now if you give S a constructor that takes an S. It just isn't actually treated as a proper copy constructor at the moment, since that's currently the postblit constructor's job. Current language doesn't have `@implicit` written anywhere... Misunderstanding that I assume has been cleared by now. Andrei
Re: Copy Constructor DIP
On 07/10/2018 04:58 PM, Manu wrote: On Tue, 10 Jul 2018 at 03:50, RazvanN via Digitalmars-d wrote: Hi everyone! I managed to put together a first draft of the DIP for adding the copy constructor to the language [1]. If anyone is interested, please take a look. Suggestions and comments about technical aspects and wording are all welcome. Thanks, RazvanN [1] https://github.com/dlang/DIPs/pull/129 I feel there's some things missing. 1. Explain the need and reasoning behind `@implicit`. Razvan: I think it would help to explain that the attribute is necessary to avoid changing semantics of existing code. Thanks. 3. In C++, copy constructors and copy assignment operators come in pairs (which is totally lame!), but we don't see that same pattern extend here, and it's not clear at all why. The proposal does not affect or interfere with opAssign in any way. 4. Given the special rules where assignments are lifted to constructions, I want to know when that occurs (maybe that is already spec-ed wrt postblit?) What special rules are you referring to? Thanks.
Re: Copy Constructor DIP
On 07/11/2018 05:55 AM, Nick Treleaven wrote: On Tuesday, 10 July 2018 at 10:47:04 UTC, RazvanN wrote: [1] https://github.com/dlang/DIPs/pull/129 Thanks for making the DIP. I can't get this code to compile (my struct has an `int i` field): static foreach (i, ref field; src.tupleof) this.tupleof[i] = field; Error: constant value src.i cannot be ref https://run.dlang.io/is/qeugC8 Removing `static` works. Otherwise I tried changing `ref` to `alias`: Error: variable src cannot be read at compile time But this shorter code seems to work fine: this.tupleof = src.tupleof; Odd. Timon, what would be the reason for that error? Razvan, can you please look into removing "static" for now. Thanks!
Re: Copy Constructor DIP
On 07/10/2018 06:52 AM, Guillaume Piolat wrote: On Tuesday, 10 July 2018 at 10:47:04 UTC, RazvanN wrote: Hi everyone! I managed to put together a first draft of the DIP for adding the copy constructor to the language [1]. If anyone is interested, please take a look. Suggestions and comments about technical aspects and wording are all welcome. Thanks, RazvanN [1] https://github.com/dlang/DIPs/pull/129 Does it allow to remove the "T.init must always be valid for structs" rule? That's not part of this proposal's charter.
Re: std.traits : Select - could it be better?
On 7/5/18 2:50 PM, SrMordred wrote: alias U = Select!( isPointer!T, PointerTarget!T, T ); This don´t compile if T are not a pointer; so you have to do this: static if( isPointer!T ) alias U = PointerTarget!T; else alias U = T; Shouldnt the 'correct' way of Select to work is ignoring the choice that was not taken? I love the idea of Select, but because of this I almost never use it. mixin("alias U = " ~ Select!(isPointer!T, "PointerTarget!T", "T") ~ ";"); Ehm this is actually not better :o). Andrei
Re: Phobos begat madness
On 6/23/18 1:36 AM, Adam D. Ruppe wrote: On Friday, 22 June 2018 at 22:28:17 UTC, Walter Bright wrote: That would help, do you want to implement it? I can't for at last two weeks, I'm about to fly tomorrow... and I'm getting married in August too so my life is kinda hectic. Congratulations, Adam! Andrei
The Case Against Annotations
An interesting article. Most of the listed disadvantages of annotations are obviated by D's approach. https://blog.softwaremill.com/the-case-against-annotations-4b2fb170ed67
Re: To the D Foundation Moderators
On 6/14/18 11:02 AM, Duser wrote: The problem with the D Foundations' new approach to 'moderating' is: Who does the moderating? Thanks for asking. Moderation is done by a small leadership group of which Walter and I are part. I won't name other names for the simple reason I forgot who the others are. Who long does it take? It's done on a best effort basis. Vladimir created a nice automated system that only flags a small number of posts for moderation, I'm sure he'd be glad to share details. What exactly are these so called 'moderator' 'filtering', so that others cannot see it? Without complete insight into this new model of moderating posts, then this is just a tool for abuse. Anything can be 'moderated'. In which case, these forums become the D Foundations propaganda machine. This is not a corporation that needs formal rules lest whatever CEO gets on board can abuse position. Also, it's not a mission-driven free speech platform where you have defined rights just by posting. That said, the sheer notion that Walter or myself would moderate away posts of which technical content disagree with is ridiculous. If you're trying to put a political spin on this, please leave this community. Andrei
Re: stride in slices
On 06/04/2018 07:08 PM, Ethan wrote: On Monday, 4 June 2018 at 18:11:47 UTC, Steven Schveighoffer wrote: BTW, do you have cross-module inlining on? Just to drive this point home. https://run.dlang.io/is/nrdzb0 Manually implemented stride and fill with everything forced inline. Otherwise, the original code is unchanged. 17 ms, 891 μs, and 6 hnsecs 15 ms, 694 μs, and 1 hnsec 15 ms, 570 μs, and 9 hnsecs My new stride outperformed std.range stride, and the manual for-loop. And, because the third test uses the new stride, it also benefited. But interestingly runs every so slightly faster... BTW I've had this thought for a long time to implement stride with a compile-time step... never got around to implementing it. It would easily generalize the existing code without too much work. Essentially the step would be a template parameter; if that is 0, then use a run-time stride. Most of the code works unchanged.
An analysis of dimensional analysis
...in various languages, including D: https://www.reddit.com/r/programming/comments/8lwfis/dimensional_analysis_in_programming_languages/
Re: Ideas for students' summer projects
On 5/22/18 1:39 PM, jmh530 wrote: On Tuesday, 22 May 2018 at 16:27:05 UTC, Eduard Staniloiu wrote: Hello, everyone! We, at UPB, have initiated D's participation to ROSEdu Summer of Code, see http://soc.rosedu.org/2018/. I will be mentoring a student over the summer and I was wondering if you have any suggestions for a project. If there is a library or feature that you would like just drop an idea. The proposed idea should be something that can be done in 8-10 weeks, though, ideally, we hope that the student/s will continue to contribute to the community after the summer ends. Let the brainstorming begin! GSOC ideas would obviously be a good place to start. https://wiki.dlang.org/GSOC_2018_Ideas We're looking at those, plus any fresh ideas.
Re: Sealed classes - would you want them in D? (v2)
Hi folks, it looks like at least a few branches of this thread have run well past their useful course and into tedious territory. We don't like to go about killing threads, so we kindly ask that you all refrain from posting in this thread going forward. Thanks much! Andrei
Re: Of possible interest: fast UTF8 validation
On 05/17/2018 09:14 AM, Patrick Schluter wrote: I'm in charge at the European Commission of the biggest translation memory in the world. Impressive! Is that the Europarl?
Re: Benchmark Game
On 05/17/2018 04:50 AM, Chris wrote: For what it's worth, I came across this website: https://benchmarksgame-team.pages.debian.net/benchmarksgame/ D is not there. Anyone interested, if it's worth it? It would be well worth the effort.
Re: DIP 1011 library alternative
On 05/15/2018 08:44 PM, Jonathan Marler wrote: On Tuesday, 15 May 2018 at 21:25:05 UTC, Andrei Alexandrescu wrote: Hello, I was reviewing again DIP 1011 and investigated a library solution. That led to https://gist.github.com/run-dlang/18845c9df3d73e45c945feaccfebfcdc It builds on the opening examples in: https://github.com/dlang/DIPs/blob/master/DIPs/DIP1011.md I'm displeased at two aspects of the implementation: * Perfect forwarding is tedious to implement: note that makeDelegate hardcodes void as the return type and (int, float) as parameter types. Ideally it should accept any parameters that the alias passes. * Pass-by-alias and overloading interact poorly. Does anyone know how to refer by alias to one specific overload? Thanks, Andrei Now that I've had a chance to look the example you've shared, the only comment I'd make is that DIP1011 aims to allow applications to create "delegate-compatible" functions that don't require generating a wrapper function to forward a delegate call to the function at runtime In this example, 2 functions have been defined that take a class and a struct pointer as the first argument, however, these function are not ABI compatible with the delegate ABI meaning you will have to generate a runtime "conversion" function to forward a delegate call to call the function. Affirmative. The important matter here is the number of indirect calls, which is not increased; forwarding direct calls are often easy to inline and even if not are cheap (subject to the number and size of their arguments). extern(delegate) allows the application to generate the function using the delegate ABI in the first place so no "conversion" is necessary. To achieve this with a libary solution, you need to modify the function definition itself, not just create a wrapper around it. Affirmative. But that's just stating it. The question is how needed and useful that is. At the least, this feedback prompts for changes the rationale and motivation of the DIP. The bulk of the current rationale rests on use cases and the disadvantages of inferior workarounds. (The consistency with UFCS rewrites argument is weaker but valid, and stays.) The DIP's rationale would need to be redone to compare the proposed feature with the best known library solution (derived from the proof of concept in this thread), and them build an argument that it is needed based on (a) remaining disadvantages of the library solution and (b) convenience for frequent/intensive use. We're not rejecting the DIP outright but we point out that it needs rework in wake of this new evidence of competing alternatives. Feel free to reach out privately for further discussion. Thanks, Andrei
Re: Of possible interest: fast UTF8 validation
On 5/16/18 1:18 PM, Joakim wrote: On Wednesday, 16 May 2018 at 16:48:28 UTC, Dmitry Olshansky wrote: On Wednesday, 16 May 2018 at 15:48:09 UTC, Joakim wrote: On Wednesday, 16 May 2018 at 11:18:54 UTC, Andrei Alexandrescu wrote: https://www.reddit.com/r/programming/comments/8js69n/validating_utf8_strings_using_as_little_as_07/ Sigh, this reminds me of the old quote about people spending a bunch of time making more efficient what shouldn't be done at all. Validating UTF-8 is super common, most text protocols and files these days would use it, other would have an option to do so. I’d like our validateUtf to be fast, since right now we do validation every time we decode string. And THAT is slow. Trying to not validate on decode means most things should be validated on input... I think you know what I'm referring to, which is that UTF-8 is a badly designed format, not that input validation shouldn't be done. I find this an interesting minority opinion, at least from the perspective of the circles I frequent, where UTF8 is unanimously heralded as a great design. Only a couple of weeks ago I saw Dylan Beattie give a very entertaining talk on exactly this topic: https://dotnext-piter.ru/en/2018/spb/talks/2rioyakmuakcak0euk0ww8/ If you could share some details on why you think UTF8 is badly designed and how you believe it could be/have been better, I'd be in your debt! Andrei
Re: Sealed classes - would you want them in D?
On 05/16/2018 04:28 AM, meppl wrote: a pitfall-section about 'private' and 'protected' in https://dlang.org/spec/class.html wouldnt hurt. Yah, improvements to the spec are always welcome and not difficult to effect. It's one of the areas in which crowdsourcing would work nicely.
Re: Sealed classes - would you want them in D?
On 05/16/2018 04:42 AM, Dave Jones wrote: On Wednesday, 16 May 2018 at 08:20:23 UTC, Uknown wrote: On Wednesday, 16 May 2018 at 07:53:36 UTC, aliak wrote: Just checked the rust spec [0]. private in rust => accessible from that module and its descendants, which is what package in D is. private in D would be to that module only. [0]: https://doc.rust-lang.org/beta/reference/visibility-and-privacy.html Dont know if its been mentioned before but in Delphi / Object Pascal private is accessible to everything in the same module. Same as D. This is interesting, thanks for the info.
Re: Of possible interest: fast UTF8 validation
On 05/16/2018 08:47 AM, Ethan Watson wrote: On Wednesday, 16 May 2018 at 11:18:54 UTC, Andrei Alexandrescu wrote: https://www.reddit.com/r/programming/comments/8js69n/validating_utf8_strings_using_as_little_as_07/ I re-implemented some common string functionality at Remedy using SSE 4.2 instructions. Pretty handy. Except we had to turn that code off for released products since nowhere near enough people are running SSE 4.2 capable hardware. Is it workable to have a runtime-initialized flag that controls using SSE vs. conservative? The code linked doesn't seem to use any instructions newer than SSE2, so it's perfectly safe to run on any x64 processor. Could probably be sped up with newer SSE instructions if you're only ever running internally on hardware you control. Even better! Contributions would be very welcome. Andrei
Of possible interest: fast UTF8 validation
https://www.reddit.com/r/programming/comments/8js69n/validating_utf8_strings_using_as_little_as_07/
DIP 1011 library alternative
Hello, I was reviewing again DIP 1011 and investigated a library solution. That led to https://gist.github.com/run-dlang/18845c9df3d73e45c945feaccfebfcdc It builds on the opening examples in: https://github.com/dlang/DIPs/blob/master/DIPs/DIP1011.md I'm displeased at two aspects of the implementation: * Perfect forwarding is tedious to implement: note that makeDelegate hardcodes void as the return type and (int, float) as parameter types. Ideally it should accept any parameters that the alias passes. * Pass-by-alias and overloading interact poorly. Does anyone know how to refer by alias to one specific overload? Thanks, Andrei
Re: andrei - better breakdown of statistics for downloads by region, OS, kind of site (academic/large corporate/large financial/etc)
On 05/08/2018 03:54 AM, Suliman wrote: Stat out of date... Plz update it. Done. Keep in mind those stats are noisy. They need to be improved, but couldn't find anyone to work on that. I have talked to a consultant, he was very successful with showing near-real-time statistics about the project and its progress in a dashboard that was visible to all project participants. For example he had product sales in real time, which I thought was a very nice touch: developers could see the result of their work making money instantly. He told me that that's a classic method used in Agile methodology. A very good project for us would be a near-real-time dashboard displaying downloads, site visits, github activity, and such. I know I'd keep such a page opened at all times. Andrei
Re: Lightening cable?
On 4/30/18 3:30 PM, Luís Marques wrote: Hi. Can anyone staying at the conference hotel lend me an iPhone charging cable? Even just for a few minutes would help. I forgot mine :( Me too, sigh...
Re: Space before parens in all function definitions
On 04/09/2018 02:50 PM, Seb wrote: On Monday, 9 April 2018 at 16:22:15 UTC, Andrei Alexandrescu wrote: On 04/07/2018 07:01 AM, Sönke Ludwig wrote: Am 07.04.2018 um 04:23 schrieb Andrei Alexandrescu: Why is there a space before "(" in our /library/ docs? https://dlang.org/library/std/stdio/file.tmpfile.html The paren here has role similar to that in mathematics, not literary. Thanks, Andrei Has been a regression during the diet-ng transition. Fix in DDOX: https://github.com/rejectedsoftware/ddox/pull/203 Thanks! When will that be live? Should happen soon -> https://github.com/dlang/dlang.org/pull/2335 Thanks folks!
Re: Space before parens in all function definitions
On 04/07/2018 07:01 AM, Sönke Ludwig wrote: Am 07.04.2018 um 04:23 schrieb Andrei Alexandrescu: Why is there a space before "(" in our /library/ docs? https://dlang.org/library/std/stdio/file.tmpfile.html The paren here has role similar to that in mathematics, not literary. Thanks, Andrei Has been a regression during the diet-ng transition. Fix in DDOX: https://github.com/rejectedsoftware/ddox/pull/203 Thanks! When will that be live?
Space before parens in all function definitions
Why is there a space before "(" in our /library/ docs? https://dlang.org/library/std/stdio/file.tmpfile.html The paren here has role similar to that in mathematics, not literary. Thanks, Andrei
[OT] Re: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/, [your code here]
On 04/06/2018 10:03 AM, Abdulhaq wrote: On Friday, 6 April 2018 at 13:10:07 UTC, jason wrote: what is this? It's a perl program that converts D code into APL Genius.
Re: DIP in making: ProtoObject
On 04/04/2018 09:18 AM, 12345swordy wrote: On Wednesday, 4 April 2018 at 04:49:10 UTC, Andrei Alexandrescu wrote: I'm working on a simple older idea to get it out of the way in preparation for the more difficult DIPs to come: https://github.com/andralex/DIPs/blob/ProtoObject/DIPs/DIP.md This is not officially reviewable yet, but conveys the gist and could use some early feedback. Any insight will be appreciated. Thanks, Andrei No attempts to make class deallocation @nogc attribute friendly? This is a major PIA for me. The current attempts at this involve various workarounds (See automem library for example), which even then does not solve all the problems it currently have. Can you please give more detail on that? You mean the destructor of Object is automatically generated with a bad signature?
PR duty
Hi folks, I was thinking of the following. To keep the PR queue trim and in good shape, we'd need at least one full-time engineer minding it. I've done that occasionally, and the queue size got shorter, but I couldn't do much else during that time. I was thinking, we can't afford a full-time engineer, and even if we did, we'd probably have other important matters for that engineer as well. However, what we can afford - and indeed already benefit from - is a quantum of time from each of many volunteers. By organizing that time better we may be able to get more output. Here's what I'm thinking. Let's define a "PR duty" role that is one week long for each of a pool of volunteers. During that week, the person on PR duty focuses on minding github queues - merge trivial PRs, ping authors of old PRs, email decision makers for specific items in PRs, etc. Then the week ends and the role is handed off to the next person in the pool. A calendar maintained by an impartial person - maybe we can ask Mike - would keep track of everything. The most obvious candidates for PR duty engineers would be the most prolific contributors in the respective repositories. One question would be how many distinct pools/tracks we should have. Presumably someone fluent with phobos is not necessarily fluent with dmd. So probably we need at least two tracks: * dmd * everything else (druntime, phobos, tools, site) If there are a dozen of us in each pool, each would be on duty one week every three months. Even with eight, we'd be on duty a manageable week every other month. Please share your thoughts. Thanks, Andrei
DIP in making: ProtoObject
I'm working on a simple older idea to get it out of the way in preparation for the more difficult DIPs to come: https://github.com/andralex/DIPs/blob/ProtoObject/DIPs/DIP.md This is not officially reviewable yet, but conveys the gist and could use some early feedback. Any insight will be appreciated. Thanks, Andrei
Re: D compiles fast, right? Right??
On 04/03/2018 05:53 PM, bachmeier wrote: On Tuesday, 3 April 2018 at 21:17:35 UTC, Rubn wrote: I feel that's probably the case for any comparisons across two languages, you are going to have a person that is more knowledgeable in one language than another. Mistakes are going to be made, but I think it should be blatantly obvious that one language is going to compiler slower if it is compiling all the unittests for a library compared to one that isn't. That's just blatant bias against D, not a mistake from misunderstanding Go. Yeah, I don't understand that either. Unit tests can be arbitrarily large, so no matter how fast the compiler, it would always be possible to make it take longer than any other language. Exactly, which is why I'm insisting this - and not compiler benchmarking, let alone idle chattaroo in the forums - is where we need to hit. What we have here, ladies and gentlemen, is a high-impact preapproved item of great general interest. Shall we start the auction?
Re: Deprecating this(this)
On 04/03/2018 04:29 PM, ag0aep6g wrote: But if postblit goes away for other reasons anyway (like the atomic copy thing, or another mechanism being simply superior), then there's no point in pursuing this, of course. The DIP will definitely need to make a solid case supporting whatever it proposes.
Re: Deprecating this(this)
On 04/03/2018 04:26 PM, ag0aep6g wrote: On 04/03/2018 05:13 PM, Steven Schveighoffer wrote: Unfortunately, I found out that it's not just "pre-filled with some values". Member postblits are run before the containing postblit. https://run.dlang.io/is/mt6eGa So this means, the data that is available to the postblit has already been processed. There's a similar situation with constructors: A constructor can call another constructor, which can lead to double initialization of fields. Example: class C { int x; this() immutable { this(42); /* Initializes x. */ x = 13; /* Breaking immutable, or ok? */ } this(int x) immutable { this.x = x; } } Let's replace "int" with an UDT: struct S { int x = -1; this(int y) immutable { x = y; } void opAssign(int) immutable; } class C { S x; this() immutable { this(42); /* Initializes x. */ x = 13; /* Breaking immutable, or ok? */ } this(int x) immutable { this.x = x; } } This code compiles, and calls the constructor twice for the same object. Clearly that shouldn't be allowed to pass. I've submitted https://issues.dlang.org/show_bug.cgi?id=18719 - thanks! (The problem seems to occur even without immutable, it's endemic to forwarding constructors.) Andre
Re: Deprecating this(this)
On 04/03/2018 10:21 AM, ag0aep6g wrote: On Tuesday, 3 April 2018 at 12:52:00 UTC, Andrei Alexandrescu wrote: On 04/03/2018 07:36 AM, ag0aep6g wrote: For constructors, we say that the first assignment is actually initialization. The compiler might or might not put the .init value down before calling the constructor. Doesn't matter, because the constructor will overwrite it anyway, and nothing of value is lost. What happens in fact is you are guaranteed the .init value is there. Much later, well after semantic checking, the backend optimizer removes dead assignments on primitive data. So constructors, including const/immutable ones, basically work the same as postblit already? You get an object pre-filled with some values, and then you can "initialize" the fields some more if you want. Well... not really. This is because .init is really an inert state - null indirections, no state allocated etc. Makes typechecking easy, and calling constructor on top of .init is what happens already. In contrast, the postblit situash is very different - the fields already contain "interesting" data, allocated resources etc. Calling a constructor on top of that is not defined.
Re: Deprecating this(this)
On 04/03/2018 07:36 AM, ag0aep6g wrote: For constructors, we say that the first assignment is actually initialization. The compiler might or might not put the .init value down before calling the constructor. Doesn't matter, because the constructor will overwrite it anyway, and nothing of value is lost. What happens in fact is you are guaranteed the .init value is there. Much later, well after semantic checking, the backend optimizer removes dead assignments on primitive data. We can do the same with the postblit function: First assignment is actually initialization. When the compiler sees that the postblit function initializes a field, it can skip that field when blitting. What if the user code reads the value? * Often people use this(this) to bump a reference count a la "if (pcnt) ++*pcnt;" * People may pass the field by reference to an opaque function. What type does the field have? But it can also just blit the whole struct, because it doesn't matter if the value just gets overwritten. In other words, a postblit function can either: 1) use the blitted value as a starting point, like a constructor can use the .init value, or it can 2) initialize the field itself. Would make perfect sense to me. In case (1) things can get quite confusing. Inside a postblit, field = TypeOfField(100); is a call to the constructor, whereas field = TypeOfField(field.x + 100); is a call to the assignment operator. Andrei
Re: Deprecating this(this)
On 04/02/2018 02:47 PM, Marco Leise wrote: Am Mon, 2 Apr 2018 11:57:55 -0400 schrieb Andrei Alexandrescu : Problem is we don't have head-mutable in the language. Yes, for built-in slices the mechanism is simple - just change qualifier(T[]) to qualifier(T)[]. For a struct S, there is no way to convert from qualifier(S) to tailqualifier(S). I plan to attack this directly in the DIP - provide a way for structs to express "here's what implicit conversion should be applied when doing template matching". Andrei You are hitting a prominent type system flaw here. What may look like a hurdle on the path to fix this(this) is also at the core of getting "shared" into a good shape and probably affects how we will discuss "immutable destructors" and their kin in the future. The question is "How transitive is a qualifier when we strip it top-level on an aggregate?" Roger. My hope is to solve that for primitive types, then use that to typecheck constructors and destructors, then use the signatures of (typechecked) constructors and destructors to address composition. Ideally we'd get away without defining another kind of qualifier - @tail(const) or whatever. That would complicate the language a great deal. Andrei
Re: What's up with ddoc on dlang.org?
On 04/02/2018 06:13 PM, ag0aep6g wrote: On 04/02/2018 11:36 PM, Steven Schveighoffer wrote: Was just perusing dlang's library documentation, and here is the description it has for std.experimental.allocator.make: Dynamically allocates (using ) and then creates in the memory allocated an object of type T, using (if any) for its initialization. Initialization occurs in the memory allocated and is otherwise semantically the same as T(). (Note that using .!(T[]) creates a pointer to an (empty) array of Ts, not an array. To use an allocator to allocate and initialize an array, use .makeArray!T described below.) Seems there's a few things missing here? What's happening? Looks like a mistake that happened with this change: https://dlang.org/changelog/2.079.0.html#fix18361 PR to fix it: https://github.com/dlang/dlang.org/pull/2326 Thanks, I'd just found that too.
Re: Deprecating this(this)
On 04/02/2018 12:53 PM, Steven Schveighoffer wrote: On 4/2/18 11:57 AM, Andrei Alexandrescu wrote: On 04/02/2018 10:59 AM, ag0aep6g wrote: That wouldn't be possible if `innocent` were only head-mutable in the postblit function, instead of fully mutable as it is currently (bug). `innocent` would be typed as `immutable(int)[]`, and you could not assign it to the fully mutable `sneaky`. Problem is we don't have head-mutable in the language. This is the wrong way to look at it. Head mutable is a specialized concept already implemented in constructors: struct S { int x; int *ptr; int *ptr2; this(int xval, immutable int *ptrval, int *cantuse) immutable { x = xval; // ok, head mutable //x = x + 1; // error, immutable field initialized multiple times ptr = ptrval; // ok // ptr2 = cantuse; // error, can't assign mutable to immutable } } I've asked Razvan to document how immutable constructors are exactly typechecked. My understanding is that they don't rely on some form of internal "head const" but instead on simple data flow - the first assignment counts as a constructor call. Consider the following example, which contains opaque methods instead of built-ins: struct S { int[] payload; S* another; this(int) immutable; } struct HasS { S member; this(int x) immutable { member = immutable S(1); } } This fails to link; the assignment is just a call to the (declared but undefined) constructor. Such behavior is nice and easy to generalize to copy construction. We could have the same mechanism for postblit. Essentially, you should be able to assign immutable fields once, but they shouldn't lose their const protections (note the cantuse example). Yes, with the distinction that is not "assign" but really "construction with assignment syntax". As was mentioned, because postblit on an immutable (or const) is ONLY allowed for new data, there shouldn't be an issue. The problem with postblit is there's "double construction", one done by the compiler, after which the user may want to assign something else. That's more difficult to typecheck than direct initialization. Andrei
std/typecons.d(2010:36)[warn]: Left side of logical or is identical to right side.
I'm seeing this in the CI runs, but the line is actually not in error: https://github.com/dlang/phobos/blob/master/std/typecons.d#L2010 Where would be the problem? Andrei
Re: Deprecating this(this)
On 04/02/2018 12:14 PM, Paolo Invernizzi wrote: On Monday, 2 April 2018 at 16:00:11 UTC, bachmeier wrote: On Monday, 2 April 2018 at 15:30:23 UTC, Paolo Invernizzi wrote: Andrei wrote in the message I am looking for folks to assist me in creating a DIP for that. There will be a _lot_ of work involved, so don't take it lightly. Andrei is asking others to write a DIP to formalize a decision There's not even an attempt made to pretend there's symmetry. The only way for Manu (and basically anyone else) to propose a change is to write a DIP. Andrei won't even participate in discussions without a DIP. That's probably a good idea. What's not a good idea is to make unilateral decisions about major breaking changes, posting in the forum, and then asking others to write the DIP. That's corporate software development, and it's very discouraging to potential contributors. I think you are plain wrong on this: the 'P' in a DIP stands for Proposal, so any decision is not taken yet. And I'll bet: - Andrei will be the main author or he will partecipate in the writing. - the DIP will follow the usual proceeding, exactly like the others. Affirmative. No need to discuss this further, it's a simple misunderstanding. I'd agree with bachmeier if his perception was correct.
Re: D compiles fast, right? Right??
On 04/02/2018 12:22 PM, H. S. Teoh wrote: Lately this has been mentioned more and more frequently. So what's the status on this? Are we going to move forward with making it so that -unittest only applies to modules supplied on the command-line? Has there been an investigation into how __traits(getUnitTests) could be made to work in spite of this change? Walter and I are willing to go with the change assuming no showstopper presents itself, but we don't have time budgeted for it. So it needs a strong champion.
Re: D compiles fast, right? Right??
On 04/02/2018 08:35 AM, Atila Neves wrote: On Sunday, 1 April 2018 at 02:40:26 UTC, Walter Bright wrote: On 3/30/2018 1:17 PM, Andrei Alexandrescu wrote: Could be faster. It's been a fair amount of time since somebody has done profiling of dmd. It needs to be done. There's probably plenty of low hanging fruit. Speculating about why it is slow is pointless without data. I profiled it as soon as I had the numbers. I didn't bother to mention it because I thought I'd just work on making dmd faster instead. I seem to be the one who feels the most pain by this, it'd be silly of me to expect anyone else to work on it. A large and obvious time sink is that unittests in library code are built when user code is to be unittested. I'd recommend doing this before any other optimization.
Re: Deprecating this(this)
On 04/02/2018 12:00 PM, bachmeier wrote: On Monday, 2 April 2018 at 15:30:23 UTC, Paolo Invernizzi wrote: Andrei wrote in the message I am looking for folks to assist me in creating a DIP for that. There will be a _lot_ of work involved, so don't take it lightly. So, let's keep the discussion factual. I'm pretty sure that every aspect will be taken in account and pondered prior to a decision. I'm +1 on major breaking changes if they drive D towards a better shape. Andrei is asking others to write a DIP to formalize a decision he has already made. Yet when Manu posts here, he responds: Apologies for the misunderstanding. I'll be the first author of the DIP and plan to dedicate a lot of time to it. I was just asking for others to join me in this important and urgent effort. Andrei
Re: Deprecating this(this)
On 04/02/2018 10:42 AM, ag0aep6g wrote: On Monday, 2 April 2018 at 14:01:22 UTC, Kagamin wrote: On Sunday, 1 April 2018 at 14:31:24 UTC, Andrei Alexandrescu wrote: 1. For immutable objects, typechecking in the presence of successive modifications of data (first assignment by the compiler, then modification by the user) is very difficult if not impossible. I don't know how to do it. The single initialization model (raw/cooked) used currently in regular immutable constructors works reasonably well and is robust. Do the same as in const constructor. The way it works in a const constructor is that `this.foo = bar;` is considered initialization, not assignment. Affirmative. First assignment is a call to the member's constructor. We typecheck that reasonably well already in qualified constructors, and it's the most promising approach for the DIP. In a postblit function, we can't say it's initialization, because the field already has a value that can't be ignored. Affirmative. That's what makes it so darn difficult to typecheck. If we don't let the compiler do the initial blitting (and instead start with T.init), the copy ctor is typechecked exactly like the regular ctor. Andrei
Re: Deprecating this(this)
On 04/02/2018 10:59 AM, ag0aep6g wrote: That wouldn't be possible if `innocent` were only head-mutable in the postblit function, instead of fully mutable as it is currently (bug). `innocent` would be typed as `immutable(int)[]`, and you could not assign it to the fully mutable `sneaky`. Problem is we don't have head-mutable in the language. Yes, for built-in slices the mechanism is simple - just change qualifier(T[]) to qualifier(T)[]. For a struct S, there is no way to convert from qualifier(S) to tailqualifier(S). I plan to attack this directly in the DIP - provide a way for structs to express "here's what implicit conversion should be applied when doing template matching". Andrei
Re: Deprecating this(this)
On 4/2/18 4:04 AM, Shachar Shemesh wrote: On 02/04/18 10:45, Jonathan M Davis wrote: Honestly, I think at this point pure is easier to understand if you think of it as @noglobal and don't think about functional purity at all. That's fine. My point was that the only optimizations possible are possible on strictly pure functions (the immutable cast one included). Weakly pure functions add nothing. But merely having them around means that when I annotate a function with "pure", I do not promise any guarantees that the compiler can actually use to perform optimizations. Shachar This is a good article motivating the relaxed purity model we have: http://klickverbot.at/blog/2012/05/purity-in-d/
Re: rvalues -> ref (yup... again!)
On 3/28/18 7:50 AM, Timon Gehr wrote: "The proposal could be amended to accept mutable ref's depending on the value-judgement balancing these 2 use cases. Sticking with const requires no such value judgement to be made at this time, and it's much easier to relax the spec in the future with emergence of evidence to do so." Just get it right the first time. "const" is a serious API restriction, and it shouldn't be forced on anyone, even intermittently until they figure out that it is too restrictive (as well as viral). A great way to move things forward here, Timon, is to write a pull request against the DIP with motivating text and examples.
Re: Deprecating this(this)
On 4/1/18 10:59 AM, Nicholas Wilson wrote: On Sunday, 1 April 2018 at 14:31:24 UTC, Andrei Alexandrescu wrote: There's a mix of fundamental flaws and bugs. I'll get to the flaws in a second. About the bugs: people have altered their code in various ways to work with the bizarre semantics of this(this). Now, if we fix various bugs in this(this) by virtually redefining it, then we'll break a lot of code in a lot of ways. To wit, we fixed a small issue and it already created problems: https://github.com/dlang/dmd/pull/8032. That didn't contribute to the decision but is quite illustrative. I found two fundamental flaws with this(this): 1. For immutable objects, typechecking in the presence of successive modifications of data (first assignment by the compiler, then modification by the user) is very difficult if not impossible. I don't know how to do it. The single initialization model (raw/cooked) used currently in regular immutable constructors works reasonably well and is robust. 2. For shared objects, the part done by the compiler and the part done by this(this) should be synchronized together. This makes it impossible for the user to e.g. define a struct that gets copied atomically. See my other reply: but why is it necessary to consider the blit logically distinct from the postblit w.r.t to program flow observability? for 1. consider immutable foo = ...; immutable bar = foo; to be immutable foo = ...; immutable bar = () {mutable _ = bitcopy(foo); _.__postblit(); return _;}(); Negative. The problem is typechecking postblit itself, not its invocation. for 2. you would have to synchronize anyway for shared, it makes no difference. Negative. Consider: shared struct Point { private long x, y, z; private Mutex mutex; ... } Task: define the copy primitive of Point so atomically copy x, y, and z using mutex. The problem is, the compiler will memcpy the three longs non-atomically before the user even gets a crack at intercepting the operation. There'd be an additional issue - this(this) is non-templated, which requires combinatorial additions when qualifiers are present on the source or destination side. (Perhaps this is what you're referring to, but all you have said so far is "this doesn't work and we need to fix it") the post blit is surely like a destructor: there's only one way to do it, irrespective of the attributes, especially of the intermediate is considered mutable until the end of post blit, like static module constructors initialising global immutables. Negative. Ignoring qualifiers during copying opens holes in the type system the size of China. Or at least Australia as it were :o). Consider: int[] sneaky; struct A { private int[] innocent; this(this) { sneaky = innocent; } } void main() { immutable a = A([1, 2, 3]); auto b = a; sneaky[1] = 42; // oops import std.stdio; writeln(a.innocent); // ops } Sadly this (and many similar ones) compiles and runs warning-free on today's compiler. We really need to close this loop, like, five years ago. I agree that we should fix any type checking bugs that may be present, and that we should strive to not make the same mistake twice, however I wouldn't call either of the above cases a showstopper. You will need to show more of what is broken and why it is broken given the expected breakage. Such discussions will be indeed present in the DIP. Andrei
Re: __has_side_effects
On 4/1/18 9:39 AM, Uknown wrote: On Sunday, 1 April 2018 at 10:23:40 UTC, Andrei Alexandrescu wrote: On 4/1/18 2:22 AM, Uknown wrote: [...] That's a great initiative, and a worthy trait for the stdlib. I think you'd have an easier time if you reasoned from the other end. A function is strongly pure if all of the following are true: [...] I got a working implementation that satisfies your requirements in about 60 lines. I will make a Pull Request as soon as I write the Docs and unittests. Here's the implementation: https://run.dlang.io/is/kVpv36 Terrific, thanks!!
Re: __has_side_effects
On 4/1/18 9:46 AM, Jonathan M Davis wrote: In principle, a function which has const parameters could be treated as strongly pure if it's given immutable arguments I want to give coders leeway to cheat on that. I'll explain later (allocators).
Re: Deprecating this(this)
On 4/1/18 9:37 AM, Jonathan M Davis wrote: One issue is that postblit constructors fundamentally don't work with const. Actually they do...
Re: Deprecating this(this)
On 4/1/18 8:55 AM, ag0aep6g wrote: On 04/01/2018 03:08 AM, Andrei Alexandrescu wrote: On 3/31/18 8:32 PM, H. S. Teoh wrote: [...] What exactly is it about this(this) that blocks us from doing that? See the updated docs. Too many bugs in design and implementation. Removing this(this) is going to be a huge breaking change far bigger than, say, removing autodecoding ever will be. We're not removing it as much as evolving it: we define an alternate copying mechanism, and once that is in tip-top shape, we deprecate this(this). Is there a fundamental flaw in the postblit idea, or are you just going to give postblit a new syntax, and try to avoid all the issues that `this(this)` currently has? If there's a fundamental flaw, I'd be interested in what it is. I can't make it out in your additions to the spec, if it's in there. I can see that `this(this)` is a mess, but it also looks like a lot could be fixed. For example, how it interacts with const/immutable is ridiculous, but that could probably be fixed. If you're just going for a clean slate, I can see the appeal. You avoid dealing with the hard breakage that fixing `this(this)` would most probably bring. There's a mix of fundamental flaws and bugs. I'll get to the flaws in a second. About the bugs: people have altered their code in various ways to work with the bizarre semantics of this(this). Now, if we fix various bugs in this(this) by virtually redefining it, then we'll break a lot of code in a lot of ways. To wit, we fixed a small issue and it already created problems: https://github.com/dlang/dmd/pull/8032. That didn't contribute to the decision but is quite illustrative. I found two fundamental flaws with this(this): 1. For immutable objects, typechecking in the presence of successive modifications of data (first assignment by the compiler, then modification by the user) is very difficult if not impossible. I don't know how to do it. The single initialization model (raw/cooked) used currently in regular immutable constructors works reasonably well and is robust. 2. For shared objects, the part done by the compiler and the part done by this(this) should be synchronized together. This makes it impossible for the user to e.g. define a struct that gets copied atomically. There'd be an additional issue - this(this) is non-templated, which requires combinatorial additions when qualifiers are present on the source or destination side. Please note that fixing one or two of these issues doesn't make this(this) viable - I'm mentioning various issues, each of which is a showstopper. Nevertheless knowing them is necessary so we don't make the same mistake again! Andrei
Re: Deprecating this(this)
On 4/1/18 6:04 AM, Johannes Loher wrote: This seems really sudden, april fool's joke? Not really sure, as there are real problems with this(this)... I'm glad I've sent it yesterday then at least in my time zone :o). This looks sudden but isn't. Eduard and I have been blocked by this problem seriously whilst working on the collections library. Andrei
Re: __has_side_effects
On 4/1/18 2:22 AM, Uknown wrote: On Sunday, 1 April 2018 at 05:27:38 UTC, Uknown wrote: [...] I knew I was missing something. Fixed it, thanks https://run.dlang.io/is/tZeZrP Sorry for the spam, but I also managed to miss `immutable`, `const` and when T has mutable indirections Final version that I'm sure covers all the cases: https://run.dlang.io/is/kGoU4X That's a great initiative, and a worthy trait for the stdlib. I think you'd have an easier time if you reasoned from the other end. A function is strongly pure if all of the following are true: * Each parameter: - is immutable, OR - can be converted automatically to immutable (i.e. has no mutable indirections) AND is passed by value * The return type: - is immutable, OR - can be converted automatically to immutable (We don't want to give const this much power yet for other reasons.) The template should support taking the function name as a string, too, and the parameter types so as to easily distinguish across overloads. This would be a great addition to std.traits. Once we have it, we'll have a precise unified definition of strongly pure across the language spec and the stdlib definition. Please follow up, thanks! Andrei
Re: Deprecating this(this)
On 3/31/18 8:32 PM, H. S. Teoh wrote: On Sat, Mar 31, 2018 at 07:38:06PM -0400, Andrei Alexandrescu via Digitalmars-d wrote: [...] Once we have that, we can encapsulate desirable abstractions (such as @nogc safe collections that work in pure code), regardless of how difficult their implementations might be. It seems that currently this(this) does not allow us to do that. What exactly is it about this(this) that blocks us from doing that? See the updated docs. Too many bugs in design and implementation. Removing this(this) is going to be a huge breaking change far bigger than, say, removing autodecoding ever will be. We're not removing it as much as evolving it: we define an alternate copying mechanism, and once that is in tip-top shape, we deprecate this(this). A lot of us here have essentially given up on const except for a few very narrow cases. The transitive nature of const makes it extremely difficult to work with in the general case, even though the simplest use cases are workable. Immutable is where it's at, in terms of usefulness. Const is a mere servant of it (and of mutable). One of the biggest stumbling blocks is that whenever ranges are involved, const is practically out of the question, because even though it can be made to work for most cases, there will almost always be that one pathological case where it's impossible / too hard to work around, and that ruins it for everything else, so that it's much simpler to just avoid it altogether. Yah, the DIP might address that, too. Consider: void fun(R)(R arr) { pragma(msg, typeof(arr)); } void main() { immutable(int[]) arr = [ 1, 2, 3 ]; pragma(msg, typeof(arr)); fun(arr); } The program prints during compilation: immutable(int[]) immutable(int)[] Interesting! So the type of the array changes during template matching, which is an exception to the rule that templates always glom to the exact type passed. This is a hack introduced in the compiler in response to the issues you mention. But we don't need hacks and special casing - we need a means for types to say "here's what needs to happen when a template parameter is matched against this type". So the DIP would address manipulating qualified ranges as a perk. The one nagging question I've been having about pure is: how much are we actually taking advantage of the guarantees provided by pure? Very little, but that doesn't matter. The problem is it's underspecified. So now it's like a vague threat - whenever we mess with fear somebody comes asking, but what about an aggressive compiler doing some unexpected optimizations based on such and such interpretation? We need to lock pure down. Andrei