| Thread overview | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
December 23, 2007 byval keyword to make objects act as value types | ||||
|---|---|---|---|---|
| ||||
so that 'byval MyClass' is a new type that acts like MyClass in all ways (ie. is polymorphic) except that it gets dupped on non-const assignment from other byval MyClasses and normal MyClasses. possibly also on assignment to normal MyClasses. this would require that it *has* a dup method, or maybe a copy constructor
byval Base b = new Derived;
despite the name 'byval' b actually holds a reference to a copy of Derived, so slicing is avoided.
or, if that's too inefficient perhaps the linker can figure out the size of the largest class derived from Base and allocate that much on the stack/inside a containing class.
myFunction(ref Base arg)
{
++arg;
}
myFunction(b)
i'm thinking it should be overridable so that the above function *does* change the value of b
question: are calls to final class member functions non-virtual?
i notice the tango iterators are classes. surely we want to use iterators as value types... this way, we can.
alternatively, since scope objects are a bit like value types already, perhaps we can just add the functionality to that.
then, we just need to return refs from functions, and it's goodbye C++!
| ||||
December 23, 2007 Re: byval keyword to make objects act as value types | ||||
|---|---|---|---|---|
| ||||
Posted in reply to BC | BC wrote: > so that 'byval MyClass' is a new type that acts like MyClass in all ways (ie. is polymorphic) except that it gets dupped on non-const assignment from other byval MyClasses and normal MyClasses. possibly also on assignment to normal MyClasses. this would require that it *has* a dup method, or maybe a copy constructor Perhaps this would be better as a class declaration modifier? byval class Foo {} // acts like a struct Or: valueclass Foo {} It would be simpler, at least: an opAssign overload. > byval Base b = new Derived; > > despite the name 'byval' b actually holds a reference to a copy of Derived, so slicing is avoided. > or, if that's too inefficient perhaps the linker can figure out the size of the largest class derived from Base and allocate that much on the stack/inside a containing class. If we get this, I'm going to ask for virtual template methods in classes again. It's not happening. > myFunction(ref Base arg) > { > ++arg; > } > > myFunction(b) > > i'm thinking it should be overridable so that the above function *does* change the value of b Besides which, arg isn't assigned to... void func(ref ValueClass arg) { arg = new ValueClass(); } > question: are calls to final class member functions non-virtual? Well, yes. But do you mean, are they found in the vtbl? You could check: class Foo { final void a(){} final void b(){} final void c(){} } assert (Foo.classinfo.vtbl.length == Object.classinfo.vtbl.length); > i notice the tango iterators are classes. surely we want to use iterators as value types... this way, we can. > > alternatively, since scope objects are a bit like value types already, perhaps we can just add the functionality to that. Ugh. No. > then, we just need to return refs from functions, and it's goodbye C++! | |||
December 23, 2007 Re: byval keyword to make objects act as value types | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Christopher Wright | On Sun, 23 Dec 2007 04:01:30 -0000, Christopher Wright <dhasenan@gmail.com> wrote: > BC wrote: >> so that 'byval MyClass' is a new type that acts like MyClass in all ways (ie. is polymorphic) except that it gets dupped on non-const assignment from other byval MyClasses and normal MyClasses. possibly also on assignment to normal MyClasses. this would require that it *has* a dup method, or maybe a copy constructor > > Perhaps this would be better as a class declaration modifier? > > byval class Foo {} // acts like a struct > > Or: > valueclass Foo {} > > It would be simpler, at least: an opAssign overload. > true, it's just that I don't buy that classes are always either value or reference types, I think flexibility is desirable. you could still do class Foo{} alias byval Foo VFoo; >> byval Base b = new Derived; >> despite the name 'byval' b actually holds a reference to a copy of Derived, so slicing is avoided. >> or, if that's too inefficient perhaps the linker can figure out the size of the largest class derived from Base and allocate that much on the stack/inside a containing class. > > If we get this, I'm going to ask for virtual template methods in classes again. It's not happening. > no, i'm not holding my breath. it could for final classes though. >> myFunction(ref Base arg) >> { >> ++arg; >> } >> myFunction(b) >> i'm thinking it should be overridable so that the above function *does* change the value of b > > Besides which, arg isn't assigned to... > > void func(ref ValueClass arg) { > arg = new ValueClass(); > } > >> question: are calls to final class member functions non-virtual? > > Well, yes. But do you mean, are they found in the vtbl? You could check: > class Foo { > final void a(){} > final void b(){} > final void c(){} > } > > assert (Foo.classinfo.vtbl.length == Object.classinfo.vtbl.length); > i should have said 'member functions of final classes'. both are found in the vtbl. i was wondering how close to struct behaviour we can bring classes. >> i notice the tango iterators are classes. surely we want to use iterators as value types... this way, we can. >> alternatively, since scope objects are a bit like value types already, perhaps we can just add the functionality to that. > > Ugh. No. > no? currently the spec says you can't assign to them (although i see now that you can), so i thought that might be the plan. >> then, we just need to return refs from functions, and it's goodbye C++! | |||
December 23, 2007 Re: byval keyword to make objects act as value types | ||||
|---|---|---|---|---|
| ||||
Posted in reply to BC | On Sun, 23 Dec 2007 05:09:43 -0000, BC <NOTmi_emayl_adrez@hotmail.com.remove.not> wrote: > On Sun, 23 Dec 2007 04:01:30 -0000, Christopher Wright <dhasenan@gmail.com> wrote: > >> BC wrote: >>> so that 'byval MyClass' is a new type that acts like MyClass in all ways (ie. is polymorphic) except that it gets dupped on non-const assignment from other byval MyClasses and normal MyClasses. possibly also on assignment to normal MyClasses. this would require that it *has* a dup method, or maybe a copy constructor >> >> Perhaps this would be better as a class declaration modifier? >> >> byval class Foo {} // acts like a struct >> >> Or: >> valueclass Foo {} >> >> It would be simpler, at least: an opAssign overload. >> > true, it's just that I don't buy that classes are always either value or > reference types, I think flexibility is desirable. you could still do > > class Foo{} > alias byval Foo VFoo; > >>> byval Base b = new Derived; >>> despite the name 'byval' b actually holds a reference to a copy of Derived, so slicing is avoided. >>> or, if that's too inefficient perhaps the linker can figure out the size of the largest class derived from Base and allocate that much on the stack/inside a containing class. >> >> If we get this, I'm going to ask for virtual template methods in classes again. It's not happening. >> > no, i'm not holding my breath. it could for final classes though. > >>> myFunction(ref Base arg) >>> { >>> ++arg; >>> } >>> myFunction(b) >>> i'm thinking it should be overridable so that the above function *does* change the value of b >> >> Besides which, arg isn't assigned to... >> >> void func(ref ValueClass arg) { >> arg = new ValueClass(); >> } >> i didn't realise you could have a reference to a reference >>> question: are calls to final class member functions non-virtual? >> >> Well, yes. But do you mean, are they found in the vtbl? You could check: >> class Foo { >> final void a(){} >> final void b(){} >> final void c(){} >> } >> >> assert (Foo.classinfo.vtbl.length == Object.classinfo.vtbl.length); >> > i should have said 'member functions of final classes'. both are found > in the vtbl. i was wondering how close to struct behaviour we can bring > classes. > >>> i notice the tango iterators are classes. surely we want to use iterators as value types... this way, we can. >>> alternatively, since scope objects are a bit like value types already, perhaps we can just add the functionality to that. >> >> Ugh. No. >> > no? currently the spec says you can't assign to them (although i see now > that you can, if you like access violations), so i thought that might be > the plan. > don't forget that if you assign it to something else such as a scope object inside another class, you get a copy, which won't get destroyed, so they could then outlast the function scope and be just like a value type as far as i can see. >>> then, we just need to return refs from functions, and it's goodbye C++! > | |||
December 23, 2007 Re: byval keyword to make objects act as value types | ||||
|---|---|---|---|---|
| ||||
Posted in reply to BC | On Sun, 23 Dec 2007 05:40:34 -0000, BC <NOTmi_emayl_adrez@hotmail.com.remove.not> wrote: > On Sun, 23 Dec 2007 05:09:43 -0000, BC <NOTmi_emayl_adrez@hotmail.com.remove.not> wrote: > >> On Sun, 23 Dec 2007 04:01:30 -0000, Christopher Wright <dhasenan@gmail.com> wrote: >> >>> BC wrote: >>>> so that 'byval MyClass' is a new type that acts like MyClass in all ways (ie. is polymorphic) except that it gets dupped on non-const assignment from other byval MyClasses and normal MyClasses. possibly also on assignment to normal MyClasses. this would require that it *has* a dup method, or maybe a copy constructor >>> >>> Perhaps this would be better as a class declaration modifier? >>> >>> byval class Foo {} // acts like a struct >>> >>> Or: >>> valueclass Foo {} >>> >>> It would be simpler, at least: an opAssign overload. >>> >> true, it's just that I don't buy that classes are always either value or >> reference types, I think flexibility is desirable. you could still do >> >> class Foo{} >> alias byval Foo VFoo; >> >>>> byval Base b = new Derived; >>>> despite the name 'byval' b actually holds a reference to a copy of Derived, so slicing is avoided. >>>> or, if that's too inefficient perhaps the linker can figure out the size of the largest class derived from Base and allocate that much on the stack/inside a containing class. >>> >>> If we get this, I'm going to ask for virtual template methods in classes again. It's not happening. >>> >> no, i'm not holding my breath. it could for final classes though. >> >>>> myFunction(ref Base arg) >>>> { >>>> ++arg; >>>> } >>>> myFunction(b) >>>> i'm thinking it should be overridable so that the above function *does* change the value of b >>> >>> Besides which, arg isn't assigned to... >>> >>> void func(ref ValueClass arg) { >>> arg = new ValueClass(); >>> } >>> > i didn't realise you could have a reference to a reference > >>>> question: are calls to final class member functions non-virtual? >>> >>> Well, yes. But do you mean, are they found in the vtbl? You could check: >>> class Foo { >>> final void a(){} >>> final void b(){} >>> final void c(){} >>> } >>> >>> assert (Foo.classinfo.vtbl.length == Object.classinfo.vtbl.length); >>> >> i should have said 'member functions of final classes'. both are found >> in the vtbl. i was wondering how close to struct behaviour we can bring >> classes. >> arrghh. only in the vtbl if overriding a base class function, as they have to be really. but not called virtually from references to the final class/ class in which they are final. >>>> i notice the tango iterators are classes. surely we want to use iterators as value types... this way, we can. >>>> alternatively, since scope objects are a bit like value types already, perhaps we can just add the functionality to that. >>> >>> Ugh. No. >>> >> no? currently the spec says you can't assign to them (although i see now >> that you can, if you like access violations), so i thought that might be >> the plan. >> > don't forget that if you assign it to something else such as a scope object > inside another class, you get a copy, which won't get destroyed, > so they could then outlast the function scope and be just like a value > type as far as i can see. > >>>> then, we just need to return refs from functions, and it's goodbye C++! >> > | |||
December 23, 2007 Re: byval keyword to make objects act as value types | ||||
|---|---|---|---|---|
| ||||
Posted in reply to BC | >so that 'byval MyClass' is a new type that acts like MyClass in all ways (ie. is polymorphic) except that it gets dupped on non-const assignment from other byval MyClasses and normal MyClasses. possibly also on assignment to normal MyClasses. this would require that it *has* a dup method, or maybe a copy constructor > >byval Base b = new Derived; I'm not really "getting" your proposal, but maybe I missed something. What's the novelty here? Why not just add copy semantics to structs? Then you don't need the byval keyword anymore. >i notice the tango iterators are classes. surely we want to use iterators as value types... this way, we can. I wholeheartedly agree, but why not use structs? -Craig | |||
December 23, 2007 Re: byval keyword to make objects act as value types | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Craig Black | On Sun, 23 Dec 2007 06:22:49 -0000, Craig Black <craigblack2@cox.net> wrote:
>> so that 'byval MyClass' is a new type that acts like MyClass in all ways (ie. is polymorphic) except that it gets dupped on non-const assignment from other byval MyClasses and normal MyClasses. possibly also on assignment to normal MyClasses. this would require that it *has* a dup method, or maybe a copy constructor
>>
>> byval Base b = new Derived;
>
> I'm not really "getting" your proposal, but maybe I missed something. What's the novelty here? Why not just add copy semantics to structs? Then you don't need the byval keyword anymore.
>
>> i notice the tango iterators are classes. surely we want to use iterators as value types... this way, we can.
>
> I wholeheartedly agree, but why not use structs?
>
> -Craig
well, there's inheritance. polymorphism. also there's not always a definitive
answer to whether a given data structure should be a value or reference
type. this way, they can be both.
| |||
December 23, 2007 Re: byval keyword to make objects act as value types | ||||
|---|---|---|---|---|
| ||||
Posted in reply to BC | On Sun, 23 Dec 2007 07:52:06 -0000, BC <notmi_emayl_adreznot@hotmail.com.remove.not> wrote: > On Sun, 23 Dec 2007 06:22:49 -0000, Craig Black <craigblack2@cox.net> wrote: > >>> so that 'byval MyClass' is a new type that acts like MyClass in all ways (ie. is polymorphic) except that it gets dupped on non-const assignment from other byval MyClasses and normal MyClasses. possibly also on assignment to normal MyClasses. this would require that it *has* a dup method, or maybe a copy constructor >>> >>> byval Base b = new Derived; >> >> I'm not really "getting" your proposal, but maybe I missed something. What's the novelty here? Why not just add copy semantics to structs? Then you don't need the byval keyword anymore. >> >>> i notice the tango iterators are classes. surely we want to use iterators as value types... this way, we can. >> >> I wholeheartedly agree, but why not use structs? >> >> -Craig > > well, there's inheritance. polymorphism. also there's not always a definitive > answer to whether a given data structure should be a value or reference > type. this way, they can be both. although adding those things and ctors/dtors to structs like you said would be just as good really. i got the impression that option was off the table though. should struct member functions & dtors be virtual by default? | |||
December 23, 2007 Re: byval keyword to make objects act as value types | ||||
|---|---|---|---|---|
| ||||
Posted in reply to BC |
>although adding those things and ctors/dtors to structs like you said
>would be just as good really. i got the impression that option was off
>the table though.
>should struct member functions & dtors be virtual by default?
Good question. Here's my philosophy about virtual by default. I am a performance-oriented guy, and I prefer the compiler to NOT make functions virtual when I don't explicitly say "virtual". For me, virtual by default means I need to be more careful about overriding so something doesn't become virtual accidentally.
Further, virtual by default prevents non-virtual overriding, which can be used for high-performance compile-time polymorphism using templates.
That said, if this happens at all, Walter would probably use virtual by default for consistency sake. Oh well, I guess it's not that big a deal.
If polymorphism is added to structs, it should be optional. I would have a problem if the vtable pointer was included in structs that didn't have any polymorphism. It should work like C++ structs and classes, where there is no overhead for non-polymorphic types.
As for virtual destructors, I agree that they should be virtual by default, but only if a type is polymorphic. Forgetting to make a destructor virtual in C++ can cause subtle and annoying bugs. It's good that most C++ compilers issue warnings when a polymorphic type has a non-virtual destructor. However, I would rather the compiler make it virtual for me.
-Craig
| |||
December 23, 2007 Re: byval keyword to make objects act as value types | ||||
|---|---|---|---|---|
| ||||
Posted in reply to BC | BC wrote: > true, it's just that I don't buy that classes are always either value or > reference types, I think flexibility is desirable. you could still do > > class Foo{} > alias byval Foo VFoo; byval class VFoo {} alias VFoo* Foo; Close enough. >>> i notice the tango iterators are classes. surely we want to use iterators as value types... this way, we can. >>> alternatively, since scope objects are a bit like value types already, perhaps we can just add the functionality to that. >> >> Ugh. No. >> > no? currently the spec says you can't assign to them (although i see now > that you can), so i thought that might be the plan. Unless you can get the functionality while maintaining the current behavior of the scope storage class, I'm against it. You'd never get an unambiguous rule to determine which is to be used in the current case. | |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply