Re: C's Biggest Mistake on Hacker News
On Thursday, 26 July 2018 at 06:04:33 UTC, Paulo Pinto wrote: On Wednesday, 25 July 2018 at 21:16:40 UTC, Walter Bright wrote: On 7/24/2018 4:53 AM, Ecstatic Coder wrote: str = str1 + " " + str2; But you have to be careful how it is written: str = "hello" + "world"; str = "hello" + "world" + str1; don't work, etc. Well, like everything in C++, there is always a way. str = "hello"s + "world"; str = "hello"s + "world" + str1; Spot the difference. :) It's just synctactic sugar for a constructed string. You can't even use C++14 string constants to initialize a string view, or you have a dangling pointer, as it's NOT a true constant. Ridiculous...
Re: An Optional!T and the implementation of the underlying type's opUnary
On Wednesday, 25 July 2018 at 21:59:00 UTC, aliak wrote: It needs to work with const as well and immutable too. immutable a = 3; auto b = -a; // is ok, should be ok with the optional as well. Plus T can be a custom type as well with "some" definition of opUnary. I can't seem to find any implementation guidelines either so I assume opUnary or any of the ops implementation details is implementation defined. Template this[0] (and CopyTypeQualifiers[1])to the rescue! import std.traits: isPointer, CopyTypeQualifiers; auto opUnary(string op, this This)() if (__traits(compiles, (CopyTypeQualifiers!(This, T) t){ mixin("return "~op~"t;"); })) { alias U = CopyTypeQualifiers!(This, T); static if (op == "*" && isPointer!T) { import std.traits: PointerTarget; alias P = PointerTarget!U; return empty || front is null ? no!P : some(cast(P)*this._value); } else { if (empty) { return no!U; } else { return some(mixin(op ~ "cast(U)_value")); } } } unittest { Optional!int a; ++a; auto a2 = -a; assert(!a2._hasValue); a = some(3); a++; immutable b = Optional!int(3); static assert(!__traits(compiles, ++b)); auto b2 = -b; } As for assigning to Optional!(immutable int), the language basically forbids this (cannot modify struct with immutable members). It would, as you say, cause problems when you can get a pointer to the contents. [0]: https://dlang.org/spec/template.html#template_this_parameter [1]: https://dlang.org/phobos/std_traits#CopyTypeQualifiers -- Simen
Re: "catch" not catching the correct exception
Hmm, sounds like the vtable and hence TypeInfo part of the reference is getting corrupted. Have you checked that the type matches where you throw it?
Re: C's Biggest Mistake on Hacker News
On Wednesday, 25 July 2018 at 21:16:40 UTC, Walter Bright wrote: On 7/24/2018 4:53 AM, Ecstatic Coder wrote: str = str1 + " " + str2; But you have to be careful how it is written: str = "hello" + "world"; str = "hello" + "world" + str1; don't work, etc. Well, like everything in C++, there is always a way. str = "hello"s + "world"; str = "hello"s + "world" + str1; Spot the difference. :)
"catch" not catching the correct exception
Under mecca, we're using GC free exceptions. I have code that uses mkEx (https://github.com/weka-io/mecca/blob/master/src/mecca/lib/exception.d#L307). Essentially, it constructs an exception in place inside a fiber-local buffer. The construction code seems correct, and the parent seems set correctly (Exception). When thrown, however, a catch for Exception does not catch it. It is caught if we try to catch Throwable, and also if we try to catch FiberInterrupt (a class deriving directly from Throwable). Thinking the buffer might have gotten corrupted by one of the scope exits, I've added the following code: catch (Exception ex) { // Code that should have run goes here } catch(Throwable ex) { META!"XXX NONONONONO caught %s of type %s son of %s"(cast(void*)ex, ex.classinfo.name, ex.classinfo.base.name); LOG_EXCEPTION(ex); throw ex; } When run, I get the following log: META XXX NONONONONO caught 0x7F1C616F39B0 of type weka.bucket.exceptions.NotBucketLeader son of object.Exception It seems immediately obvious that the problem is not with using a static buffer for the exception (at least, it does not seem to be corrupted), but something else. Somehow, the catch matching does not work. At which point I'm stuck. I don't know how D's catch matching works, so I don't know where to continue looking. The problem does not happen consistently, but does happen frequently enough for me to be able to reproduce it when needed. I need suggestions on how to debug this. Thank you, Shachar
Re: Looking for the article comparing D to Ada and others
On Thursday, 26 July 2018 at 02:21:58 UTC, Ali Çehreli wrote: On 07/25/2018 04:27 PM, Nicholas Wilson wrote: On Wednesday, 25 July 2018 at 21:59:52 UTC, Ali Çehreli wrote: Somebody had posted an article here on how well different languages matched certain requirements of a certain coding safety standards. I remember D was doing pretty well and I think Ada (or SPARK?) was included as well. What article? Where? Thank you, Ali https://dlang.org/blog/2018/06/20/how-an-engineering-company-chose-to-migrate-to-d/ Thanks but no. :) The article I'm looking for was specifically for comparing languages against each paragraph (point?) of a safety spec. Ali Oh, I vaguely remember that too. I think it was the MISRA spec? Or was it JSF or something else? Can't quite remember, sorry.
Re: Struct Initialization syntax
On Tuesday, 24 July 2018 at 16:35:32 UTC, H. S. Teoh wrote: On Tue, Jul 24, 2018 at 01:13:16PM +, Dukc via Digitalmars-d wrote: On Tuesday, 24 July 2018 at 12:37:21 UTC, Cym13 wrote: > That argument sounds quite dangerous to me, especially since > my experience is on the contrary that constructor arguments > are often named the same as the attribute they refer to. And > what of mixed cases? I really wouldn't rely on anything like > naming conventions for something like that. I was going to ask that how can they be named the same since the argument would then shadow the member, but then I realized that this works: struct S { int a; int b; this(int a, int b) { this.a = a; this.b = b; } } Yes, you are right. It works, but TBH it's quite a bad idea, and very confusing to read. This is a very common programming style and is found in numerous programming books and tutorials. Personal judgments as to whether it's a good idea or confusing are completely beside the point; designers of struct initialization syntax should not impose such judgments on the rest of the world, possibly forcing people to change their code and their texts. And TBH, if all the ctor is doing is copying its arguments to member variables, then we really should be more DRY and have special syntax for doing that, ala C++ (though the C++ syntax itself is pretty pathological... D could use better syntax, but the idea remains: get rid of redundancy like `this.a = a` or `a = _a`). T This too is completely off topic. And there are hundreds of thousands of extant lines of such code in various languages other than C++ (or Scala, which has a different and more concise way to avoid this boilerplate), and it hasn't been a big deal. Some people use IDE forms/macros to fill in these common lines. Back to the topic: I think #1 is noisy and confusing -- it looks like a function or ctor call but isn't, and it looks like {...} is a literal but isn't. I think #2 has to be considered in conjunction with and dependent on named parameters. If named parameters use the same syntax then #2 could be treated as if it were a call to an implicit ctor that takes optional named parameters corresponding to each member, which would provide uniformity, but I think it's a bit dangerous and confusing, using the same syntax to do two different things, initialization and construction. I think #3 is straightforward, clear, and consistent with existing struct initialization ... does it have any downsides?
Re: Looking for the article comparing D to Ada and others
On 07/25/2018 04:27 PM, Nicholas Wilson wrote: On Wednesday, 25 July 2018 at 21:59:52 UTC, Ali Çehreli wrote: Somebody had posted an article here on how well different languages matched certain requirements of a certain coding safety standards. I remember D was doing pretty well and I think Ada (or SPARK?) was included as well. What article? Where? Thank you, Ali https://dlang.org/blog/2018/06/20/how-an-engineering-company-chose-to-migrate-to-d/ Thanks but no. :) The article I'm looking for was specifically for comparing languages against each paragraph (point?) of a safety spec. Ali
Re: C's Biggest Mistake on Hacker News
On Wed, Jul 25, 2018 at 11:27:45PM +, Laeeth Isharc via Digitalmars-d wrote: > On Tuesday, 24 July 2018 at 00:41:54 UTC, RhyS wrote: [...] > > I am sorry to say but to succeed as a language beyond being a small > > or hobby language it takes: Being established already or having a > > big name to hype behind your "product". > > I don't agree. We are in a time of positive disruption when old > heuristics break down. > > All D has to do is to keep compounding its adoption and what average > people think of D is completely irrelevant. What's important is what > the best people amongst those who are principals rather than agents > think of D. There's no point selling it to a committee, but who wants > to deal with committees anyway - life is too short for that if one > possibly has the choice. +1. [...] > > If i am honest, DasBetterC is a for me unreliable D product because > > using specific D library function can be GC. Or DasBetterC needs to > > be sold as C only, ever, forget about everything else that is D ( > > library, packages, ... ). Until everything is 100% GC free, your > > going to run into this. And even when its 100% GC free, people have > > long memories. > > Don't use it if you don't want to. But making predictions is a tricky > thing and mostly of not much value. I think it's more interesting to > be the change you wish to see in the world. [...] +1!!! Predictions rarely come true, as history proves. And for the amount of effort put into naysaying, so much more could have done productively. But hey, if that's what people like doing, then what is one to say. T -- Being able to learn is a great learning; being able to unlearn is a greater learning.
Re: C's Biggest Mistake on Hacker News
On Tuesday, 24 July 2018 at 00:41:54 UTC, RhyS wrote: On Monday, 23 July 2018 at 22:45:15 UTC, Walter Bright wrote: I've predicted before that what will kill C is managers and customers requiring memory safety because unsafeness costs them millions. The "just hire better programmers" will never work. I have yet to see a company Walter where higher ups will take correct actions to resolve issues. It might be that you are working for the wrong companies. Half the companies in the world are below average and few are excellent. And most manager are not going to rock the boat and stick their necks out. Not when they can simply blame issues on programmer incompetence or "it has always been like that with programming languages". I have yet to see managers really taking responsibility beyond guiding the projects so they do not get fired and hope to rack in bonuses. Issues can always be blamed on the tools or programmers. That's a good point, but the nice thing about not having dominant market share is it's easy to grow it. You don't need to convince most managers. Just a few more people who are on the edge already anyway. Quality is better than quantity because the former concentrate power. And frankly, good luck convincing any company to convert millions of C code into D code. The point is with betterC you don't need to. And on the other hand if you did, libclang would take quite a lot of the pain out once you did a bit of work upfront. See DPP I am sorry to say but to succeed as a language beyond being a small or hobby language it takes: Being established already or having a big name to hype behind your "product". I don't agree. We are in a time of positive disruption when old heuristics break down. All D has to do is to keep compounding its adoption and what average people think of D is completely irrelevant. What's important is what the best people amongst those who are principals rather than agents think of D. There's no point selling it to a committee, but who wants to deal with committees anyway - life is too short for that if one possibly has the choice. Its the same reason why PHP despite being a good language ( for what it is ) ! , still keeps getting the exact same crude on forums. If i am honest, DasBetterC is a for me unreliable D product because using specific D library function can be GC. Or DasBetterC needs to be sold as C only, ever, forget about everything else that is D ( library, packages, ... ). Until everything is 100% GC free, your going to run into this. And even when its 100% GC free, people have long memories. Don't use it if you don't want to. But making predictions is a tricky thing and mostly of not much value. I think it's more interesting to be the change you wish to see in the world.
Re: Looking for the article comparing D to Ada and others
On Wednesday, 25 July 2018 at 21:59:52 UTC, Ali Çehreli wrote: Somebody had posted an article here on how well different languages matched certain requirements of a certain coding safety standards. I remember D was doing pretty well and I think Ada (or SPARK?) was included as well. What article? Where? Thank you, Ali https://dlang.org/blog/2018/06/20/how-an-engineering-company-chose-to-migrate-to-d/
Re: C's Biggest Mistake on Hacker News
On Wednesday, 25 July 2018 at 21:16:40 UTC, Walter Bright wrote: On 7/24/2018 4:53 AM, Ecstatic Coder wrote: str = str1 + " " + str2; But you have to be careful how it is written: str = "hello" + "world"; str = "hello" + "world" + str1; don't work, etc. Yeah. That's exactly there where D shines, and C++ s*cks... C++ string constants are stupid pointers, no size etc. Indeed one big C++ silly thing that Walter fixed perfectly. He is the only language designed who found and applied the perfect solution for strings, arrays and slices. Big respect to him...
Re: C's Biggest Mistake on Hacker News
On Wednesday, 25 July 2018 at 20:24:39 UTC, bpr wrote: On Wednesday, 25 July 2018 at 17:23:40 UTC, Ecstatic Coder wrote: But don't be too optimistic about BetterC... I'm too old to get optimistic about these things. In the very best case, D has quite an uphill battle for market share. Any non mainstream language does. If I were a betting man, I'd bet on Rust. Honestly, considering D's leadership current priorities, I don't see how it could become soon a true C++ or Go competitor, even with the half-baked BetterC initiative... There are a few ways I can see, and doubtless others can see different ones. Here's one: use Mir and BetterC to write a TensorFlow competitor for use in developing and deploying ML models. I'm sure you can shoot holes in that idea, but you get the point. Try lots of things and see what works, and keep doing more of those things. Worked for Python. For instance, I've suggested they consider using reference counting as an alternative default memory management scheme, and add it to the lists of scolarship and crowdsourced project, and of course they have added all the other suggestion, but not this one. What a surprise ;) I'm pretty sure D leadership is pursuing such things. In fact, https://wiki.dlang.org/Vision/2018H1 rather prominently mentions it. Despite this is probably one of the most used allocation management scheme in typical C++ development, as this drastically reduces the risks of memory leaks and dangling pointers... Anyway, meanwhile D remains a fantastic strongly-typed scripting language for file processing and data analysis, and its recent adoption at Netflix has once again clearly proved it... For this and similar uses, tracing GC is fine, better in fact than the alternatives. I'm only making noise about betterC for the cases where C++ dominates and tracing GC is a showstopper. In an alternative timeline, DasBtterC would have been released before D with GC, and the main libraries would have been nogc, and maybe there'd be a split between raw pointers and traced refs (like Nim and Modula-3) and then maybe there'd have been no strong desire for Rust since D could have filled that niche. +1
Re: DIP 1016--ref T accepts r-values--Community Review Round 1
On Wednesday, 25 July 2018 at 21:55:00 UTC, Manu wrote: On Wed, 25 Jul 2018 at 13:55, 12345swordy via Digitalmars-d wrote: > It's not a false equivalence fallacy: all the discussion is > about IMPLICIT conversion or rvalues to lvalues. Yes it is, the issues regarding rvalue/lvalue conversion is not the same issues regarding the unsigned/signed conversion. I don't want to encourage this tangent, but I do want to say; there's no proposal of rvalue -> lvalue *conversion*. The proposal is "ref accepts rvalues". There's no 'conversion' anywhere in sight. That's not on the menu. Semantics? Call it a transformation. But it is an implicit changing of semantics. Guess you encouraged it :p
Looking for the article comparing D to Ada and others
Somebody had posted an article here on how well different languages matched certain requirements of a certain coding safety standards. I remember D was doing pretty well and I think Ada (or SPARK?) was included as well. What article? Where? Thank you, Ali
Re: An Optional!T and the implementation of the underlying type's opUnary
On Wednesday, 25 July 2018 at 18:01:54 UTC, Atila Neves wrote: This works for me: struct Optional(T) { private T _value; private bool empty = true; this(T value) { _value = value; empty = false; } auto opUnary(string op)() { if(!empty) mixin(op ~ "_value;"); return this; } string toString() const { import std.conv: text; return empty ? "None!" ~ T.stringof : text("Some!", T.stringof, "(", _value.text, ")"); } } void main() { import std.stdio; Optional!int nope; writeln(nope); auto mut = Optional!int(3); ++mut; // compiles writeln(mut); immutable imut = Optional!int(7); // ++imut; // error } It needs to work with const as well and immutable too. immutable a = 3; auto b = -a; // is ok, should be ok with the optional as well. Plus T can be a custom type as well with "some" definition of opUnary. I can't seem to find any implementation guidelines either so I assume opUnary or any of the ops implementation details is implementation defined.
Re: DIP 1016--ref T accepts r-values--Community Review Round 1
On Wed, 25 Jul 2018 at 13:55, 12345swordy via Digitalmars-d wrote: > > > It's not a false equivalence fallacy: all the discussion is > > about IMPLICIT conversion or rvalues to lvalues. > Yes it is, the issues regarding rvalue/lvalue conversion is not > the same issues regarding the unsigned/signed conversion. I don't want to encourage this tangent, but I do want to say; there's no proposal of rvalue -> lvalue *conversion*. The proposal is "ref accepts rvalues". There's no 'conversion' anywhere in sight. That's not on the menu.
Re: C's Biggest Mistake on Hacker News
On Tuesday, 24 July 2018 at 07:19:21 UTC, Paolo Invernizzi wrote: If I'm not wrong, Python has grown up really slowly and quietly, till the recent big success in the scientific field. Python replaced Perl and to some extent Php... Two very questionable languages, which was a good starting-point. C++98 was a similarly questionable starting-point, but nobody got the timing right when that window was open. The success of Python in scientific computing is to a large extent related to C though.
Re: C's Biggest Mistake on Hacker News
On 7/24/2018 4:53 AM, Ecstatic Coder wrote: str = str1 + " " + str2; But you have to be careful how it is written: str = "hello" + "world"; str = "hello" + "world" + str1; don't work, etc.
Re: DIP 1016--ref T accepts r-values--Community Review Round 1
On Wednesday, 25 July 2018 at 19:55:50 UTC, Paolo Invernizzi wrote: I don't know what vocabulary you are used to consult, ad hominem attacks is not an argument Actually, by definition, every bug is made by a programmer that THINK to know what he is doing... no? Avoiding burden of proof by shifting goal post. Aren't you. going a little too far in judging? loaded question An so? He has explain the point in detail, go back and read his post. It's not a false equivalence fallacy: all the discussion is about IMPLICIT conversion or rvalues to lvalues. Yes it is, the issues regarding rvalue/lvalue conversion is not the same issues regarding the unsigned/signed conversion. Alexander
Re: C's Biggest Mistake on Hacker News
On Wednesday, 25 July 2018 at 17:23:40 UTC, Ecstatic Coder wrote: But don't be too optimistic about BetterC... I'm too old to get optimistic about these things. In the very best case, D has quite an uphill battle for market share. Any non mainstream language does. If I were a betting man, I'd bet on Rust. Honestly, considering D's leadership current priorities, I don't see how it could become soon a true C++ or Go competitor, even with the half-baked BetterC initiative... There are a few ways I can see, and doubtless others can see different ones. Here's one: use Mir and BetterC to write a TensorFlow competitor for use in developing and deploying ML models. I'm sure you can shoot holes in that idea, but you get the point. Try lots of things and see what works, and keep doing more of those things. Worked for Python. For instance, I've suggested they consider using reference counting as an alternative default memory management scheme, and add it to the lists of scolarship and crowdsourced project, and of course they have added all the other suggestion, but not this one. What a surprise ;) I'm pretty sure D leadership is pursuing such things. In fact, https://wiki.dlang.org/Vision/2018H1 rather prominently mentions it. Despite this is probably one of the most used allocation management scheme in typical C++ development, as this drastically reduces the risks of memory leaks and dangling pointers... Anyway, meanwhile D remains a fantastic strongly-typed scripting language for file processing and data analysis, and its recent adoption at Netflix has once again clearly proved it... For this and similar uses, tracing GC is fine, better in fact than the alternatives. I'm only making noise about betterC for the cases where C++ dominates and tracing GC is a showstopper. In an alternative timeline, DasBtterC would have been released before D with GC, and the main libraries would have been nogc, and maybe there'd be a split between raw pointers and traced refs (like Nim and Modula-3) and then maybe there'd have been no strong desire for Rust since D could have filled that niche.
Re: DIP 1016--ref T accepts r-values--Community Review Round 1
On Wednesday, 25 July 2018 at 17:52:00 UTC, 12345swordy wrote: On Wednesday, 25 July 2018 at 16:43:38 UTC, Paolo Invernizzi wrote: That's an opinion, naturally. No I am expressing an argument not an opinion. I don't know what vocabulary you are used to consult, but your 'pointless' it's a plain and simple opinion. To me it's not pointless at all. "let's force the programmer to think about what he is doing, passing an rvalue by ref" Nonsense, you have shown no evidence that they don't know what they are doing when making a automatic conversion. You might as well argue against the existence of var. Actually, by definition, every bug is made by a programmer that THINK to know what he is doing... no? Aren't you. going a little too far in judging? At best, is "let's catch early some bugs (caused by other problems as Manu pointed out)". He also pointed it is own class of problems, as it can be replicated without ref. An so? Jonathan argumentation and mine is that are are. losing a way to catch such bugs earlier. Set of problems as automatic promotion or conversion, as decades of problems with unsigned/signed have proved... False Equivalence. We are not discussing numeric overflows here. It's not a false equivalence fallacy: all the discussion is about IMPLICIT conversion or rvalues to lvalues... your argumentation smell a little about strawmen (eheh) There's not a magic conversion between apples and oranges in a foreach loop... ref value apart. https://dlang.org/spec/type.html#usual-arithmetic-conversions You where saying? I'm saying that a foreach statement is easily lowered mentally in a for statement, and that implicitly converting between rvalue and lvalue is entirely another beast. I will stop here... btw
Re: DIP 1016--ref T accepts r-values--Community Review Round 1
On Wed, 25 Jul 2018 at 10:45, Atila Neves via Digitalmars-d wrote: > > On Saturday, 21 July 2018 at 08:59:39 UTC, Manu wrote: > > [...] > > 3. Scenario depends on introduction of a getter, but any getter > > property that returns a member by-val is almost certainly a > > primitive > > type. A getter for a struct member would necessarily return a > > ref, or > > it would experience large copy semantics every time the get is > > called! > > This is assuming anything that isn't a primitive is a large > struct that is copied, which, in my experience, is rarely the > case. But my point is, that exact reasoning extends to the hypothetical ref argument as the return value. If a property function sees fit to return by-value (ie, struct is small), then a function receiving that object will also receive the argument by-value. This will be the usual pattern. When a type becomes large enough to want to pass it by ref, any property that returns one will also most likely return by ref. I'm trying to say that, a mismatch is naturally unlikely to occur. And very unlikely occur *by accident*; it would be a design intent. > I don't recall ever implementing a getter in D that returns by > ref. I'd consider that a code smell in pretty much every > language, allowing mutation from the outside. Such a getter would likely return const ref, but discussions about proper use of 'const' are not on topic here. > For context, I > think that getters are a faint code smell and that setters always > stink. So, you're reducing the power of the properties argument in principle? > All of this to say that I disagree that getters will usually > return by ref unless the return type is a primitive. That's not > how I write code and I don't remember encountering this in the > wild. Agreed. My above amendment should be a more accurate tendency, which is what I was trying to express, but in too-few words. > > (`ref` is not the bug) > > - note, in all other constructions of this same 'bug', > > existing > > language semantics find it acceptable to silently accept the > > accidental mutation of an expiring rvalue. Nobody is losing > > sleep at > > night. > > That's because T().mutate() is obviously not going to do > anything. Nobody would expect it to. Of course `T().mutate()` is obvious, but `s.member.mutate()` (where member is property) might be misunderstood to do something. I don't see how the exact set of arguments being applied to ref don't apply here (and many other possible cases). > > The same 'bug' expressed in a simpler and more likely way: > > > > // a struct that shall be the member > > struct M { > > int x; > > void mutate() { ++x; } > > } > > > > // the original (working) code > > struct S { > > M member; > > } > > S s; > > s.member.mutate(); > > It'd take roughly 5s between me seeing this in code review and > typing the words "Law of Demeter violation". To me that's TRWTF. I don't understand what you're saying here? I think this case is equally hard to spot as the passing-property-as-ref-arg case. Either way, the solution to this whole branch of discussion lies with property, not with ref (and I've given some ideas).
Re: DIP 1016--ref T accepts r-values--Community Review Round 1
On Wed, 25 Jul 2018 at 10:45, Atila Neves via Digitalmars-d wrote: > > > ...all that said, we understand that there is value in > > inhibiting calls with rvalues in some cases. We address this in > > a very nice way with @disable, which is also nicely symmetrical > > such that the limitation may by applied to rval or lval's. > > I like using @disable this way. It's unclear to me the impact on > existing code that doesn't already have a @disable since it > wasn't needed before. > > I'm not against the DIP - I think easier interop with C++ is a > good thing and this would help it. I have to think a bit more > about the points Jonathan has brought up, because it sounds like > there's a possibility that bugs might be introduced if the DIP > goes through, at least as-is. I'm not sure. FWIW; I presented a further solution for the property case, which I think is a good improvement for properties in general (it will address other constructions of this same issue that aren't in conjunction with ref). It addresses the issue Jonathan raised in the domain where the problem exists, and leaves unrelated problems outside of this DIP's problem space.
Re: DIP 1016--ref T accepts r-values--Community Review Round 1
On Wed, 25 Jul 2018 at 04:50, Jim Balter via Digitalmars-d wrote: > > On Wednesday, 25 July 2018 at 08:34:30 UTC, Manu wrote: > [snip] > > > Meanwhile I think we have determined that the presumed > > practical trouble > > cases are even less that I suspected up front. > > That's surprising; I didn't realize that you suspected practical > trouble cases. My initial draft was written for 'ref const T ', and that was a conservative choice because I felt the same unsubstantiated fear. I think it's like this; there is a presumption that the feature was made that way for a reason... so it *must* be protecting us against something that it was designed to protect us against, right? Others argued to remove the 'const' from my proposal, and then the more I thought on that, and followed various experiments through, I realised that my fears were unsubstantiated (I couldn't dream up legitimate problem cases), and that mutable ref brought significant additional value which actually strengthen the DIP substantially. I still suspect it's possible to contrive a case where a bug may be caught by the existing mechanic, but what we have determined by following some of these cases presented here is that they're far less likely than even I initially _imagined_ (yes, still working from the same unsubstantiated fear), or that the bugs are actually unrelated issues which should be addressed separately. For instance, I can imagine a DIP to address the property concern that we have identified here: ** Mutable-but-also-byval properties (ie, a property with a by-val getter and also a setter) do not behave like a user expects when supplied as ref arguments. ** Situation: a by-val getter passes an rval to a ref arg, which may be mutated, and the results are lost. ** Propose: after the function call concludes, call the properties setter, supplying the potentially mutated rval that the getter returned. This very simple semantic will cause non-ref properties to function correctly even in the context of by-val getting and ref. I actually think this is a very elegant solution to a wider class of problem with properties. ...but this comment is dangerous. I REALLY don't want this point to lead off on a tangent ;) *considers deleting post... but clicks send anyway...*
Re: An Optional!T and the implementation of the underlying type's opUnary
On Wednesday, 25 July 2018 at 12:51:08 UTC, aliak wrote: Hi, I'm working on an Optional!T type that is a mixture of Scala's Option[T] (i.e. range based) and Swift's and Kotlin's T? (i.e. safe dispatching). I'm interested in hearing about mutability concerns. So I want operations on the optional to dispatch to the underlying type T if it's present. So let's take opUnary as an example, this is how it's currently implemented: auto opUnary(string op)() { return this.opUnaryImpl!op(); } auto opUnary(string op)() const { return this.opUnaryImpl!(op, const(T))(); } auto opUnary(string op)() immutable { return this.opUnaryImpl!(op, immutable(T))(); } private auto opUnaryImpl(string op, U = T)() const { import std.traits: isPointer; static if (op == "*" && isPointer!U) { import std.traits: PointerTarget; alias P = PointerTarget!U; return empty || front is null ? no!P : some(cast(P)*this._value); } else { if (empty) { return no!U; } else { return some(mixin(op ~ "cast(U)_value")); } } } (functions "some" and "no" are type constructors which return an Optional!T of whatever the argument type is - except "no" needs an explicit T argument) Why not "opUnary(string op)() inout"? The reason it's like this is because I want to transfer the constness of "this" to the value T that is stored inside. If I rewrite "opUnaryImpl()() const" as "opUnary()() inout" and remove the implementation for mutable, const, and immutable, then this works: immutable a = Optional!int(3); ++a; And the internal value is modified. Should that be allowed? The caveat is that 1) I want Optional!T to be nogc compatible. So therefore the value is stored similarly to this PR in phobos [1] (also for an Optional type) And 2) Optional!T provides an "unwrap" function that returns a T (if T is a class or interface), or a T*. So, if I allow modification by using inout on opUnary, then for the sake of consistency, I should be able to do this: immutable a = Optional!int(3); a = 4; But I can't do this because Optional.opAssign would be either inout or immutable and I can't modify this.value = newValue; And then what about: auto a = Optional(immutable int)(3); a = 3; // should this be allowed? If it is allowed then this will fail because of the nogc requirement: unittest { Optional!(immutable int) a = some!(immutable int)(5); immutable(int)* p = a.unwrap; assert(*p == 5); a = 4; assert(*a.unwrap == 4); assert(*p == 5); } Comments, suggestions, opinions? Cheers, - Ali [1] https://github.com/dlang/phobos/pull/3915 This works for me: struct Optional(T) { private T _value; private bool empty = true; this(T value) { _value = value; empty = false; } auto opUnary(string op)() { if(!empty) mixin(op ~ "_value;"); return this; } string toString() const { import std.conv: text; return empty ? "None!" ~ T.stringof : text("Some!", T.stringof, "(", _value.text, ")"); } } void main() { import std.stdio; Optional!int nope; writeln(nope); auto mut = Optional!int(3); ++mut; // compiles writeln(mut); immutable imut = Optional!int(7); // ++imut; // error }
Re: DIP 1016--ref T accepts r-values--Community Review Round 1
On Wednesday, 25 July 2018 at 16:43:38 UTC, Paolo Invernizzi wrote: That's an opinion, naturally. No I am expressing an argument not an opinion. "let's force the programmer to think about what he is doing, passing an rvalue by ref" Nonsense, you have shown no evidence that they don't know what they are doing when making a automatic conversion. You might as well argue against the existence of var. At best, is "let's catch early some bugs (caused by other problems as Manu pointed out)". He also pointed it is own class of problems, as it can be replicated without ref. Set of problems as automatic promotion or conversion, as decades of problems with unsigned/signed have proved... False Equivalence. We are not discussing numeric overflows here. There's not a magic conversion between apples and oranges in a foreach loop... ref value apart. https://dlang.org/spec/type.html#usual-arithmetic-conversions You where saying? -Alexander
Re: DIP 1016--ref T accepts r-values--Community Review Round 1
On Saturday, 21 July 2018 at 08:59:39 UTC, Manu wrote: On Sat, 21 Jul 2018 at 00:15, Johannes Loher via Digitalmars-d wrote: On Saturday, 21 July 2018 at 05:59:37 UTC, Manu wrote: > [...] Let me give a concrete example of one of the situations Jonathan is describing. Consider the following code: struct Secret { public: string key; } /* ... */ genrateRandomKey(ref string key) { key = /* some code to actually generate the key */ } Secret secret; generateRandomKey(secret.key); Now somebody else working on the project who sees the definition of Secret might think "Having public access to member variables is bad, so lets use property methods instead. This even allows us to do some contract checks!" and he changes the definition of Secret to the following: struct Secret { private: string _key; public: string key() @property const { return this._key; } void key(string key) @property in { assert(key.length == 256) } do { this._key = key; } } Now with DIP 1016, the use of generateRandomKey silently "fails", i.e. secret._key will not be changed by it, which in this case is a big problem as the key is still default initialized! Of course one might argue that genrateRandomKey should not take its argument by reference and rather just return the key instead. But in my experience, there is quite a lot of code like this out there (e.g. in order to avoid copying, string is probably not the best example here...). In one of your earlier answers you argued, that in cases like this, the @property function should probably have returned by reference and that not doing so is the real bug. Do you also think this is true in this case? I don't think so. One reason is for example, that you can not put contracts on your setter @property method then... In my opinion, there is no bug with the definition of the @property methods here. The bug only arises through interactions with functions which take its parameters by reference. Do you think this example in contrived? If yes, why? So, to be clear; the 'gotcha' moment as proposed is this: 1. Function mutates an input received by ref. 2. Existing code is structured so the function is called with a member of some lvalue. 3. Member is _changed_ to be an accessor property for some reason *and* the property returns the value by-val. 4. Gotcha! It is definitely pretty contrived. 1. The function in this scenario is clearly an 'out' parameter, so it should use 'out', not ref. 2. A function like that would almost certainly return its result, not mutate an argument. Using ref this way is a poor choice and subverts move semantics. 3. Scenario depends on introduction of a getter, but any getter property that returns a member by-val is almost certainly a primitive type. A getter for a struct member would necessarily return a ref, or it would experience large copy semantics every time the get is called! This is assuming anything that isn't a primitive is a large struct that is copied, which, in my experience, is rarely the case. I don't recall ever implementing a getter in D that returns by ref. I'd consider that a code smell in pretty much every language, allowing mutation from the outside. For context, I think that getters are a faint code smell and that setters always stink. All of this to say that I disagree that getters will usually return by ref unless the return type is a primitive. That's not how I write code and I don't remember encountering this in the wild. 4. A struct-type getter that returns by-val exhibits this gotcha in a variety of ways; you 'get' the member (a by-val copy), then mutate a member in any way, (ie, call a method), and you've accidentally modified the copy, not the source value! I have trouble understanding why anyone would expect to mutate the original object without first consulting the API to see if was returned by ref. I'd never expect that to happen. I don't think that's a bug because I'd never expect things to work that way. Nearly all of my variables and function parameters are const anyway. Maybe my brain is weird. All I know is that I'd never encounter this and consider it a bug. To me not mutating my object is a feature. (`ref` is not the bug) - note, in all other constructions of this same 'bug', existing language semantics find it acceptable to silently accept the accidental mutation of an expiring rvalue. Nobody is losing sleep at night. That's because T().mutate() is obviously not going to do anything. Nobody would expect it to. The same 'bug' expressed in a simpler and more likely way: // a struct that shall be the member struct M { int x; void mutate() { ++x; } } // the original (working) code struct S { M member; } S s; s.member.mutate(); It'd take roughly 5s between me seeing this in code review and typing the words "Law of Demeter violati
Re: C's Biggest Mistake on Hacker News
On Wednesday, 25 July 2018 at 16:39:51 UTC, bpr wrote: On Tuesday, 24 July 2018 at 17:24:41 UTC, Seb wrote: On Tuesday, 24 July 2018 at 17:14:53 UTC, Chris M. wrote: On Tuesday, 24 July 2018 at 16:15:52 UTC, bpr wrote: On Tuesday, 24 July 2018 at 14:07:43 UTC, Ecstatic Coder wrote: [...] No. For many C++ users, tracing GC is absolutely not an option. And, if it were, D's GC is not a shining example of a good GC. It's not even precise, and I would bet that it never will be. If I'm able to tolerate a GC, there are languages with much better GCs than the D one, like Go and Java. [...] There was a precise GC in the works at one point, no clue what happened to it. The newest PR is: https://github.com/dlang/druntime/pull/1977 Though there's already a bit of precise scanning on Windows, e.g. https://github.com/dlang/druntime/pull/1798 and IIRC Visual D uses a precise GC too. Well, this is a big problem with D IMO. There are a lot of unfinished, half baked features which linger in development for years. How long for precise GC now, over 5 years? I don't think D was really designed to be friendly to GC, and it just isn't realistic to expect that there will *ever* be a production quality precise GC for all of D. Maybe giving up on some things and finishing/fixing others would be a better strategy? I think so, which is why I think DasBetterC is the most appealing thing I've seen in D lately. +1 But don't be too optimistic about BetterC... Honestly, considering D's leadership current priorities, I don't see how it could become soon a true C++ or Go competitor, even with the half-baked BetterC initiative... For instance, I've suggested they consider using reference counting as an alternative default memory management scheme, and add it to the lists of scolarship and crowdsourced project, and of course they have added all the other suggestion, but not this one. What a surprise ;) Despite this is probably one of the most used allocation management scheme in typical C++ development, as this drastically reduces the risks of memory leaks and dangling pointers... Anyway, meanwhile D remains a fantastic strongly-typed scripting language for file processing and data analysis, and its recent adoption at Netflix has once again clearly proved it...
Re: DIP 1016--ref T accepts r-values--Community Review Round 1
On Wednesday, 25 July 2018 at 13:36:38 UTC, 12345swordy wrote: On Wednesday, 25 July 2018 at 12:40:16 UTC, Paolo Invernizzi wrote: That proposal is a 'Syntactic Sugar' feature, that simply hide what normally need to be explicitly coded: proved a temp rvalue, pass it to a callable taking ref. What you call 'simplification', I call it 'obfuscation'; what you call uniformity I call trying to spread a well justified restriction... /Paolo A restriction which causes pointless redundant code for the caller who doesn't always have source code access. If my old teacher assistant taught me anything it is this: Redundant code is bad. You are literately forcing the programmer to create tmp variables that risk the possibility of being shadowed or worse, having its value change. That's an opinion, naturally. What it's "pointless redundant" for you, it is let's "let's force the programmer to think about what he is doing, passing an rvalue by ref" for me, at least. At best, is "let's catch early some bugs (caused by other problems as Manu pointed out)", but as Jonathan states. Your manual solution suggestion have it own set of problems. Set of problems as automatic promotion or conversion, as decades of problems with unsigned/signed have proved... You might as well argue against the foreach statement, because its "obfuscation" There's not a magic conversion between apples and oranges in a foreach loop... ref value apart. /Paolo
Re: C's Biggest Mistake on Hacker News
On Tuesday, 24 July 2018 at 17:24:41 UTC, Seb wrote: On Tuesday, 24 July 2018 at 17:14:53 UTC, Chris M. wrote: On Tuesday, 24 July 2018 at 16:15:52 UTC, bpr wrote: On Tuesday, 24 July 2018 at 14:07:43 UTC, Ecstatic Coder wrote: [...] No. For many C++ users, tracing GC is absolutely not an option. And, if it were, D's GC is not a shining example of a good GC. It's not even precise, and I would bet that it never will be. If I'm able to tolerate a GC, there are languages with much better GCs than the D one, like Go and Java. [...] There was a precise GC in the works at one point, no clue what happened to it. The newest PR is: https://github.com/dlang/druntime/pull/1977 Though there's already a bit of precise scanning on Windows, e.g. https://github.com/dlang/druntime/pull/1798 and IIRC Visual D uses a precise GC too. Well, this is a big problem with D IMO. There are a lot of unfinished, half baked features which linger in development for years. How long for precise GC now, over 5 years? I don't think D was really designed to be friendly to GC, and it just isn't realistic to expect that there will *ever* be a production quality precise GC for all of D. Maybe giving up on some things and finishing/fixing others would be a better strategy? I think so, which is why I think DasBetterC is the most appealing thing I've seen in D lately.
Re: Way to override/overload D’s runtime assertions to use custom handlers?
On Wednesday, 25 July 2018 at 15:24:50 UTC, Alexander Nicholi wrote: Is there a way to change this to use our own handlers with the D runtime? You can provide your own implementations of the runtime hooks at https://github.com/dlang/druntime/blob/cb5efa9854775c5a72acd6870083b16e5ebba369/src/core/exception.d#L628 extern(C) void _d_assertp(immutable(char)* file, uint line) { import core.stdc.stdio; printf("Houston, we have a problem at %s:%u\n", file, line); } void main() { assert(false); } Try it out at https://run.dlang.io/is/QZEO9W How does this change without the runtime, e.g. via `-betterC` code? Unfortunately, this doesn't work with -betterC because -betterC seems to forward runtime assertions to the C implementation. See https://run.dlang.io/is/QZEO9W For that you have to provide a new implementation of `__assert`: extern(C) void __assert(const char *msg, const char *file, int line) { import core.stdc.stdio; printf("Houston, we have a problem at %s:%u\n", file, line); } extern(C) void main() { assert(false); } https://run.dlang.io/is/D5JxCT Mike
Re: Way to override/overload D’s runtime assertions to use custom handlers?
On Wednesday, 25 July 2018 at 15:24:50 UTC, Alexander Nicholi wrote: Hello, A project I’m helping develop mixes D code along with C and C++, and in the latter two languages we have custom macros that print things the way we need to, along with app-specific cleanup tasks before halting the program. Because it uses multiple languages, two of which have spotty or nonexistent exception support, and because we only depend on the D runtime sans libphobos, we have opted to avoid the use of exceptions in our codebase. Assertions still give us the ability to do contract programming to some extent, while C++ and D provide static assertions at compile-time to supplement. With runtime assertions, C and C++ handle things amicably, but D’s `assert` builtin seems to fall back to C99’s assert.h handlers and there doesn’t seem to be a way around this. Is there a way to change this to use our own handlers with the D runtime? How does this change without the runtime, e.g. via `-betterC` code? If not, is this something that can be implemented in the language as a feature request? Our use case is a bit odd but still a possibility when using D as a systems-level language like this. Thanks, Alex As far as I know, D's "assert" falls back to __assert. I have a pet/educational project (github.com/marler8997/maros) where I don't use the D runtime or the C runtime and my definition looks like this: extern (C) void __assert(bool cond, const(char)[] msg) { // TODO: would be nice to get a stack trace if (!cond) { version (linux) { import stdm.linux.file : stderr, write; import stdm.linux.process : exit; } else static assert(0, __FUNCTION__ ~ " not implemented on this platform"); write(stderr, "assert failed: "); write(stderr, msg); write(stderr, "\n"); exit(1); } } I just put this in my "object.d".
Way to override/overload D’s runtime assertions to use custom handlers?
Hello, A project I’m helping develop mixes D code along with C and C++, and in the latter two languages we have custom macros that print things the way we need to, along with app-specific cleanup tasks before halting the program. Because it uses multiple languages, two of which have spotty or nonexistent exception support, and because we only depend on the D runtime sans libphobos, we have opted to avoid the use of exceptions in our codebase. Assertions still give us the ability to do contract programming to some extent, while C++ and D provide static assertions at compile-time to supplement. With runtime assertions, C and C++ handle things amicably, but D’s `assert` builtin seems to fall back to C99’s assert.h handlers and there doesn’t seem to be a way around this. Is there a way to change this to use our own handlers with the D runtime? How does this change without the runtime, e.g. via `-betterC` code? If not, is this something that can be implemented in the language as a feature request? Our use case is a bit odd but still a possibility when using D as a systems-level language like this. Thanks, Alex
Re: C's Biggest Mistake on Hacker News
On Wednesday, 25 July 2018 at 08:23:40 UTC, Paulo Pinto wrote: On Tuesday, 24 July 2018 at 09:54:37 UTC, Ecstatic Coder wrote: On Tuesday, 24 July 2018 at 00:41:54 UTC, RhyS wrote: [...] +1 IMO, D in its current state, and with its current ecosystem, even after more than a decade of existence, is still NOT the best alternative to C/C++ where they HAVE to be used (microcontrollers, game engines, etc), despite D has always had this objective in mind. And despite C++ is an unsafe language which makes it easy to have memory leaks, dangling pointers, etc. [...] I might add that the C# 7.x improvements for low level memory management, and the effort that Unity is doing with their C# subset (HPC# with Burst compiler toolchain) to migrate core subsystems from C++ to C#, it gets even harder for adoption in the games industry. https://unity3d.com/unity/features/job-system-ECS Mike Acton and Andreas Fredriksson left Insomianc Games to help drive this effort. Mike opinions regarding performance and C vs C++ are very well known across the gaming industry, and here he is improving C# performance at Unity. -- Paulo Yop :) Orthodox C++ and data-oriented designs are now the basis of most new game engines since several years. I'm glad that the Unity management has finally decided to switch its engin to a more modern archicture, so we can now develop our games as everybody else in the industry...
Re: Kaspersky Endpoint Security 10 flags the DMD installer as malicious!
On Wednesday, 25 July 2018 at 14:30:57 UTC, FeepingCreature wrote: On Wednesday, 25 July 2018 at 09:13:27 UTC, Mike Franklin wrote: On Wednesday, 25 July 2018 at 08:27:25 UTC, Rel wrote: Possibly because anything that says "pay money or we'll flag your binary and scare our users about it!" sounds like a scam. Also, nowadays virus scanners arguably cause more problems than they prevent - viruses have already exploited vulns in virus scanners, which usually run as root. And if somebody breaks into Github or dlang.org and replaces the binary with a backdoored one, they won't use a backdoor that'll be detected by common scanners because why would they? To add to this, I've had issues with kaspersky tagging any 50 line program I wrote as a virus, as long as it had a do{} while() loop in main. Very annoying. At some point people need to realize that anti-viruses are not simply never going to improve computer security.
Re: Kaspersky Endpoint Security 10 flags the DMD installer as malicious!
On Wednesday, 25 July 2018 at 09:13:27 UTC, Mike Franklin wrote: On Wednesday, 25 July 2018 at 08:27:25 UTC, Rel wrote: To be exact as a "HEUR:Trojan-Downloader.Win32.Agent.gen". Few other AV software does the same: https://www.virustotal.com/#/file/0aa364c5cb90630a5757aacc0c3c05a2273f5fdb88e14e2b80d4c19ee5b16d10/detection I think, we should do something about it, at very least report for false-positive to Kaspersky or something. It's been reported at https://issues.dlang.org/show_bug.cgi?id=18786 For some reason it's not being taken seriously. It's embarrassing to say the least. Mike Possibly because anything that says "pay money or we'll flag your binary and scare our users about it!" sounds like a scam. Also, nowadays virus scanners arguably cause more problems than they prevent - viruses have already exploited vulns in virus scanners, which usually run as root. And if somebody breaks into Github or dlang.org and replaces the binary with a backdoored one, they won't use a backdoor that'll be detected by common scanners because why would they?
Re: DIP 1016--ref T accepts r-values--Community Review Round 1
On Wednesday, 25 July 2018 at 12:40:16 UTC, Paolo Invernizzi wrote: That proposal is a 'Syntactic Sugar' feature, that simply hide what normally need to be explicitly coded: proved a temp rvalue, pass it to a callable taking ref. What you call 'simplification', I call it 'obfuscation'; what you call uniformity I call trying to spread a well justified restriction... /Paolo A restriction which causes pointless redundant code for the caller who doesn't always have source code access. If my old teacher assistant taught me anything it is this: Redundant code is bad. You are literately forcing the programmer to create tmp variables that risk the possibility of being shadowed or worse, having its value change. Your manual solution suggestion have it own set of problems. You might as well argue against the foreach statement, because its "obfuscation". -Alexander
An Optional!T and the implementation of the underlying type's opUnary
Hi, I'm working on an Optional!T type that is a mixture of Scala's Option[T] (i.e. range based) and Swift's and Kotlin's T? (i.e. safe dispatching). I'm interested in hearing about mutability concerns. So I want operations on the optional to dispatch to the underlying type T if it's present. So let's take opUnary as an example, this is how it's currently implemented: auto opUnary(string op)() { return this.opUnaryImpl!op(); } auto opUnary(string op)() const { return this.opUnaryImpl!(op, const(T))(); } auto opUnary(string op)() immutable { return this.opUnaryImpl!(op, immutable(T))(); } private auto opUnaryImpl(string op, U = T)() const { import std.traits: isPointer; static if (op == "*" && isPointer!U) { import std.traits: PointerTarget; alias P = PointerTarget!U; return empty || front is null ? no!P : some(cast(P)*this._value); } else { if (empty) { return no!U; } else { return some(mixin(op ~ "cast(U)_value")); } } } (functions "some" and "no" are type constructors which return an Optional!T of whatever the argument type is - except "no" needs an explicit T argument) Why not "opUnary(string op)() inout"? The reason it's like this is because I want to transfer the constness of "this" to the value T that is stored inside. If I rewrite "opUnaryImpl()() const" as "opUnary()() inout" and remove the implementation for mutable, const, and immutable, then this works: immutable a = Optional!int(3); ++a; And the internal value is modified. Should that be allowed? The caveat is that 1) I want Optional!T to be nogc compatible. So therefore the value is stored similarly to this PR in phobos [1] (also for an Optional type) And 2) Optional!T provides an "unwrap" function that returns a T (if T is a class or interface), or a T*. So, if I allow modification by using inout on opUnary, then for the sake of consistency, I should be able to do this: immutable a = Optional!int(3); a = 4; But I can't do this because Optional.opAssign would be either inout or immutable and I can't modify this.value = newValue; And then what about: auto a = Optional(immutable int)(3); a = 3; // should this be allowed? If it is allowed then this will fail because of the nogc requirement: unittest { Optional!(immutable int) a = some!(immutable int)(5); immutable(int)* p = a.unwrap; assert(*p == 5); a = 4; assert(*a.unwrap == 4); assert(*p == 5); } Comments, suggestions, opinions? Cheers, - Ali [1] https://github.com/dlang/phobos/pull/3915
Re: DIP 1016--ref T accepts r-values--Community Review Round 1
On 26/07/2018 12:40 AM, Paolo Invernizzi wrote: Just to be clear, I'm also against all the new proposed addition for, named parameter, new struct initialisation and so on You'll go giddy once you hear about what I have planned after named parameters ;) But seriously tho, just because a pattern of code can be done purely in library, doesn't mean it can't be done entirely better with a nice simple language feature which makes it considerably easier to learn and understand. We do have to be careful, that we only try to go after features which are fairly well proven to our existing code and not for a theoretical improvement.
Re: DIP 1016--ref T accepts r-values--Community Review Round 1
On Wednesday, 25 July 2018 at 08:34:30 UTC, Manu wrote: With UFCS as a super popular feature of D, 'this' is not really much of a special guest at all. It's just as much the first argument of a function as the first argument of *any* UFCS call. Guido van Rossum has raised an objection on that a couple of decades ago... There's a tension between Walter effort in turning D as a suitable language for memory correctness, and a good candidate for writing 'bug free rock solid software fast' and the continuous addition of features like this. This isn't 'a feature' so much as lifting a restriction for the sake of a bunch of uniformity and simplification. I can't really see how you can find that disagreeable from your apparent position... That proposal is a 'Syntactic Sugar' feature, that simply hide what normally need to be explicitly coded: proved a temp rvalue, pass it to a callable taking ref. What you call 'simplification', I call it 'obfuscation'; what you call uniformity I call trying to spread a well justified restriction... Finally, sorry to use often the term 'feeling', and sorry for not being constructive: but really is a 'feeling'... I don't pretend to be right. So no problems in just ignoring that It upsets me when people present strong opinions about this who literally have no horse in the race. This is only really meaningful, and only affects you if it actually affects you... It's clearly not important to you, or you wouldn't be basing your opinion on *I kinda feel...* Jonathan's argument is similar. He's worried about something that this thread has tried and failed to determine exactly what is. Meanwhile I think we have determined that the presumed practical trouble cases are even less that I suspected up front. Experience, in programming, has value: Walter is famous for his anecdotes on that. D2 has already a lot of problematic stuff to solve, I not buy adding more (yes) features for the sake of an hypothetical 'simplification' of what it's already possibile. Just to be clear, I'm also against all the new proposed addition for, named parameter, new struct initialisation and so on No pun, really :-P /Paolo
Re: DIP 1016--ref T accepts r-values--Community Review Round 1
On Wednesday, 25 July 2018 at 08:34:30 UTC, Manu wrote: [snip] It upsets me when people present strong opinions about this who literally have no horse in the race. This is only really meaningful, and only affects you if it actually affects you... It's clearly not important to you, or you wouldn't be basing your opinion on *I kinda feel...* Jonathan's argument is similar. He's worried about something that this thread has tried and failed to determine exactly what is. I don't think that's fair. He has been quite specific about his concern and the kind of situations where there would be degraded behavior, and it clearly *is* important to him, and he certainly has a horse in the race. But I believe you are correct that those are cases where there's some unrelated bug that the ref parameter restriction just happens to catch, and that's not a good enough argument for keeping the restriction. Meanwhile I think we have determined that the presumed practical trouble cases are even less that I suspected up front. That's surprising; I didn't realize that you suspected practical trouble cases.
Re: DIP 1016--ref T accepts r-values--Community Review Round 1
On Saturday, 21 July 2018 at 01:17:40 UTC, Jonathan M Davis wrote: On Friday, July 20, 2018 18:04:26 Manu via Digitalmars-d wrote: On Fri, 20 Jul 2018 at 18:02, Manu wrote: > [...] > > I think you're describing now a bug where a function returns > an lvalue, but it was meant to return an rvalue. Sorry, wrong way around! I meant to say: I think you're describing now a bug where a function returns an rvalue, but it was meant to return an lvalue (ie, a ref). The function returning an rvalue isn't necessarily a bug. It's the fact that it was then used in conjunction with a function that accepts its argument by ref in order to mutate it. If a function accepts its argument by ref in order to mutate it, then it's a but for it to be given an rvalue regardless of whether the rvalue comes from. It's just that some cases are more obviously wrong than others (e.g. passing foo + bad might be obviously wrong, whereas passing foo.bar may be wrong but look correct). - Jonathan M Davis If the value returned by the function is not supposed to be mutable, then the fact that the function taking the ref parameter doesn't mutate it is not a bug. If it is supposed to be mutable, then there's an unrelated bug in the function that returns the value, which just happens to get caught by the current ref parameter restriction. The only other sort of bug is where you have a value that isn't supposed to be mutated and you have no intention of mutating it, and yet you pass it to a ref function parameter the express purpose of which is to mutate it, and then you don't use the result of that mutation ... but it's hard to even see that as a bug, just a pointless exercise, and it's hard to come up with a likely scenario where this would happen accidentally. The situation is similar with a property that either isn't supposed to be mutable and you don't expect to mutate it and don't use its changed value yet pass it to a ref parameter the express purpose of which is to mutate it, or the property is supposed to be mutable but isn't and the current ref parameter restriction just happens to catch that unrelated bug. I've read this exchange carefully and so far I agree with Manu's reasoning and the value of the DIP as it stands, and I'm not in favor of requiring @rvalue, as that negates much of the intent. However, I'm a D neophyte so I could well be missing something.
Re: Can't implement conformant memset/memcpy without compiler -ffreestanding support
On 25/07/2018 9:48 PM, Zheng (Vic) Luo wrote: First, IIRC, the name hacking is a technique used to bypass llvm optimizers, I'm not sure if it also applies to gdc. Moreover, I think this *is* a hack around compiler because this forces memset implementer to write all code in that function. I won't call it a hack. Because memset obviously can't go on to call memset. Realistically, the default case that uses D itself, won't need more than a single function to implement. For optimized versions you must use assembly. Where the problem won't manifest anyway. However this would be a wonderful candidate for a pragma to disable the calling to memset and friends.
Re: Can't implement conformant memset/memcpy without compiler -ffreestanding support
On Wednesday, 25 July 2018 at 09:37:56 UTC, rikki cattermole wrote: You misunderstand. It isn't optimizing anything. You requested the call to memcpy, explicitly when you said 'I want this copied ASAP'. By the looks, the spec doesn't clearly explain this properly. Well, it seems that this is not a good example to show. I didn't notice its semantics :) A naive implementation of memset also lead to "call memset": https://run.dlang.io/is/k3Hl04 Okay yup, that is an optimization. This won't optimize: extern(C) void* memset(ubyte* dest, int val, size_t count) { immutable c = cast(ubyte)val; foreach(i; 0..count) { dest[i] = c; } return dest; } And yes the name is important :) First, IIRC, the name hacking is a technique used to bypass llvm optimizers, I'm not sure if it also applies to gdc. Moreover, I think this *is* a hack around compiler because this forces memset implementer to write all code in that function.
Re: Kaspersky Endpoint Security 10 flags the DMD installer as malicious!
On Wednesday, 25 July 2018 at 08:31:05 UTC, rikki cattermole wrote: On 25/07/2018 8:27 PM, Rel wrote: To be exact as a "HEUR:Trojan-Downloader.Win32.Agent.gen". Few other AV software does the same: https://www.virustotal.com/#/file/0aa364c5cb90630a5757aacc0c3c05a2273f5fdb88e14e2b80d4c19ee5b16d10/detection I think, we should do something about it, at very least report for false-positive to Kaspersky or something. This is a pretty regular problem for Windows. Until we start signing the executables, it will never end. It is a very simple thing to do. But the foundation hasn't bothered buying a code signing certificate, even though it is cheap. Would be nice to hear why they haven't done this yet, considering that just the recurring open collective donations could cover expenses like this.
Re: Can't implement conformant memset/memcpy without compiler -ffreestanding support
On Wednesday, 25 July 2018 at 08:57:41 UTC, Zheng (Vic) Luo wrote: gcc and clang provides an option "-ffreestanding" to bypass optimizations that need libc support. Although we can hack around this issue by making our implementation complicated enough/using assembly to bypass the optimizer, it would be better to provide a standard flag like "-ffreestanding" for all compilers to disable such optimizations, so that developers won't have to hack around different compiler implementations. I ran into this with LDC and discussed it at https://forum.dlang.org/post/kchsryntrrnfaohjf...@forum.dlang.org The solution for me was to compile with `-disable-simplify-libcalls`. I never ran into this issue with GDC when I was compiling with `-nophoboslib -nostdinc -nodefaultlibs -nostdlib`. If I remember correctly, GDC would generate calls to `memset`, `memcpy`, and friends but seemed to be smart enough not to rewrite my own implementations of those functions, so as long as I implemented those functions everything worked fine. I'll have more to say in response to one of your other posts. Mike
Re: Can't implement conformant memset/memcpy without compiler -ffreestanding support
On 25/07/2018 9:32 PM, Zheng (Vic) Luo wrote: On Wednesday, 25 July 2018 at 09:16:19 UTC, rikki cattermole wrote: On 25/07/2018 8:59 PM, Zheng (Vic) Luo wrote: Minimal example in D: https://run.dlang.io/is/EYVTzb. Affects at least dmd and ldc. https://run.dlang.io/is/8tPOVX Note that switch void* to ubyte* won't matter once its extern(C)'d. My version (_memcpy_impl2) is just the regular old memcpy without optimizations. Your example is syntax sugar for a function call. A naive implementation of memset also lead to "call memset": https://run.dlang.io/is/k3Hl04 Okay yup, that is an optimization. This won't optimize: extern(C) void* memset(ubyte* dest, int val, size_t count) { immutable c = cast(ubyte)val; foreach(i; 0..count) { dest[i] = c; } return dest; } And yes the name is important :)
Re: Can't implement conformant memset/memcpy without compiler -ffreestanding support
On 25/07/2018 9:23 PM, Zheng (Vic) Luo wrote: On Wednesday, 25 July 2018 at 09:16:19 UTC, rikki cattermole wrote: On 25/07/2018 8:59 PM, Zheng (Vic) Luo wrote: Minimal example in D: https://run.dlang.io/is/EYVTzb. Affects at least dmd and ldc. https://run.dlang.io/is/8tPOVX Note that switch void* to ubyte* won't matter once its extern(C)'d. My version (_memcpy_impl2) is just the regular old memcpy without optimizations. Your example is syntax sugar for a function call. There is no guarantee that a compiler (in a future version or after enabling some optimization flags) will not optimize _memcpy_impl2 into "call memset". Maybe it just happens that the optimizer is not smart enough to optimize this, because nothing with -beeterC prohibits the compiler to do so. You misunderstand. It isn't optimizing anything. You requested the call to memcpy, explicitly when you said 'I want this copied ASAP'. By the looks, the spec doesn't clearly explain this properly.
Re: Can't implement conformant memset/memcpy without compiler -ffreestanding support
On Wednesday, 25 July 2018 at 09:16:19 UTC, rikki cattermole wrote: On 25/07/2018 8:59 PM, Zheng (Vic) Luo wrote: Minimal example in D: https://run.dlang.io/is/EYVTzb. Affects at least dmd and ldc. https://run.dlang.io/is/8tPOVX Note that switch void* to ubyte* won't matter once its extern(C)'d. My version (_memcpy_impl2) is just the regular old memcpy without optimizations. Your example is syntax sugar for a function call. A naive implementation of memset also lead to "call memset": https://run.dlang.io/is/k3Hl04
Re: Can't implement conformant memset/memcpy without compiler -ffreestanding support
On Wednesday, 25 July 2018 at 09:16:19 UTC, rikki cattermole wrote: On 25/07/2018 8:59 PM, Zheng (Vic) Luo wrote: Minimal example in D: https://run.dlang.io/is/EYVTzb. Affects at least dmd and ldc. https://run.dlang.io/is/8tPOVX Note that switch void* to ubyte* won't matter once its extern(C)'d. My version (_memcpy_impl2) is just the regular old memcpy without optimizations. Your example is syntax sugar for a function call. There is no guarantee that a compiler (in a future version or after enabling some optimization flags) will not optimize _memcpy_impl2 into "call memset". Maybe it just happens that the optimizer is not smart enough to optimize this, because nothing with -beeterC prohibits the compiler to do so.
Re: Can't implement conformant memset/memcpy without compiler -ffreestanding support
On 25/07/2018 8:59 PM, Zheng (Vic) Luo wrote: Minimal example in D: https://run.dlang.io/is/EYVTzb. Affects at least dmd and ldc. https://run.dlang.io/is/8tPOVX Note that switch void* to ubyte* won't matter once its extern(C)'d. My version (_memcpy_impl2) is just the regular old memcpy without optimizations. Your example is syntax sugar for a function call.
Re: DIP 1016--ref T accepts r-values--Community Review Round 1
On Saturday, 21 July 2018 at 08:59:39 UTC, Manu wrote: On Sat, 21 Jul 2018 at 00:15, Johannes Loher via Digitalmars-d wrote: On Saturday, 21 July 2018 at 05:59:37 UTC, Manu wrote: > [...] Let me give a concrete example of one of the situations Jonathan is describing. Consider the following code: [Snip] Do you think this example in contrived? If yes, why? [Snip] There are countless ways you can construct the same bug. ref doesn't contact this problem in a general way, so a solution to this class of problem shouldn't be ref's responsibility. [Snip] ... I don't understand how the existing rule can be so zealously defended in the face of a bunch of advantages, when all other constructions of the exact same problem are silently allowed, and literally nobody complains about them ever! +1000 Very well and elegantly argued Manu. I also notice that nobody that opposes this DIP has bothered to address the inconsistency that you raised above, i.e. the current acceptance of the same behaviour in other constructions, but somehow oppose this DIP for the exact same behaviour.
Re: Kaspersky Endpoint Security 10 flags the DMD installer as malicious!
On Wednesday, 25 July 2018 at 08:27:25 UTC, Rel wrote: To be exact as a "HEUR:Trojan-Downloader.Win32.Agent.gen". Few other AV software does the same: https://www.virustotal.com/#/file/0aa364c5cb90630a5757aacc0c3c05a2273f5fdb88e14e2b80d4c19ee5b16d10/detection I think, we should do something about it, at very least report for false-positive to Kaspersky or something. It's been reported at https://issues.dlang.org/show_bug.cgi?id=18786 For some reason it's not being taken seriously. It's embarrassing to say the least. Mike
Re: C's Biggest Mistake on Hacker News
On Monday, 23 July 2018 at 22:45:15 UTC, Walter Bright wrote: On 7/23/2018 5:39 AM, Joakim wrote: In my experience, people never learn, even from the blatantly obvious, _particularly_ when they're invested in the outdated. What inevitably happens is the new tech gets good enough to put them out of business, then they finally pick it up or retire. Until most system software is written in D/Go/Rust/Swift/Zig/etc., they will keep mouthing platitudes about how C is here to stay. I've predicted before that what will kill C is managers and customers requiring memory safety because unsafeness costs them millions. The "just hire better programmers" will never work. It ought to be obvious that "just use better tools" is far cheaper and more effective, but I think one of the problems is something that I also see in politics quite a bit: a lot of people are more interested in feeling superior or punishing people for their flaws than in avoiding bad outcomes. And there's also the magical "if only everyone would ..." thinking. If you want to get everyone to do something they aren't currently doing, you need some *causal mechanism* (and it has to be feasible, which "avoid all mistakes through discipline" is not).
Re: Can't implement conformant memset/memcpy without compiler -ffreestanding support
Minimal example in D: https://run.dlang.io/is/EYVTzb. Affects at least dmd and ldc.
Can't implement conformant memset/memcpy without compiler -ffreestanding support
Current implementation of compilers assumes libc implementation, which leads to an infinite loop if we want to implement primitives like memset with our own code because the compiler will optimize consecutive set with "memset". This suggests that we cannot write a freestanding program without supports from compiler. With "-betterC" flag, ldc also comes into this issue, which also applies to C/C++[1] and rust [2][3][4]. gcc and clang provides an option "-ffreestanding" to bypass optimizations that need libc support. Although we can hack around this issue by making our implementation complicated enough/using assembly to bypass the optimizer, it would be better to provide a standard flag like "-ffreestanding" for all compilers to disable such optimizations, so that developers won't have to hack around different compiler implementations. [1] https://godbolt.org/g/5gVWeN [2] https://play.rust-lang.org/?gist=64f2acafa8cec112893633a5f2e12a9a&version=stable&mode=release&edition=2015 [3] https://github.com/rust-lang/rust/issues/10116 [4] https://github.com/thestinger/rust-core#freestanding
Re: DIP 1016--ref T accepts r-values--Community Review Round 1
On Wed., 25 Jul. 2018, 12:30 am Paolo Invernizzi via Digitalmars-d, < digitalmars-d@puremagic.com> wrote: > On Wednesday, 25 July 2018 at 02:21:18 UTC, Marco Leise wrote: > > Am Sat, 21 Jul 2018 19:22:05 + > > schrieb 12345swordy : > > > >> On Saturday, 21 July 2018 at 08:55:59 UTC, Paolo Invernizzi > >> wrote: > >> > >> > Frankly speaking, my feeling is that D is becoming a > >> > horrible mess for the programmer... > >> > >> > /Paolo > >> How!? Please Explain. You need to demonstrate evidence instead > >> of appeal to emotional fallacy by resorting to "feels". > >> > >> -Alexander > > > > The DIP increases consistency recalling that rvalues are > > accepted: > > > > - for the implicit 'this' parameter in methods > > - in foreach loop variables declared as ref > > > > No more special rules: rvalues are implicitly promoted to > > lvalues where needed. > > That's correct, but 'this' is already a special guest in C++ > style PL, with its own special rules. The support for ref > variable in foreach loop can be removed (yup!), or made > stricter.. no more inconsistency. > With UFCS as a super popular feature of D, 'this' is not really much of a special guest at all. It's just as much the first argument of a function as the first argument of *any* UFCS call. > It is kind of ironic that in order to do better than C++ you > > have to support most of what modern C++ compilers offer and end > > up having tons of unrelated features that make the language > > just as bloated as C++ after a decade of community feedback. > > It is a system PL. I think it needs to be this way and is a > > lot cleaner with basic data types and more expressive still, > > lacking a lot of C++'s legacy. > > There's a tension between Walter effort in turning D as a > suitable language for memory correctness, and a good candidate > for writing 'bug free rock solid software fast' and the > continuous addition of features like this. > This isn't 'a feature' so much as lifting a restriction for the sake of a bunch of uniformity and simplification. I can't really see how you can find that disagreeable from your apparent position... Joke aside, I'm still on Jonathan side on this. > > Finally, sorry to use often the term 'feeling', and sorry for not > being constructive: but really is a 'feeling'... I don't pretend > to be right. So no problems in just ignoring that > It upsets me when people present strong opinions about this who literally have no horse in the race. This is only really meaningful, and only affects you if it actually affects you... It's clearly not important to you, or you wouldn't be basing your opinion on *I kinda feel...* Jonathan's argument is similar. He's worried about something that this thread has tried and failed to determine exactly what is. Meanwhile I think we have determined that the presumed practical trouble cases are even less that I suspected up front.
Re: Kaspersky Endpoint Security 10 flags the DMD installer as malicious!
On 25/07/2018 8:27 PM, Rel wrote: To be exact as a "HEUR:Trojan-Downloader.Win32.Agent.gen". Few other AV software does the same: https://www.virustotal.com/#/file/0aa364c5cb90630a5757aacc0c3c05a2273f5fdb88e14e2b80d4c19ee5b16d10/detection I think, we should do something about it, at very least report for false-positive to Kaspersky or something. This is a pretty regular problem for Windows. Until we start signing the executables, it will never end.
Kaspersky Endpoint Security 10 flags the DMD installer as malicious!
To be exact as a "HEUR:Trojan-Downloader.Win32.Agent.gen". Few other AV software does the same: https://www.virustotal.com/#/file/0aa364c5cb90630a5757aacc0c3c05a2273f5fdb88e14e2b80d4c19ee5b16d10/detection I think, we should do something about it, at very least report for false-positive to Kaspersky or something.
Re: C's Biggest Mistake on Hacker News
On Tuesday, 24 July 2018 at 09:54:37 UTC, Ecstatic Coder wrote: On Tuesday, 24 July 2018 at 00:41:54 UTC, RhyS wrote: [...] +1 IMO, D in its current state, and with its current ecosystem, even after more than a decade of existence, is still NOT the best alternative to C/C++ where they HAVE to be used (microcontrollers, game engines, etc), despite D has always had this objective in mind. And despite C++ is an unsafe language which makes it easy to have memory leaks, dangling pointers, etc. [...] I might add that the C# 7.x improvements for low level memory management, and the effort that Unity is doing with their C# subset (HPC# with Burst compiler toolchain) to migrate core subsystems from C++ to C#, it gets even harder for adoption in the games industry. https://unity3d.com/unity/features/job-system-ECS Mike Acton and Andreas Fredriksson left Insomianc Games to help drive this effort. Mike opinions regarding performance and C vs C++ are very well known across the gaming industry, and here he is improving C# performance at Unity. -- Paulo
Re: Constructing a class in-place
On 25/07/2018 8:05 PM, Shachar Shemesh wrote: Forget the "why" for the moment. T construct(T, ARGS...)(ARGS args) if( is(T==class) ) { auto buffer = new ubyte[__traits(classInstanceSize, T)]; T cls = cast(T)buffer.ptr; Allocates the storage space of the fields (both public and private). // Is this really the best way to do this? buffer[] = cast(ubyte[])typeid(T).initializer()[]; Copies the default initialized state, basically does .init for a struct but was not too long ago renamed because it conflicted. cls.__ctor(args); Calls a constructor that matches the given arguments. return cls; } My question is this: Is this the correct way to do it? There are steps here that seem kinda arbitrary, to say the least. Yes and not arbitrary, read above :) I am looking for something akin to C++'s placement new. Thank you, Shachar Standard solution[0]. [0] https://dlang.org/phobos/std_conv.html#.emplace.4
Constructing a class in-place
Forget the "why" for the moment. T construct(T, ARGS...)(ARGS args) if( is(T==class) ) { auto buffer = new ubyte[__traits(classInstanceSize, T)]; T cls = cast(T)buffer.ptr; // Is this really the best way to do this? buffer[] = cast(ubyte[])typeid(T).initializer()[]; cls.__ctor(args); return cls; } My question is this: Is this the correct way to do it? There are steps here that seem kinda arbitrary, to say the least. I am looking for something akin to C++'s placement new. Thank you, Shachar
Re: DIP 1016--ref T accepts r-values--Community Review Round 1
On Wednesday, 25 July 2018 at 02:21:18 UTC, Marco Leise wrote: Am Sat, 21 Jul 2018 19:22:05 + schrieb 12345swordy : On Saturday, 21 July 2018 at 08:55:59 UTC, Paolo Invernizzi wrote: > Frankly speaking, my feeling is that D is becoming a > horrible mess for the programmer... > /Paolo How!? Please Explain. You need to demonstrate evidence instead of appeal to emotional fallacy by resorting to "feels". -Alexander The DIP increases consistency recalling that rvalues are accepted: - for the implicit 'this' parameter in methods - in foreach loop variables declared as ref No more special rules: rvalues are implicitly promoted to lvalues where needed. That's correct, but 'this' is already a special guest in C++ style PL, with its own special rules. The support for ref variable in foreach loop can be removed (yup!), or made stricter.. no more inconsistency. The feeling probably comes from the inevitable realization that the community is pluralistic and Dlang acquired a lot of features that go towards someone else's vision for a good PL. Some want a relaxed stance towards breaking change, some want C++ or ObjC compatibility, some want to know what assembly a piece of code compiles to or have soft realtime constraints that don't work with a system language's mark&sweep GC. Is D2 messier than D1? Sure it is, and it caters to more use cases, too. As soon as you substantiate what exact feature is adding to the horrible mess, someone (often a group) will jump to defend it, because they have a good use case or two. Yep, and I'm conscious to be often a pessimistic, lurking guy here in the forum... :-/ It is kind of ironic that in order to do better than C++ you have to support most of what modern C++ compilers offer and end up having tons of unrelated features that make the language just as bloated as C++ after a decade of community feedback. It is a system PL. I think it needs to be this way and is a lot cleaner with basic data types and more expressive still, lacking a lot of C++'s legacy. There's a tension between Walter effort in turning D as a suitable language for memory correctness, and a good candidate for writing 'bug free rock solid software fast' and the continuous addition of features like this. Joke aside, I'm still on Jonathan side on this. Finally, sorry to use often the term 'feeling', and sorry for not being constructive: but really is a 'feeling'... I don't pretend to be right. So no problems in just ignoring that :-P Cheers, Paolo