Re: Why is "delete" unsafe?
On Wednesday, 23 September 2020 at 04:15:51 UTC, mw wrote: It's there because there _are_ times when it makes sense and is useful, but it's definitely not safe, so you have to be careful and know what you're doing. What do you mean by saying "it's definitely not safe" here? I mean: if I'm careful and know what I'm doing, e.g. remove all the reference to any part of the `object` before call core.memory.GC.free(object), is there still any inherit "unsafe" side of `free` I should be aware of? FYI: I just described my use case here: https://forum.dlang.org/post/hzryuifoixwwywwif...@forum.dlang.org If there are no lingering references, the function calling free() can safely be made @trusted. -- Simen
Re: Why is "delete" unsafe?
On Saturday, 27 October 2012 at 01:08:12 UTC, Jonathan M Davis wrote: On Saturday, October 27, 2012 01:09:39 Alex Rønne Petersen wrote: On 27-10-2012 01:03, Minas wrote: > So the delete keyword has been deprecated - so good bye > manual memory management... Um, no. Use destroy() from the object module instead. Definitely, though it's important to note that what it's doing is inherently different. It destroys what you pass to it but does _not_ free the memory, which is why it's safer. To free memory from the GC, use core.memory.GC.free(). Yes. But using core.memory.GC.free is unsafe for the same reasons that delete is. It's just that it's a druntime function instead of a part of the language, so it's less likely for someone to free GC memory without knowing what they're doing. It's there because there _are_ times when it makes sense and is useful, but it's definitely not safe, so you have to be careful and know what you're doing. What do you mean by saying "it's definitely not safe" here? I mean: if I'm careful and know what I'm doing, e.g. remove all the reference to any part of the `object` before call core.memory.GC.free(object), is there still any inherit "unsafe" side of `free` I should be aware of? FYI: I just described my use case here: https://forum.dlang.org/post/hzryuifoixwwywwif...@forum.dlang.org
Re: uda pattern foo and foo(val)
On 9/22/20 11:31 PM, Steven Schveighoffer wrote: I thought it had something to do with the optional parentheses. I think it does have something to do with this. I think it works if you do attrs[0], because you really get an alias to the function symbol, and that calls it. I still think I can work with this anyway. -Steve
Re: uda pattern foo and foo(val)
On 9/22/20 10:20 PM, Adam D. Ruppe wrote: On Wednesday, 23 September 2020 at 02:07:04 UTC, Steven Schveighoffer wrote: I just said pragma(msg, __traits(getAttributes, z)) Ah, ok, this is weird, `pragma(msg, __traits(getAttributes, z)[0])` works just fine! Oh, yeah, weird! I see that now. So it will actually work, it's just my method of testing "will this work", which actually isn't how I would use it, triggers some obscure bug, lol. But that might be adequate for you - just loop over the attributes and use them one by one. Which you'd do anyway. Yep, exactly what I would be doing anyway. I suspect this is overload resolution not happening yet when you getAttributes but then it happens when it is forced evaluated with the index. (prolly one of those order-of-semantic bugs in dmd) I thought it had something to do with the optional parentheses. Thanks anyway for helping! -Steve
Re: uda pattern foo and foo(val)
On Wednesday, 23 September 2020 at 02:07:04 UTC, Steven Schveighoffer wrote: I just said pragma(msg, __traits(getAttributes, z)) Ah, ok, this is weird, `pragma(msg, __traits(getAttributes, z)[0])` works just fine! But that might be adequate for you - just loop over the attributes and use them one by one. Which you'd do anyway. I suspect this is overload resolution not happening yet when you getAttributes but then it happens when it is forced evaluated with the index. (prolly one of those order-of-semantic bugs in dmd)
Re: uda pattern foo and foo(val)
On Wednesday, 23 September 2020 at 01:57:08 UTC, Adam D. Ruppe wrote: On Wednesday, 23 September 2020 at 01:45:46 UTC, Steven Schveighoffer wrote: @foo int z; // Error: cannot interpret foo(T)(T val) at compile time Where do you get that error? Is it from phobos' thing? cuz I copy/pasted your code and it compiled. You can also just use a struct as the uda if your detection function checks for both the type and a value of the type, so it really depends on which search method you using. I just said pragma(msg, __traits(getAttributes, z)) Well actually the thing I tried is slightly different. As usual I dumbed it down to post here (maybe was a bad idea). A struct won’t work because the foo(val) form needs to hold any type and ifti doesn’t work on constructors. -Steve
Re: uda pattern foo and foo(val)
On Wednesday, 23 September 2020 at 01:45:46 UTC, Steven Schveighoffer wrote: @foo int z; // Error: cannot interpret foo(T)(T val) at compile time Where do you get that error? Is it from phobos' thing? cuz I copy/pasted your code and it compiled. You can also just use a struct as the uda if your detection function checks for both the type and a value of the type, so it really depends on which search method you using.
uda pattern foo and foo(val)
I want to set up a way to use the following patterns: @foo @foo(val) Is there a way I can define foo such that this works? I tried this: struct Foo(T) { T val; } auto foo(T)(T val) { return Foo!T(val); } @property foo() { return Foo!int(0); } So this works: @foo() int x; @foo(1) int y; But this doesn't: @foo int z; // Error: cannot interpret foo(T)(T val) at compile time Is there a way I can do this while keeping the name the same for both options? If I have different names, I can get it to work also. -Steve
Re: Escape this in pure members
On Tuesday, 22 September 2020 at 18:21:10 UTC, Jacob Carlborg wrote: On 2020-09-19 21:50, Per Nordlöw wrote: On Saturday, 19 September 2020 at 18:48:31 UTC, Jacob Carlborg wrote: A nested class seems to be able to escape the `this` reference: Ahh, thanks. I just realized that it can escape into other parameters without the `scope` qualifier? This class Bar { void bar(scope Bar b) @safe pure { b = this; } } compiles but this class Bar { scope void bar(scope Bar b) @safe pure { b = this; // Error: scope variable `this` assigned to `b` with longer lifetime } } Hmm, why would `b` have longer lifetime? Isn't the lifetime of `b` throughout `bar`? The following analysis might be wrong but I think that `scope` as a **member** function attribute is not supposed to be used as that is not even documented. So it would works "by default". The compiler thinks that `this` is a scope variable that will stop living after `bar()`. Also as `b` is not `ref` this is clearly a wrong diagnostic. There's a special case missing in the compiler.
Re: Array of Algebraic argument syntax
On 9/22/20 2:53 PM, Kasra Sadeghi wrote: On Tuesday, 22 September 2020 at 21:36:48 UTC, Ali Çehreli wrote: ... alias Value = Algebraic!(int, double, string, None); ... void main() { printValue([Value(4.5), Value("hello"), Value(42)]); } Thanks! Wish there was a less redundant syntax for the arrays. Do you really need to write literal Value arrays? If not, you would build a Value[] at runtime without seeing the syntax above. Still, here is a function template that provides better syntax: Value[] valueArray(Args...)(Args args) { Value[] result; foreach (arg; args) { result ~= Value(arg); } return result; } void main() { printValue(valueArray(4.5, "hello", 42)); } Ali
Re: Timeout around function call
On Tuesday, 22 September 2020 at 09:32:13 UTC, drathier wrote: What's the obvious way to put a timeout around a function call? I'm thinking a 5 or 30 second timeout, and I'm expecting it to pretty much never time out. You have several options. Either you use the actor model (spawn[Linked]) and send a termination message after a specified time. Or you use a task and check for yourTask.done(). Or you could create a Thread and check isRunning. (You didn't specify what you wanted to happen and if blocking was allowed or not)
Re: Timeout around function call
On 9/22/20 2:32 AM, drathier wrote:> What's the obvious way to put a timeout around a function call? I'm > thinking a 5 or 30 second timeout, and I'm expecting it to pretty much > never time out. I would start a thread and use receiveTimeout(): import std.concurrency; import std.stdio; import std.exception; import core.thread; // Uncomment to see what happens upon time out. // version = doTimeout; void compute(int i) { version (doTimeout) { writeln("The thread is napping."); Thread.sleep(2.seconds); } ownerTid.send(i + 1); } void main() { auto worker = spawn(&compute, 42); const received = receiveTimeout( 1.seconds, (int result) { writefln!"Received the result: %s"(result); } ); enforce(received, "Timed out."); } The thread need not be one-shot: It can continue waiting for more messages until told to stop: import std.concurrency; import std.stdio; import std.exception; import core.thread; // Uncomment to see what happens upon time out. // version = doTimeout; struct Done { } void computer() { bool done = false; while (!done) { receive( (Done _) { done = true; }, (int i) { version (doTimeout) { writeln("The thread is napping."); Thread.sleep(2.seconds); } ownerTid.send(i + 1); } ); } } void main() { // This time we use spawnLinked() so that we will receive // a LinkTerminated message. And the name is different and // the argument will be passed later with send(). auto worker = spawnLinked(&computer); foreach (i; 0 .. 10) { worker.send(i); const received = receiveTimeout( 1.seconds, (int result) { writefln!"Received the result: %s"(result); } ); enforce(received, "Timed out."); } // Tell worker to stop. worker.send(Done()); // Wait for worker to terminate. receiveOnly!LinkTerminated(); } Ali
Re: Array of Algebraic argument syntax
On Tuesday, 22 September 2020 at 21:36:48 UTC, Ali Çehreli wrote: ... alias Value = Algebraic!(int, double, string, None); ... void main() { printValue([Value(4.5), Value("hello"), Value(42)]); } Thanks! Wish there was a less redundant syntax for the arrays.
Re: Array of Algebraic argument syntax
On 9/22/20 2:30 PM, Kasra Sadeghi wrote: Hi everyone! What's the syntax for passing an array of Algebraics? definition: class None {} class Value = Algebraic!(int, double, string, None); That should be 'alias' instead of 'class': import std.variant; import std.stdio; class None {} alias Value = Algebraic!(int, double, string, None); void printValue(Value[] values) { foreach(value; values) { value.writeln; } } void main() { printValue([Value(4.5), Value("hello"), Value(42)]); } Ali
Array of Algebraic argument syntax
Hi everyone! What's the syntax for passing an array of Algebraics? definition: class None {} class Value = Algebraic!(int, double, string, None); void printValue(Value[] values) { foreach(value; values) { value.writeln; } } usage attempts: printValue([4.5]); printValue(Value[4.5]); printValue(Value[](4.5));
Re: Why private methods cant be virtual?
On Tuesday, 22 September 2020 at 13:19:10 UTC, Daniel Kozak wrote: On Tue, Sep 22, 2020 at 3:05 PM claptrap via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote: The thread title is... "Why private methods cant be virtual?" IE Not... "how do I override private functions in a non-polymorphic manner." And what you suggest wont work because I was asking about virtual functions, so I specifically want polymorphism. And FWIW it's no big deal I can just use protected, i wasn't looking for a solution, I was looking for an explanation as to why it was done that way. But apparently there is none. And I did not try to show solution. It was just an answer to this part of your response: So final private functions can be overriden? It seems not, but the sentence is definitely confusing if not just plain wrong. So the reason why there is this: "Functions marked as final may not be overridden in a derived class, unless they are also private" Is because with private methods final keyword has no meaning. Its not that final has no meaning for private methods, but that final has no meaning for non-virtual methods, and private methods happen to be non-virtual. IE. It's a side effect of making private methods non-virtual, not a direct effect of them being private. And lets be honest, overriding a virtual method is a different thing to "overriding" or rather hiding a non virtual one. It's mistake to use the same terminology for both cases. And there is a reason "Why private methods cant be virtual?". It is because it would break existing code. Why would it break existing code? And because private methods are final it makes them fast. And yes compiler probably could findout that method could be made non-virtual but I am not sure how easy is this and how it would slow down compilation times Testing it out on compiler explorer it seems neither LDC or DMD de-virtualize a simple case, a class with one method, no decedent class, So maybe the docs shouldn't say that it does so.
Re: Escape this in pure members
On 2020-09-19 21:50, Per Nordlöw wrote: On Saturday, 19 September 2020 at 18:48:31 UTC, Jacob Carlborg wrote: A nested class seems to be able to escape the `this` reference: Ahh, thanks. I just realized that it can escape into other parameters without the `scope` qualifier? This class Bar { void bar(scope Bar b) @safe pure { b = this; } } compiles but this class Bar { scope void bar(scope Bar b) @safe pure { b = this; // Error: scope variable `this` assigned to `b` with longer lifetime } } Hmm, why would `b` have longer lifetime? Isn't the lifetime of `b` throughout `bar`? -- /Jacob Carlborg
Re: Why private methods cant be virtual?
On Tuesday, 22 September 2020 at 14:19:09 UTC, Steven Schveighoffer wrote: On 9/22/20 10:11 AM, Arafel wrote: This is a very good guess. Specifically, I think classes (and the mechanisms for inner classes and anonymous classes) were added to D1 to allow porting of JWT to D. Classes existed long before then. But yeah, the inner classes and anonymous classes were added for DWT, IIRC.
Re: Why private methods cant be virtual?
On 9/22/20 10:11 AM, Arafel wrote: My guess is that this was taken from Java, as in fact most of the D class system seems to be (see `synchronized`, reference semantics, etc). There it makes sense, because there is only one class per compilation unit, so the `private` members are in effect hidden from any child classes and it wouldn't make sense to override them. This is a very good guess. Specifically, I think classes (and the mechanisms for inner classes and anonymous classes) were added to D1 to allow porting of JWT to D. -Steve
Re: Why private methods cant be virtual?
On 22/9/20 15:04, claptrap wrote: The thread title is... "Why private methods cant be virtual?" IE Not... "how do I override private functions in a non-polymorphic manner." And what you suggest wont work because I was asking about virtual functions, so I specifically want polymorphism. And FWIW it's no big deal I can just use protected, i wasn't looking for a solution, I was looking for an explanation as to why it was done that way. But apparently there is none. TL;DR: Wouldn't `package` [1] visibility probably be a better option in any case? Long Answer: My guess is that this was taken from Java, as in fact most of the D class system seems to be (see `synchronized`, reference semantics, etc). There it makes sense, because there is only one class per compilation unit, so the `private` members are in effect hidden from any child classes and it wouldn't make sense to override them. The different (and to me still confusing, but I understand the reasoning behind it) factor in D is that the encapsulation unit is the module, not the class. Hence, you can have multiple classes in the same module inheriting from each other. These classes can then access the private members of the parent, but not override it, which as you say is somewhat strange. I personally would rather have the class as the encapsulation unit for classes, and then this point would be moot, but I come mostly from Java, so that might just be my bias, and, as I said, I understand there are also good reasons to keeps the module as the common encapsulation unit. Still, I think that when you design a class, if you declare something as `private` means that it's an internal implementation detail that you don't want to expose, much less any child class to override. In fact, to allow only the classes in the same module to override a private method looks to me like code smell. You likely have good reasons to do it, but, even if it were possible, I would probably try to do it in a way where the intent is clearer, either through `protected` or `package` visibility... the latter has the added benefit that you can split the module later if needed. A. [1]: https://dlang.org/spec/attribute.html#visibility_attributes
Re: Why private methods cant be virtual?
On Tuesday, 22 September 2020 at 13:19:10 UTC, Daniel Kozak wrote: So final private functions can be overriden? It seems not, but the sentence is definitely confusing if not just plain wrong. Yeah. I've seen this called hiding, shadowing and overwriting earlier, but never overriding - that's always been reserved for the polymorphic kind. I'd argue the documentation should use one of those other terms. And yes compiler probably could findout that method could be made non-virtual but I am not sure how easy is this and how it would slow down compilation times Steve showed a few posts up one example that would make it basically impossible. Other language features make it even worse: class A { private void fun() {} } class B(string s) : A { mixin(s); } -- Simen
Re: Why private methods cant be virtual?
On Tue, Sep 22, 2020 at 3:05 PM claptrap via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote: > > The thread title is... > > "Why private methods cant be virtual?" > > IE Not... > > "how do I override private functions in a non-polymorphic manner." > > And what you suggest wont work because I was asking about virtual > functions, so I specifically want polymorphism. And FWIW it's no > big deal I can just use protected, i wasn't looking for a > solution, I was looking for an explanation as to why it was done > that way. But apparently there is none. > > And I did not try to show solution. It was just an answer to this part of your response: So final private functions can be overriden? It seems not, but the sentence is definitely confusing if not just plain wrong. So the reason why there is this: "Functions marked as final may not be overridden in a derived class, unless they are also private" Is because with private methods final keyword has no meaning. And there is a reason "Why private methods cant be virtual?". It is because it would break existing code. And because private methods are final it makes them fast. And yes compiler probably could findout that method could be made non-virtual but I am not sure how easy is this and how it would slow down compilation times
Re: Why private methods cant be virtual?
On Tuesday, 22 September 2020 at 10:23:08 UTC, Daniel Kozak wrote: On Tue, Sep 22, 2020 at 11:06 AM claptrap via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote: "Functions marked as final may not be overridden in a derived class, unless they are also private" So final private functions can be overriden? It seems not, but the sentence is definitely confusing if not just plain wrong. Yes they can, if you have class A in one module and class B in another module this will work: //a.d class A { private final void overrideFun() { import std.stdio : writeln; writeln("A::overrideFun"); } } //b.d import a; class B : A { void overrideFun() { import std.stdio : writeln; writeln("B::overrideFun"); } } // main.d import b; void main(string[] args) { B b = new B; b.overrideFun; } The thread title is... "Why private methods cant be virtual?" IE Not... "how do I override private functions in a non-polymorphic manner." And what you suggest wont work because I was asking about virtual functions, so I specifically want polymorphism. And FWIW it's no big deal I can just use protected, i wasn't looking for a solution, I was looking for an explanation as to why it was done that way. But apparently there is none.
Re: Why private methods cant be virtual?
On 9/22/20 5:00 AM, claptrap wrote: IE the compiler is supposed to make methods non-virtual automatically, it should be easy to do for private as all the relevant info be in the one compilation unit. class A { private void foo() {} } class B(T) : A { static if(T.stringof == "BlahBlahBlah") private override foo() {} } -Steve
Re: Why private methods cant be virtual?
On Tue, Sep 22, 2020 at 1:30 PM ShadoLight via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote: > > > This is not really "overriding", it is more akin to "overloading" > No it is not overloading, overloading is when you have more methods with same name and differents params. It is overriding > It is also not polymorphic > I did not say otherwise :-)
Re: Why private methods cant be virtual?
On Tuesday, 22 September 2020 at 10:23:08 UTC, Daniel Kozak wrote: On Tue, Sep 22, 2020 at 11:06 AM claptrap via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote: "Functions marked as final may not be overridden in a derived class, unless they are also private" So final private functions can be overriden? It seems not, but the sentence is definitely confusing if not just plain wrong. Yes they can, if you have class A in one module and class B in another module this will work: //a.d class A { private final void overrideFun() { import std.stdio : writeln; writeln("A::overrideFun"); } } //b.d import a; class B : A { void overrideFun() { import std.stdio : writeln; writeln("B::overrideFun"); } } // main.d import b; void main(string[] args) { B b = new B; b.overrideFun; } This is not really "overriding", it is more akin to "overloading". It is also not polymorphic i.e. this will call A::overrideFun. A b = new B; b.overrideFun;
Re: Why private methods cant be virtual?
On Tue, Sep 22, 2020 at 11:06 AM claptrap via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote: > > "Functions marked as final may not be overridden in a derived > class, unless they are also private" > > So final private functions can be overriden? It seems not, but > the sentence is definitely confusing if not just plain wrong. > > Yes they can, if you have class A in one module and class B in another module this will work: //a.d class A { private final void overrideFun() { import std.stdio : writeln; writeln("A::overrideFun"); } } //b.d import a; class B : A { void overrideFun() { import std.stdio : writeln; writeln("B::overrideFun"); } } // main.d import b; void main(string[] args) { B b = new B; b.overrideFun; }
Re: Why private methods cant be virtual?
On Tue, Sep 22, 2020 at 12:23 PM Daniel Kozak wrote: > ... > void main(string[] args) > { > B b = new B; > b.overrideFun; > } > You can have A and B in one module too of course
Timeout around function call
What's the obvious way to put a timeout around a function call? I'm thinking a 5 or 30 second timeout, and I'm expecting it to pretty much never time out.
Re: Why private methods cant be virtual?
On Tuesday, 22 September 2020 at 00:46:02 UTC, Steven Schveighoffer wrote: On 9/21/20 7:52 PM, H. S. Teoh wrote: On Mon, Sep 21, 2020 at 07:43:30PM -0400, Steven Schveighoffer via Digitalmars-d-learn wrote: [...] No, it's not a bug. It's intentional. private and package functions are final, and we aren't going to change that now, even if it makes sense to make them virtual. [...] Whoa. But why?? What's the reasoning behind private being non-virtual? You'd have to confirm with Walter. This is a relic from D1. I think it has something to do with the expectation of whether a private function makes sense to override. The use case is pretty narrow -- allow overriding only within the current package/module. But I can see the use case being valid. However, changing it now means a slew of code becomes virtual that is currently not virtual. This could be a problem for existing code. If we ever got a virtual keyword, then it might be possible to allow them to become virtual if you opt-in. But I don't see it happening without that. "All public and protected member functions which are non-static and are not templatized are virtual ***unless the compiler can determine that they will never be overridden***" IE the compiler is supposed to make methods non-virtual automatically, it should be easy to do for private as all the relevant info be in the one compilation unit. Then there's this gem from the docs.. "Functions marked as final may not be overridden in a derived class, unless they are also private" So final private functions can be overriden? It seems not, but the sentence is definitely confusing if not just plain wrong.