February 15, 2006 Re: In, inout, out, and damn lies.... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Regan Heath | On Wed, 15 Feb 2006 15:33:45 +1300, Regan Heath wrote: > On Tue, 14 Feb 2006 05:11:42 -0800, S. Chancellor >> Cleary, inout is a lie here as I do not modify Foo at all. It would be nice to be able to say "I want a reference, but i'm not going to modify the value it points to!" The alternative right now is to just say "in" and copy 100000 bytes of memory for no good reason. > > So, what is wrong with using a pointer in this case? i.e. > int ProcessFoos( Foo* bar ) > > ? You have to trust the called function to NOT change the array. If we could say ... int ProcessFoos( inref Foo bar ) which means that the compiler will pass a pointer *and* protect the contents of the array, maybe by doing a copy if the function is silly enough to explicitly modify it. -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocracy!" 15/02/2006 1:40:30 PM |
February 15, 2006 Re: In, inout, out, and damn lies.... | ||||
---|---|---|---|---|
| ||||
Posted in reply to S. Chancellor | In article <dssku5$1ifs$1@digitaldaemon.com>, S. Chancellor says... > >This recent thread about unsafe, and some of my own coding has recently pointed out a feature D lacks: > >In by reference > >Let me start by first posing a question: > >What is the implementation difference between inout and out? Both are by reference, and it is true that the out keyword on in the parameter does not preclude you from accessing the variables contents. So what does it mean? It tells the person calling your function that you have no plans to use the value given in an "out" parameter. So what? Well what about the 'in' keyword? It is implemented differently from out or inout, that is, it is passed by value. So where is the option to specify that I want an "in" parameter by reference without using pointers? It would be nice to not have to lie: > >struct Foo { > char[100000] bigArray; >} > >int ProcessFoos( inout Foo bar ) >{ > int hash = hash.max; > foreach( char c; bar.bigArray ) { > hash = (hash << 1) ^ c; > } > return hash; >} > >Cleary, inout is a lie here as I do not modify Foo at all. It would be nice to be able to say "I want a reference, but i'm not going to modify the value it points to!" The alternative right now is to just say "in" and copy 100000 bytes of memory for no good reason. > >-S. Wow, I didn't know about that. Seems to be a critical one! It's without question a serious issue to take care of if we expect D to be competitive. It should be possible to do IN BY REFERENCE parameters. Tom; |
February 15, 2006 Re: In, inout, out, and damn lies.... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | In article <kfg0ycw7i51c.1t4brpu7xgj6c.dlg@40tude.net>, Derek Parnell says... > >On Wed, 15 Feb 2006 15:33:45 +1300, Regan Heath wrote: > >> On Tue, 14 Feb 2006 05:11:42 -0800, S. Chancellor > >>> Cleary, inout is a lie here as I do not modify Foo at all. It would be nice to be able to say "I want a reference, but i'm not going to modify the value it points to!" The alternative right now is to just say "in" and copy 100000 bytes of memory for no good reason. >> >> So, what is wrong with using a pointer in this case? i.e. >> int ProcessFoos( Foo* bar ) >> >> ? > >You have to trust the called function to NOT change the array. If we could say ... > > int ProcessFoos( inref Foo bar ) > >which means that the compiler will pass a pointer *and* protect the contents of the array, maybe by doing a copy if the function is silly enough to explicitly modify it. Am I right that this would be the equivalent as in C++ would be: int ProcessFoos( const Foo &bar ) ? If this was the case, the compiler wouldn't allow modification of any member of the struct, so no copy would be necessary. If i'm wrong (or totally confused) please correct me, it's late and it has been a long day. Tom; |
February 15, 2006 Re: In, inout, out, and damn lies.... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Regan Heath | On 2006-02-14 18:41:02 -0800, "Regan Heath" <regan@netwin.co.nz> said:
> On Wed, 15 Feb 2006 15:33:45 +1300, Regan Heath <regan@netwin.co.nz> wrote:
>> On Tue, 14 Feb 2006 05:11:42 -0800, S. Chancellor <dnewsgr@mephit.kicks-ass.org> wrote:
>>> This recent thread about unsafe, and some of my own coding has recently pointed out a feature D lacks:
>>>
>>> In by reference
>>>
>>> Let me start by first posing a question:
>>>
>>> What is the implementation difference between inout and out? Both are by reference, and it is true that the out keyword on in the parameter does not preclude you from accessing the variables contents. So what does it mean? It tells the person calling your function that you have no plans to use the value given in an "out" parameter. So what? Well what about the 'in' keyword? It is implemented differently from out or inout, that is, it is passed by value. So where is the option to specify that I want an "in" parameter by reference without using pointers? It would be nice to not have to lie:
>>>
>>> struct Foo {
>>> char[100000] bigArray;
>>> }
>>>
>>> int ProcessFoos( inout Foo bar )
>>> {
>>> int hash = hash.max;
>>> foreach( char c; bar.bigArray ) {
>>> hash = (hash << 1) ^ c;
>>> }
>>> return hash;
>>> }
>>>
>>> Cleary, inout is a lie here as I do not modify Foo at all. It would be nice to be able to say "I want a reference, but i'm not going to modify the value it points to!" The alternative right now is to just say "in" and copy 100000 bytes of memory for no good reason.
>>
>> So, what is wrong with using a pointer in this case? i.e.
>> int ProcessFoos( Foo* bar )
>
> To be clear, I realise you said "without pointers" above, I want to know why you do not want to use a pointer.
>
> Regan
Pointers are just as vague as misusing inout. You're basically saying "I'm going to take this by reference and you don't have a clue what I'm going to do with it! Hahahaha!"
-S.
|
February 15, 2006 Re: In, inout, out, and damn lies.... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tom | On Wed, 15 Feb 2006 03:05:50 +0000 (UTC), Tom wrote: > In article <kfg0ycw7i51c.1t4brpu7xgj6c.dlg@40tude.net>, Derek Parnell says... >> >>On Wed, 15 Feb 2006 15:33:45 +1300, Regan Heath wrote: >> >>> On Tue, 14 Feb 2006 05:11:42 -0800, S. Chancellor >> >>>> Cleary, inout is a lie here as I do not modify Foo at all. It would be nice to be able to say "I want a reference, but i'm not going to modify the value it points to!" The alternative right now is to just say "in" and copy 100000 bytes of memory for no good reason. >>> >>> So, what is wrong with using a pointer in this case? i.e. >>> int ProcessFoos( Foo* bar ) >>> >>> ? >> >>You have to trust the called function to NOT change the array. If we could say ... >> >> int ProcessFoos( inref Foo bar ) >> >>which means that the compiler will pass a pointer *and* protect the contents of the array, maybe by doing a copy if the function is silly enough to explicitly modify it. > > Am I right that this would be the equivalent as in C++ would be: > > int ProcessFoos( const Foo &bar ) > > ? > > If this was the case, the compiler wouldn't allow modification of any member of the struct, so no copy would be necessary. If i'm wrong (or totally confused) please correct me, it's late and it has been a long day. No, I wasn't implying C++'s const functionality. I was implying that the compiler would *not* complain if the function had code to modified the passed array, instead it would silently take a copy of it and modify the copy. But this is probably too much against Walter's philosophy so I'm just wasting bandwidth again ;-) -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocracy!" 15/02/2006 2:14:14 PM |
February 15, 2006 Re: In, inout, out, and damn lies.... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | On Wed, 15 Feb 2006 13:44:37 +1100, Derek Parnell <derek@psych.ward> wrote: > On Wed, 15 Feb 2006 15:33:45 +1300, Regan Heath wrote: > >> On Tue, 14 Feb 2006 05:11:42 -0800, S. Chancellor > >>> Cleary, inout is a lie here as I do not modify Foo at all. It would be >>> nice to be able to say "I want a reference, but i'm not going to modify >>> the value it points to!" The alternative right now is to just say "in" >>> and copy 100000 bytes of memory for no good reason. >> >> So, what is wrong with using a pointer in this case? i.e. >> int ProcessFoos( Foo* bar ) >> >> ? > > You have to trust the called function to NOT change the array. True. > If we could say ... > > int ProcessFoos( inref Foo bar ) > > which means that the compiler will pass a pointer *and* protect the > contents of the array, maybe by doing a copy if the function is silly > enough to explicitly modify it. The fundamental problem being that as far as I can see the compiler provides no way to (or cannot) protect 'data' at all, eg. import std.stdio; struct Foo { const byte[10] data; } void processFoo(Foo* f) { f.data[1] = 5; } int main() { Foo f; processFoo(&f); writefln(f.data); return 0; } I suspect the "const" above applies to the static array itself (i.e. the static array data pointer/memory address), not the data contained in the array/pointed to by the array data pointer (which is const by nature anyway). To apply it to the data itself we'd need some syntax like: const byte[10] const data; or similar. Yet, even were that to work. It doesn't provide us a way to express the contract of a function which promises not to modify the content of the thing passed to it, whether it be a class, array, pointer to struct, etc. Given the convoluted things you can do with pointers I'm not sure even a really smart compiler could provide any guarantee that it will prevent/catch the function modifying the data at compile time. Even at runtime there doesn't seem to be any way short of copying the object and comparing with the copy at the end (which defeats the point of passing it by reference). Placing the object in read only memory works, but, it only works for: const byte[10] const data; or another _copy_ of a function parameter. It doesn't work for: byte[10] data; passed to a function which promises not to modify the content of the array (because "data" is not in read only memory.. yet) Is there any way to ask the hardware to 'lock' a section of memory, such that writes fail and signal an error? Could D provide this with software perhaps? What would that cost in terms of performance? Would it be enough to lock the contents of the object passed By contents I mean the thing that is referred to by the pointer/reference not the reference itself), or would it have to lock the contents of every reference in every reference ... in every object passed? (these questions are the same or similar to those Walter posted around here somewhere) The method I'd use at the moment is to use a pointer, and assume the function will use "Copy On Write" when it modifies something. Regan |
February 15, 2006 Re: In, inout, out, and damn lies.... | ||||
---|---|---|---|---|
| ||||
Posted in reply to S. Chancellor | On Tue, 14 Feb 2006 19:09:58 -0800, S. Chancellor <dnewsgr@mephit.kicks-ass.org> wrote:
> On 2006-02-14 18:41:02 -0800, "Regan Heath" <regan@netwin.co.nz> said:
>
>> On Wed, 15 Feb 2006 15:33:45 +1300, Regan Heath <regan@netwin.co.nz> wrote:
>>> On Tue, 14 Feb 2006 05:11:42 -0800, S. Chancellor <dnewsgr@mephit.kicks-ass.org> wrote:
>>>> This recent thread about unsafe, and some of my own coding has recently pointed out a feature D lacks:
>>>> In by reference
>>>> Let me start by first posing a question:
>>>> What is the implementation difference between inout and out? Both are by reference, and it is true that the out keyword on in the parameter does not preclude you from accessing the variables contents. So what does it mean? It tells the person calling your function that you have no plans to use the value given in an "out" parameter. So what? Well what about the 'in' keyword? It is implemented differently from out or inout, that is, it is passed by value. So where is the option to specify that I want an "in" parameter by reference without using pointers? It would be nice to not have to lie:
>>>> struct Foo {
>>>> char[100000] bigArray;
>>>> }
>>>> int ProcessFoos( inout Foo bar )
>>>> {
>>>> int hash = hash.max;
>>>> foreach( char c; bar.bigArray ) {
>>>> hash = (hash << 1) ^ c;
>>>> }
>>>> return hash;
>>>> }
>>>> Cleary, inout is a lie here as I do not modify Foo at all. It would be nice to be able to say "I want a reference, but i'm not going to modify the value it points to!" The alternative right now is to just say "in" and copy 100000 bytes of memory for no good reason.
>>> So, what is wrong with using a pointer in this case? i.e.
>>> int ProcessFoos( Foo* bar )
>> To be clear, I realise you said "without pointers" above, I want to know why you do not want to use a pointer.
>> Regan
>
> Pointers are just as vague as misusing inout. You're basically saying "I'm going to take this by reference and you don't have a clue what I'm going to do with it! Hahahaha!"
So, your reason for avoiding them is as Derek said? You want to express that the function promises not to modify the data inside the object passed, right?
Regan
|
February 15, 2006 Re: In, inout, out, and damn lies.... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | In article <1d166miote41e$.1qa28uiydunuu$.dlg@40tude.net>, Derek Parnell says... > >On Wed, 15 Feb 2006 03:05:50 +0000 (UTC), Tom wrote: > >> In article <kfg0ycw7i51c.1t4brpu7xgj6c.dlg@40tude.net>, Derek Parnell says... >>> >>>On Wed, 15 Feb 2006 15:33:45 +1300, Regan Heath wrote: >>> >>>> On Tue, 14 Feb 2006 05:11:42 -0800, S. Chancellor >>> >>>>> Cleary, inout is a lie here as I do not modify Foo at all. It would be nice to be able to say "I want a reference, but i'm not going to modify the value it points to!" The alternative right now is to just say "in" and copy 100000 bytes of memory for no good reason. >>>> >>>> So, what is wrong with using a pointer in this case? i.e. >>>> int ProcessFoos( Foo* bar ) >>>> >>>> ? >>> >>>You have to trust the called function to NOT change the array. If we could say ... >>> >>> int ProcessFoos( inref Foo bar ) >>> >>>which means that the compiler will pass a pointer *and* protect the contents of the array, maybe by doing a copy if the function is silly enough to explicitly modify it. >> >> Am I right that this would be the equivalent as in C++ would be: >> >> int ProcessFoos( const Foo &bar ) >> >> ? >> >> If this was the case, the compiler wouldn't allow modification of any member of the struct, so no copy would be necessary. If i'm wrong (or totally confused) please correct me, it's late and it has been a long day. > >No, I wasn't implying C++'s const functionality. I was implying that the compiler would *not* complain if the function had code to modified the passed array, instead it would silently take a copy of it and modify the copy. But this is probably too much against Walter's philosophy so I'm just wasting bandwidth again ;-) I'm the king of wasted bandwidth so don't feel bad about it ;-) So, if you didn't imply const functionality what is wrong about inref beeing that (const Type &var === inref Type var)? I really don't understand what´s the benefit of making a copy silently instead of complaining about the function trying to modify the INREF parameter. Please if you don't mind to explain me further, or I'm _really_ confused here and should shut my mouth (or my hands) :-) Tom; |
February 15, 2006 Re: In, inout, out, and damn lies.... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tom | On Wed, 15 Feb 2006 03:38:21 +0000 (UTC), Tom wrote: > In article <1d166miote41e$.1qa28uiydunuu$.dlg@40tude.net>, Derek Parnell says... >>> If this was the case, the compiler wouldn't allow modification of any member of the struct, so no copy would be necessary. If i'm wrong (or totally confused) please correct me, it's late and it has been a long day. >> >>No, I wasn't implying C++'s const functionality. I was implying that the compiler would *not* complain if the function had code to modified the passed array, instead it would silently take a copy of it and modify the copy. But this is probably too much against Walter's philosophy so I'm just wasting bandwidth again ;-) > > I'm the king of wasted bandwidth so don't feel bad about it ;-) > > So, if you didn't imply const functionality what is wrong about inref beeing that (const Type &var === inref Type var)? I really don't understand what´s the benefit of making a copy silently instead of complaining about the function trying to modify the INREF parameter. Please if you don't mind to explain me further, or I'm _really_ confused here and should shut my mouth (or my hands) :-) Ok, you asked for it ;-) Its pure laziness, that's all. It's just a way of automating CoW semantics. If all the compiler did was complain then I'd have to modify my code to do something different. This is a RARE circumstance I'm addressing here and one that also smacks of lazy coding. void func( inref char[] a) { . . . a[0] = 'C'; // compiler complains! . . . } so I change it to void func( inref char[] a) { . . . char[] b = a.dup; b[0] = 'C'; // compiler is now happy . . . } but if the compiler was happy for me to be lazy it might help me out by silent doing ... void func( inref char[] a) { a = a.dup; // take a copy and replace the pointer. . . . a[0] = 'C'; // compiler is now happy . . . } So, there is not really a good argument for supporting the silent CoW idea because I may as well be explicit about it anyway, thus using current D syntax ... void func(char[] a) { a = a.dup; // take a copy and replace the pointer. . . . a[0] = 'C'; . . . } -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocracy!" 15/02/2006 2:48:01 PM |
February 15, 2006 Re: In, inout, out, and damn lies.... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Regan Heath | In article <ops4zveocz23k2f5@nrage.netwin.co.nz>, Regan Heath says... > >On Tue, 14 Feb 2006 19:09:58 -0800, S. Chancellor <dnewsgr@mephit.kicks-ass.org> wrote: >> On 2006-02-14 18:41:02 -0800, "Regan Heath" <regan@netwin.co.nz> said: >> >>> On Wed, 15 Feb 2006 15:33:45 +1300, Regan Heath <regan@netwin.co.nz> wrote: >>>> On Tue, 14 Feb 2006 05:11:42 -0800, S. Chancellor <dnewsgr@mephit.kicks-ass.org> wrote: >>>>> This recent thread about unsafe, and some of my own coding has >>>>> recently pointed out a feature D lacks: >>>>> In by reference >>>>> Let me start by first posing a question: >>>>> What is the implementation difference between inout and out? Both >>>>> are by reference, and it is true that the out keyword on in the >>>>> parameter does not preclude you from accessing the variables >>>>> contents. So what does it mean? It tells the person calling your >>>>> function that you have no plans to use the value given in an "out" >>>>> parameter. So what? Well what about the 'in' keyword? It is >>>>> implemented differently from out or inout, that is, it is passed by >>>>> value. So where is the option to specify that I want an "in" >>>>> parameter by reference without using pointers? It would be nice to >>>>> not have to lie: >>>>> struct Foo { >>>>> char[100000] bigArray; >>>>> } >>>>> int ProcessFoos( inout Foo bar ) >>>>> { >>>>> int hash = hash.max; >>>>> foreach( char c; bar.bigArray ) { >>>>> hash = (hash << 1) ^ c; >>>>> } >>>>> return hash; >>>>> } >>>>> Cleary, inout is a lie here as I do not modify Foo at all. It would >>>>> be nice to be able to say "I want a reference, but i'm not going to >>>>> modify the value it points to!" The alternative right now is to >>>>> just say "in" and copy 100000 bytes of memory for no good reason. >>>> So, what is wrong with using a pointer in this case? i.e. >>>> int ProcessFoos( Foo* bar ) >>> To be clear, I realise you said "without pointers" above, I want to >>> know why you do not want to use a pointer. >>> Regan >> >> Pointers are just as vague as misusing inout. You're basically saying "I'm going to take this by reference and you don't have a clue what I'm going to do with it! Hahahaha!" > >So, your reason for avoiding them is as Derek said? You want to express that the function promises not to modify the data inside the object passed, right? > >Regan Yes, that's what I thought I was saying in my original post. -S. |
Copyright © 1999-2021 by the D Language Foundation