Re: Virtual methods on stack objects
On Wednesday, 11 May 2022 at 20:53:21 UTC, Marvin Hannott wrote: On Wednesday, 11 May 2022 at 20:23:07 UTC, Ali Çehreli wrote: On 5/11/22 13:06, Marvin Hannott wrote: > I appreciate the answer, don't much like the "solutions". Me neither. :) > It's not so much about copying Great! > scoped class objects should have value semantics. std.typecons.scoped does exactly that: https://dlang.org/phobos/std_typecons.html#scoped import std.stdio; import std.typecons; interface Animal { string sing(); } class Cat : Animal { this() { writeln("Hi!"); } ~this() { writeln("Bye!"); } string sing() { return "mew"; } } void foo(Animal animal) { writeln(animal.sing()); } void bar() { auto cat = scoped!Cat(); foo(cat); } void main() { bar(); } The output: Hi! mew Bye! Ali Yeah, but you can't return `Cat` . And the documentation for `scoped` says: It's illegal to move a class instance even if you are sure there are no pointers to it. As such, it is illegal to move a scoped object. That's kinda very limiting. Anyway, I cooked up another idea based on your first suggestions. ```D struct S { static private interface I { int f(int i); } static private final class A : I { int f(int i) {return i;} } static private final class B : I { int f(int i) {return i+ 1;} } private I i; private int d; this(int d) { this.d = d; if(d < 10) { i = scoped!A(); }else { i = scoped!B(); } } int f() { return i.f(d);} } ``` I mean, this is a super dumb example, but it kinda works. And I think it could be made a lot less tedious with some mixin magic. `scoped` is not necesary, try this: ```d import std.typecons; struct S{ static private interface I{ int f(int i)const; } static private final class A : I{ static immutable typeof(this) instance = new immutable typeof(this)(); int f(int i)const {return i;} } static private final class B : I{ static immutable typeof(this) instance = new immutable typeof(this)(); int f(int i)const {return i+ 1;} } private immutable I i; private int d; this(int d){ this.d = d; if(d < 10) i = A.instance; else i = B.instance; } int f() { return i.f(d);} } void main(){ import std.stdio; S(1).f().writeln(); /// 1 S(100).f().writeln(); /// 101 } ```
Re: Virtual methods on stack objects
On Wednesday, 11 May 2022 at 20:53:21 UTC, Marvin Hannott wrote: On Wednesday, 11 May 2022 at 20:23:07 UTC, Ali Çehreli wrote: [...] Yeah, but you can't return `Cat` . And the documentation for `scoped` says: [...] That's kinda very limiting. Anyway, I cooked up another idea based on your first suggestions. ```D struct S { static private interface I { int f(int i); } static private final class A : I { int f(int i) {return i;} } static private final class B : I { int f(int i) {return i+ 1;} } private I i; private int d; this(int d) { this.d = d; if(d < 10) { i = scoped!A(); }else { i = scoped!B(); } } int f() { return i.f(d);} } ``` I mean, this is a super dumb example, but it kinda works. And I think it could be made a lot less tedious with some mixin magic. add a single `writeln("A.f")` to A.f and `writeln("B.f")` B.f, and a simple test ```d void main() { S s1 = S(9); S s2 = S(12); s1.f(); s2.f(); } ``` outputs: ``` A.f Error: program killed by signal 11 (Aka. segmentation fault !) ```
Re: Virtual methods on stack objects
On Wednesday, 11 May 2022 at 20:23:07 UTC, Ali Çehreli wrote: On 5/11/22 13:06, Marvin Hannott wrote: > I appreciate the answer, don't much like the "solutions". Me neither. :) > It's not so much about copying Great! > scoped class objects should have value semantics. std.typecons.scoped does exactly that: https://dlang.org/phobos/std_typecons.html#scoped import std.stdio; import std.typecons; interface Animal { string sing(); } class Cat : Animal { this() { writeln("Hi!"); } ~this() { writeln("Bye!"); } string sing() { return "mew"; } } void foo(Animal animal) { writeln(animal.sing()); } void bar() { auto cat = scoped!Cat(); foo(cat); } void main() { bar(); } The output: Hi! mew Bye! Ali Yeah, but you can't return `Cat` . And the documentation for `scoped` says: It's illegal to move a class instance even if you are sure there are no pointers to it. As such, it is illegal to move a scoped object. That's kinda very limiting. Anyway, I cooked up another idea based on your first suggestions. ```D struct S { static private interface I { int f(int i); } static private final class A : I { int f(int i) {return i;} } static private final class B : I { int f(int i) {return i+ 1;} } private I i; private int d; this(int d) { this.d = d; if(d < 10) { i = scoped!A(); }else { i = scoped!B(); } } int f() { return i.f(d);} } ``` I mean, this is a super dumb example, but it kinda works. And I think it could be made a lot less tedious with some mixin magic.
Re: Virtual methods on stack objects
On 5/11/22 13:06, Marvin Hannott wrote: > I appreciate the answer, don't much like the "solutions". Me neither. :) > It's not so much about copying Great! > scoped class objects should have value semantics. std.typecons.scoped does exactly that: https://dlang.org/phobos/std_typecons.html#scoped import std.stdio; import std.typecons; interface Animal { string sing(); } class Cat : Animal { this() { writeln("Hi!"); } ~this() { writeln("Bye!"); } string sing() { return "mew"; } } void foo(Animal animal) { writeln(animal.sing()); } void bar() { auto cat = scoped!Cat(); foo(cat); } void main() { bar(); } The output: Hi! mew Bye! Ali
Re: Virtual methods on stack objects
On Wednesday, 11 May 2022 at 14:44:59 UTC, Ali Çehreli wrote: On 5/11/22 06:57, Marvin Hannott wrote: > I understand that D's classes solve some particular problems. However, > they also cause problems because they cannot be copied when scoped. So > how do I get virtual methods on a copyable stack object? Problems classes solve don't usually need copying nor need to be on the stack. Is that really necessary? If so, I can think of two solutions: a) Use a struct but provide "virtual" functions manually (with function pointers like one would do in C, all of which potentially collected in a per-type function table (a.k.a. vtbl :) )). b) Use classes but provide a virtual function that you call to copy. Ali I appreciate the answer, don't much like the "solutions". It's not so much about copying, but about heap allocations. Tying virtual methods to heap allocation is kind of unfortunate. And I am not really keen on building a poor man's vtbl. And for my taste, scoped class objects should have value semantics.
Re: Virtual methods on stack objects
On 5/11/22 06:57, Marvin Hannott wrote: > I understand that D's classes solve some particular problems. However, > they also cause problems because they cannot be copied when scoped. So > how do I get virtual methods on a copyable stack object? Problems classes solve don't usually need copying nor need to be on the stack. Is that really necessary? If so, I can think of two solutions: a) Use a struct but provide "virtual" functions manually (with function pointers like one would do in C, all of which potentially collected in a per-type function table (a.k.a. vtbl :) )). b) Use classes but provide a virtual function that you call to copy. Ali
Virtual methods on stack objects
Hi everybody! I understand that D's classes solve some particular problems. However, they also cause problems because they cannot be copied when scoped. So how do I get virtual methods on a copyable stack object?