January 31, 2013 pass-by-ref semantics for structs (was Deque impl.) | ||||
---|---|---|---|---|
| ||||
On Thu, Jan 31, 2013 at 5:30 PM, monarch_dodra <monarchdodra@gmail.com> wrote:
> The pull is kind of stuck in limbo, specifically because of the problems associated with implementing reference semantics with structs :/
Thanks for the enlightening email.
I am of the considered view that reference semantics with structs in D is tough (if not impossible) with default constructor and postblit constructor (used when passing objects). This is because you can not initialize any object (wrapped in the struct) in the default constructor and if you are passing the struct as a function parameter, it is not possible to initialize these internal objects (before passing them) in the postblit constructor. I faced this in some of my code. Do not know if you are facing the same scenario in the DList implementation.
Are there any possible solutions in the pipe?
Regards
- Puneet
|
January 31, 2013 Re: pass-by-ref semantics for structs (was Deque impl.) | ||||
---|---|---|---|---|
| ||||
Posted in reply to d coder | On Thursday, 31 January 2013 at 12:28:00 UTC, d coder wrote:
> On Thu, Jan 31, 2013 at 5:30 PM, monarch_dodra <monarchdodra@gmail.com> wrote:
>> The pull is kind of stuck in limbo, specifically because of the problems
>> associated with implementing reference semantics with structs :/
>
>
> Thanks for the enlightening email.
>
> I am of the considered view that reference semantics with structs in D
> is tough (if not impossible) with default constructor and postblit
> constructor (used when passing objects). This is because you can not
> initialize any object (wrapped in the struct) in the default
> constructor and if you are passing the struct as a function parameter,
> it is not possible to initialize these internal objects (before
> passing them) in the postblit constructor. I faced this in some of my
> code. Do not know if you are facing the same scenario in the DList
> implementation.
>
> Are there any possible solutions in the pipe?
>
> Regards
> - Puneet
This keeps coming up, so I'll wrap up how it goes:
Conclusions:
* The language will not change.
* Use "static S opCall()" to emulate no-arg constructor
The conversation:
- "But opCall is not good enough: It's not a constructor"
- "But it's all you'll get"
If you want some history, specifically, you need to look for "no-arg constructor".
|
January 31, 2013 Re: pass-by-ref semantics for structs (was Deque impl.) | ||||
---|---|---|---|---|
| ||||
Posted in reply to d coder | On Thu, 31 Jan 2013 07:27:08 -0500, d coder <dlang.coder@gmail.com> wrote:
> On Thu, Jan 31, 2013 at 5:30 PM, monarch_dodra <monarchdodra@gmail.com> wrote:
>> The pull is kind of stuck in limbo, specifically because of the problems
>> associated with implementing reference semantics with structs :/
>
>
> Thanks for the enlightening email.
>
> I am of the considered view that reference semantics with structs in D
> is tough (if not impossible) with default constructor and postblit
> constructor (used when passing objects). This is because you can not
> initialize any object (wrapped in the struct) in the default
> constructor and if you are passing the struct as a function parameter,
> it is not possible to initialize these internal objects (before
> passing them) in the postblit constructor. I faced this in some of my
> code. Do not know if you are facing the same scenario in the DList
> implementation.
It's pretty simple. Containers are reference types, and it makes most sense to pass them by reference.
In order to be sane, containers must be implemented as classes. Otherwise, you have behavior like this:
void foo(int[int] aa, int x, int y)
{
aa[x] = y;
}
void main()
{
int[int] aa;
foo(aa, 1, 2);
aa[3] = 4;
foo(aa, 5, 6);
assert(!(1 in aa));
assert(aa[3] == 4);
assert(aa[5] == 6);
}
In other words, the only way to turn a default-instantiated struct into a valid struct is to use it once. Not the behavior you want.
Classes don't have this problem, because you must instantiate them to use them.
-Steve
|
January 31, 2013 Re: pass-by-ref semantics for structs (was Deque impl.) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On 1/31/13 10:03 AM, Steven Schveighoffer wrote:
> On Thu, 31 Jan 2013 07:27:08 -0500, d coder <dlang.coder@gmail.com> wrote:
>
>> On Thu, Jan 31, 2013 at 5:30 PM, monarch_dodra
>> <monarchdodra@gmail.com> wrote:
>>> The pull is kind of stuck in limbo, specifically because of the problems
>>> associated with implementing reference semantics with structs :/
>>
>>
>> Thanks for the enlightening email.
>>
>> I am of the considered view that reference semantics with structs in D
>> is tough (if not impossible) with default constructor and postblit
>> constructor (used when passing objects). This is because you can not
>> initialize any object (wrapped in the struct) in the default
>> constructor and if you are passing the struct as a function parameter,
>> it is not possible to initialize these internal objects (before
>> passing them) in the postblit constructor. I faced this in some of my
>> code. Do not know if you are facing the same scenario in the DList
>> implementation.
>
> It's pretty simple. Containers are reference types, and it makes most
> sense to pass them by reference.
>
> In order to be sane, containers must be implemented as classes.
> Otherwise, you have behavior like this:
>
> void foo(int[int] aa, int x, int y)
> {
> aa[x] = y;
> }
>
> void main()
> {
> int[int] aa;
> foo(aa, 1, 2);
> aa[3] = 4;
> foo(aa, 5, 6);
> assert(!(1 in aa));
> assert(aa[3] == 4);
> assert(aa[5] == 6);
> }
>
> In other words, the only way to turn a default-instantiated struct into
> a valid struct is to use it once. Not the behavior you want.
>
> Classes don't have this problem, because you must instantiate them to
> use them.
As far as I can tell classes have the same problem.
Andrei
|
January 31, 2013 Re: pass-by-ref semantics for structs (was Deque impl.) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Thu, 31 Jan 2013 10:12:53 -0500, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote: > On 1/31/13 10:03 AM, Steven Schveighoffer wrote: >> On Thu, 31 Jan 2013 07:27:08 -0500, d coder <dlang.coder@gmail.com> wrote: >> >>> On Thu, Jan 31, 2013 at 5:30 PM, monarch_dodra >>> <monarchdodra@gmail.com> wrote: >>>> The pull is kind of stuck in limbo, specifically because of the problems >>>> associated with implementing reference semantics with structs :/ >>> >>> >>> Thanks for the enlightening email. >>> >>> I am of the considered view that reference semantics with structs in D >>> is tough (if not impossible) with default constructor and postblit >>> constructor (used when passing objects). This is because you can not >>> initialize any object (wrapped in the struct) in the default >>> constructor and if you are passing the struct as a function parameter, >>> it is not possible to initialize these internal objects (before >>> passing them) in the postblit constructor. I faced this in some of my >>> code. Do not know if you are facing the same scenario in the DList >>> implementation. >> >> It's pretty simple. Containers are reference types, and it makes most >> sense to pass them by reference. >> >> In order to be sane, containers must be implemented as classes. >> Otherwise, you have behavior like this: >> >> void foo(int[int] aa, int x, int y) >> { >> aa[x] = y; >> } >> >> void main() >> { >> int[int] aa; >> foo(aa, 1, 2); >> aa[3] = 4; >> foo(aa, 5, 6); >> assert(!(1 in aa)); >> assert(aa[3] == 4); >> assert(aa[5] == 6); >> } >> >> In other words, the only way to turn a default-instantiated struct into >> a valid struct is to use it once. Not the behavior you want. >> >> Classes don't have this problem, because you must instantiate them to >> use them. > > As far as I can tell classes have the same problem. Nope. void foo(someclass aa, int x, int y) { aa[x] = y; } void main() { someclass aa; foo(aa, 1, 2); // segfault ... } -Steve |
January 31, 2013 Re: pass-by-ref semantics for structs (was Deque impl.) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On 1/31/13 10:18 AM, Steven Schveighoffer wrote:
> On Thu, 31 Jan 2013 10:12:53 -0500, Andrei Alexandrescu
>> As far as I can tell classes have the same problem.
>
> Nope.
>
> void foo(someclass aa, int x, int y)
> {
> aa[x] = y;
> }
>
> void main()
> {
> someclass aa;
> foo(aa, 1, 2); // segfault
> ...
> }
We could easily arrange things to segfault just the same with a struct-based implementation.
Andrei
|
January 31, 2013 Re: pass-by-ref semantics for structs (was Deque impl.) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Thursday, 31 January 2013 at 15:12:52 UTC, Andrei Alexandrescu wrote:
>
> As far as I can tell classes have the same problem.
>
>
> Andrei
Regarding classes, would there be any chance of being to create a class instance that isn't a child of "object"?
I'm not entirely sure what the implications are, but it seems that is the major "no-sell" argument against using classes.
I know *I* would be using them a whole lot more if this was the case.
|
January 31, 2013 Re: pass-by-ref semantics for structs (was Deque impl.) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Thursday, 31 January 2013 at 15:21:02 UTC, Andrei Alexandrescu wrote:
>
> We could easily arrange things to segfault just the same with a struct-based implementation.
>
> Andrei
Not if you have a "lazy initialization scheme", which is the current scheme we are using...
...and will probably continue to use, since we have no standard way of forcing initialization :(
|
January 31, 2013 Re: pass-by-ref semantics for structs (was Deque impl.) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Thu, 31 Jan 2013 10:21:04 -0500, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote: > On 1/31/13 10:18 AM, Steven Schveighoffer wrote: >> On Thu, 31 Jan 2013 10:12:53 -0500, Andrei Alexandrescu >>> As far as I can tell classes have the same problem. >> >> Nope. >> >> void foo(someclass aa, int x, int y) >> { >> aa[x] = y; >> } >> >> void main() >> { >> someclass aa; >> foo(aa, 1, 2); // segfault >> ... >> } > > We could easily arrange things to segfault just the same with a struct-based implementation. So you want to make a struct that acts just like a class? I'm not seeing the point. -Steve |
January 31, 2013 Re: pass-by-ref semantics for structs (was Deque impl.) | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On 1/31/13 10:27 AM, monarch_dodra wrote: > On Thursday, 31 January 2013 at 15:12:52 UTC, Andrei Alexandrescu wrote: >> >> As far as I can tell classes have the same problem. >> >> >> Andrei > > Regarding classes, would there be any chance of being to create a class > instance that isn't a child of "object"? Using classes entails buying into an entire object model with its own pluses and minuses. Adding classes that don't inherit Object would wreck havoc all over the place. > I'm not entirely sure what the implications are, but it seems that is > the major "no-sell" argument against using classes. > > I know *I* would be using them a whole lot more if this was the case. What would be the problem? Andrei |
Copyright © 1999-2021 by the D Language Foundation