February 16, 2006 Re: In, inout, out, and damn lies.... | ||||
---|---|---|---|---|
| ||||
Posted in reply to S. | S. wrote: > In article <dsva39$139m$1@digitaldaemon.com>, David Medlock says... > >>S. Chancellor 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: >> >>inout is a C++ reference. >>out ensures the value will be initialized if it is untouched, it would also probably allow some compiler optimizations in certain cases. >> >> >>>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. >>> >> >>Its not a lie, its an ability which you simply did not use. >> >>This type of ability might be somewhat useful for library authors, but outside that it sounds as if you wish to handle a specific class of errors by changing the whole language. > > > Who said ANYTHING changing the entire language? The functionality I require is > already IN the language as pointers or as inout. The point is that there is > inconsitency in this case. > Making in variables reside in unwriteable memory does change the language, not the syntax but the semantics. If you can't see that I cannot discuss it further with you. > >>If you are simply writing programs and not a library, asking the compiler to guess your intent is not really feasible. The in/out/inout bestows *capabilities* not *constraints*. > > > The point of the in/inout/out keywords has NOTHING to do with anything other > than information. You are incorrect that they bestow features OR constraints. > They are neither! If they provide no new capabilites, you must intend that they are the same? Again I don't think you understand what the modifiers do. They are a means for function writers to give INFORMATION > about what their function does to the compiler, and to consumers of their > function. It just so happens that OUT by value or INOUT by value make NO SENSE, > so those keywords bestow reference passing on the parameter! Currently there is > no way to get reference passing parameters aside from pointers, or one of those > informational keywords. Wrong again, all class instances are passed by reference as I showed in my example. Structs are passed by value. And with out/inout you can modify the reference in either case. For structs, without inout you would have to pass an in paramter to get the current value and an out parameter to change the new value. if you add const what about this: void update( const in int a, out int b ) { b = a + 5; } int x = 5; update( x, x ); Since x is obviously not in read only memory, you will still have to copy some data around. Having to use pointers, or incorrently stating what > your function does with the parameter, are unacceptable ways to obtain a > reference. > > >>Even so, why not just use a class and perhaps an Immutable wrapper? >>Structs are useful for specific things, but shared data is not one of them, thats what classes are for. >>class CFoo >>{ >> Foo foo; >> int opApply( int delegate( inout char c ) dg ) { >> <process foo.bigArray> >> } >>} > > > Structs (AKA structures) and Classes are two fundementally different things > which are supposed to be for completely different purposes. That is storing > structured data vs grouping functions, which work on the same data, together. > You seem to be saying that the only difference between structures is solely the > fact that one has reference semantics while the other does not. I would fully > disagree with that assertion. > > -S. What I am saying is that structs are arbitrary chunks of memory passed as chunks of memory, whilst classes are references to objects passed as references to objects. You aren't objecting to a capability which isn't there you are objecting to the way to achieve it in D. I am having trouble judging your tone, but I suspect you might be worked up over this? Cheers. -DavidM |
February 16, 2006 Re: In, inout, out, and damn lies.... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | On 2006-02-15 17:06:26 -0800, Derek Parnell <derek@psych.ward> said:
> On Thu, 16 Feb 2006 13:39:56 +1300, Regan Heath wrote:
>
>> On Thu, 16 Feb 2006 11:34:39 +1100, Derek Parnell <derek@psych.ward> wrote:
>>> On Thu, 16 Feb 2006 11:27:45 +1100, Derek Parnell wrote:
>>>
>>>> On Wed, 15 Feb 2006 16:12:22 -0800, Sean Kelly wrote:
>>>>
>>>>> Derek Parnell wrote:
>>>>>> On Tue, 14 Feb 2006 05:11:42 -0800, S. Chancellor wrote:
>>>>>>
>>>>>>> This recent thread about unsafe, and some of my own coding has recently
>>>>>>> pointed out a feature D lacks:
>>>>>>>
>>>>>>> In by reference
>>>>>>
>>>>>> I've just noticed this in the D documentation, in the ABI reference...
>>>>>>
>>>>>> ---------------
>>>>>> Reference Types
>>>>>> When passing a static array to a function, the result, although declared as
>>>>>> a static array, will actually be a reference to a static array.
>>>>>
>>>>> This seems identical to array passing in C, where the same thing occurs.
>>>>>
>>>>
>>>> Okay. It's just that it seems to me then that S.'s concerns about passing a
>>>> huge array using the 'in' format are not warranted. However, this doesn't
>>>> help out with passing huge structures
>>>
>>> Oops, spoke too soon. I just tried this little test ...
>>>
>>> -----------------
>>> import std.stdio;
>>> char[100000] a = void;
>>>
>>> void func(in char[100000] x)
>>> {
>>> x[0] = 'x';
>>> }
>>>
>>> void main()
>>> {
>>> a[0] = 'a';
>>> func(a);
>>> writefln("%s", a[0]);
>>> }
>>> -----------------
>>>
>>> So although the huge array might actually be passed via a reference, it
>>> seems that the 'in' modifier is not respected. The output was 'x'.
>>
>> The 'in' modifier applies to the array reference, not the data.
>
> Yes I know that! But I didn't pass a reference, I passed an array. The
> compiler passed the reference. But yeah, I know...this is the whole point
> that people have been on about for ages. I just thought I'd highlight
> another trap for coders. You may think your passing the array but you
> aren't really. Nasty things could happen here.
Which is specifically why I wrapped the array into a structure. Static arrays within structures are contiguous with the rest of the structure, or should be. Try it again that way.
My main point had nothing to do with passing arrays specifically, but passing NON-REFERENCE data types such as structures via in keywords. I filled the structure with a big static array to illustrate that it was big.
-S.
|
February 16, 2006 Re: In, inout, out, and damn lies.... | ||||
---|---|---|---|---|
| ||||
Posted in reply to David Medlock | On 2006-02-15 18:00:35 -0800, David Medlock <noone@nowhere.com> said: > S. wrote: >> In article <dsva39$139m$1@digitaldaemon.com>, David Medlock says... >> >>> S. Chancellor 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: >>> >>> inout is a C++ reference. >>> out ensures the value will be initialized if it is untouched, it would also probably allow some compiler optimizations in certain cases. >>> >>> >>>> 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. >>>> >>> >>> Its not a lie, its an ability which you simply did not use. >>> >>> This type of ability might be somewhat useful for library authors, but outside that it sounds as if you wish to handle a specific class of errors by changing the whole language. >> >> >> Who said ANYTHING changing the entire language? The functionality I require is >> already IN the language as pointers or as inout. The point is that there is >> inconsitency in this case. >> > > Making in variables reside in unwriteable memory does change the language, not the syntax but the semantics. If you can't see that I cannot discuss it further with you. You seem to be confusing this thread with the const thread. Go re-read my original message. This has nothing to do with "readonlyness". Nowhere did I recommend the compiler _DO_ anything but provide a "inref" keyword which allowed you to declare what you were doing, and that you wanted to do it to a reference. (If walter wants to implement some kind of warning when you write to it, that's fine by me.) I did nowhere call for any compiler checking of this feature.As you will also note, the compiler does not currently prevent you from using the value of an "out" parameter before you assign anything to it either. (Although it seems the current version of DMD sets it to the type initializer regardless of what you do.) Also moving the variables to unwritable memory clearly would not be "by reference,...." >> >>> If you are simply writing programs and not a library, asking the compiler to guess your intent is not really feasible. The in/out/inout bestows *capabilities* not *constraints*. >> >> >> The point of the in/inout/out keywords has NOTHING to do with anything other >> than information. You are incorrect that they bestow features OR constraints. >> They are neither! > > If they provide no new capabilites, you must intend that they are the same? Again I don't think you understand what the modifiers do. You've already demonstrated that you don't by claiming that classes are passed by reference even when an in parameter is specified. You should try it. > They are a means for function writers to give INFORMATION >> about what their function does to the compiler, and to consumers of their >> function. It just so happens that OUT by value or INOUT by value make NO SENSE, >> so those keywords bestow reference passing on the parameter! Currently there is >> no way to get reference passing parameters aside from pointers, or one of those >> informational keywords. > > Wrong again, all class instances are passed by reference as I showed in my example. Structs are passed by value. And with out/inout you can modify the reference in either case. Yes, Mostly. That is indeed how they are implemented, and that is indeed what in and inout do. > For structs, without inout you would have to pass an in paramter to get the current value and an out parameter to change the new value. Yes. That's because DMD does you a favor and initializes any out parameters to their type's initializer. If it skipped this step, inout and out would be identical aside from their informational purposes. > > if you add const what about this: > > void update( const in int a, out int b ) > { > b = a + 5; > } > > > int x = 5; > update( x, x ); > > Since x is obviously not in read only memory, you will still have to copy some data around. > > Having to use pointers, or incorrently stating what >> your function does with the parameter, are unacceptable ways to obtain a >> reference. >> >> >>> Even so, why not just use a class and perhaps an Immutable wrapper? >>> Structs are useful for specific things, but shared data is not one of them, thats what classes are for. >>> class CFoo >>> { >>> Foo foo; >>> int opApply( int delegate( inout char c ) dg ) { >>> <process foo.bigArray> >>> } >>> } >> >> >> Structs (AKA structures) and Classes are two fundementally different things >> which are supposed to be for completely different purposes. That is storing >> structured data vs grouping functions, which work on the same data, together. >> You seem to be saying that the only difference between structures is solely the >> fact that one has reference semantics while the other does not. I would fully >> disagree with that assertion. >> -S. > > What I am saying is that structs are arbitrary chunks of memory passed as chunks of memory, whilst classes are references to objects passed as references to objects. You aren't objecting to a capability which isn't there you are objecting to the way to achieve it in D. The difference between structs and classes goes beyond reference semantics. What is well suited as a struct may not be well suited as a class. Your suggestion of using classes instead of structures to obtain my goal is not a solution to the question raised. Also, you are incorrect, if you pass a class via an "IN" parameter is is in fact dup'd prior to being passed in. Go ahead and try it. Clearly there is a REASON why in C++ there is the ability to pass _any_ type by reference or by value. This is available in C, C#, Visual Basic, etc. and also in D but using outdated syntax to accomplish it. Syntax which is not consistent with the rest of D. Do you think this is a useless feature? That seems to be what you're implying. Let me reiterate what I'm saying for you, since you are mixing up threads: 1. In always dup's the type, essentially passing by value. (It seems this is broken for arrays, but not classes.) 2. Inout passes by reference and leaves the passed value in tact. 3. Out passed by reference and destroys the current contents, essentially acting as another return value. 4. There is no current way to specify that you will NOT modify the value, but that you don't want the overhead of copying. This needs to be addressed. Once something is passed by reference the compiler cannot PREVENT you from modifying it, but that's not the point. If you WANTED to modify it you could simply say inout. We're not malicious hackers here. The purposes of these keywords are fundamentally informational, not that they actually "DO" anything in particular. It just so happens though it would be stupid to have a By value out parameter or the like, so D simplifies it and wraps some functionality into that inout modifier. 5. If the compiler wants to give an error if you try to modify an InByRef parameter, more power to it. Obviously it can't copy it into readonly memory before passing or it wouldn't be able to be by reference. > I am having trouble judging your tone, but I suspect you might be worked up over this? "Wrong again". Cheers -S. |
February 16, 2006 Re: In, inout, out, and damn lies.... | ||||
---|---|---|---|---|
| ||||
Posted in reply to S. Chancellor | S. Chancellor wrote: > On 2006-02-15 18:00:35 -0800, David Medlock <noone@nowhere.com> said: > >> S. wrote: >>> >>> Who said ANYTHING changing the entire language? The functionality I require is >>> already IN the language as pointers or as inout. The point is that there is >>> inconsitency in this case. >>> >> >> Making in variables reside in unwriteable memory does change the language, not the syntax but the semantics. If you can't see that I cannot discuss it further with you. > > > You seem to be confusing this thread with the const thread. Go re-read my original message. This has nothing to do with "readonlyness". Nowhere did I recommend the compiler _DO_ anything but provide a "inref" keyword which allowed you to declare what you were doing, and that you wanted to do it to a reference. (If walter wants to implement some kind of warning when you write to it, that's fine by me.) I did nowhere call for any compiler checking of this feature.As you will also note, the compiler does not currently prevent you from using the value of an "out" parameter before you assign anything to it either. (Although it seems the current version of DMD sets it to the type initializer regardless of what you do.) > Actually I am not. To do what you wish to do you need to ensure that the data isnt changed by the function you call. Unless you can be sure of that, the struct data *must* be passed by value or you *will* change the semantics of the current operators. foo test( inref B foo ) { return some_other_c_function( &foo ); } If foo was passed by reference the original is modified. If I could guarantee that foo is not modified then reference semantics would work. > Also moving the variables to unwritable memory clearly would not be "by reference,...." > But having them in unwritable memory would ensure that the byreference semantics wouldnt break existing code.... >>> >>>> If you are simply writing programs and not a library, asking the compiler to guess your intent is not really feasible. The in/out/inout bestows *capabilities* not *constraints*. >>> >>> >>> >>> The point of the in/inout/out keywords has NOTHING to do with anything other >>> than information. You are incorrect that they bestow features OR constraints. >>> They are neither! >> >> >> If they provide no new capabilites, you must intend that they are the same? Again I don't think you understand what the modifiers do. > > > You've already demonstrated that you don't by claiming that classes are passed by reference even when an in parameter is specified. You should try it. > import std.stdio; class A { int x = 1; } struct B { int x = 1; } void one( in A a ) { a.x = 5; } void two( in B b ) { b.x = 5; } void main( char[][] args ) { A foo = new A(); writefln( "%s", foo.x ); one( foo ); writefln( "%s", foo.x ); B bar; writefln( "%s", bar.x ); two( bar ); writefln( "%s", bar.x ); } prints: 1 5 1 1 This is reference versus value semantics. The class object is passed by reference, the struct is passed by value. > The difference between structs and classes goes beyond reference semantics. What is well suited as a struct may not be well suited as a class. Your suggestion of using classes instead of structures to obtain my goal is not a solution to the question raised. Also, you are incorrect, if you pass a class via an "IN" parameter is is in fact dup'd prior to being passed in. Go ahead and try it. I did and the class reference still points to the same class object as the caller. > Clearly there is a REASON why in C++ there is the ability to pass _any_ type by reference or by value. This is available in C, C#, Visual Basic, etc. and also in D but using outdated syntax to accomplish it. Syntax which is not consistent with the rest of D. Do you think this is a useless feature? That seems to be what you're implying. No I don't think its a useless feature. I do think as long as we have pointers and C compatability in D it isn't really feasible. > > Let me reiterate what I'm saying for you, since you are mixing up threads: > > 1. In always dup's the type, essentially passing by value. (It seems this is broken for arrays, but not classes.) It dups the value for everything but arrays(pointers with a length) and classes. > 4. There is no current way to specify that you will NOT modify the value, but that you don't want the overhead of copying. This needs to be addressed. I thought we werent talking about const? Once something is passed by reference the compiler > cannot PREVENT you from modifying it, but that's not the point. If you WANTED to modify it you could simply say inout. We're not malicious hackers here. The purposes of these keywords are fundamentally informational, not that they actually "DO" anything in particular. Again, they do change the passing semantics. Whether or not you realize it, you are asking for in/inref to be equivalent to C++'s const. >> I am having trouble judging your tone, but I suspect you might be worked up over this? > > > "Wrong again". Cheers > > -S. Can't imagine how I got that impression with the title of the thread... -DavidM |
February 16, 2006 Re: In, inout, out, and damn lies.... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | Derek Parnell wrote: > On Thu, 16 Feb 2006 13:39:56 +1300, Regan Heath wrote: > >> On Thu, 16 Feb 2006 11:34:39 +1100, Derek Parnell <derek@psych.ward> wrote: >>> On Thu, 16 Feb 2006 11:27:45 +1100, Derek Parnell wrote: >>> >>>> On Wed, 15 Feb 2006 16:12:22 -0800, Sean Kelly wrote: >>>> >>>>> Derek Parnell wrote: >>>>>> On Tue, 14 Feb 2006 05:11:42 -0800, S. Chancellor wrote: >>>>>> >>>>>>> This recent thread about unsafe, and some of my own coding has recently >>>>>>> pointed out a feature D lacks: >>>>>>> >>>>>>> In by reference >>>>>> I've just noticed this in the D documentation, in the ABI reference... >>>>>> >>>>>> --------------- >>>>>> Reference Types >>>>>> When passing a static array to a function, the result, although declared as >>>>>> a static array, will actually be a reference to a static array. >>>>> This seems identical to array passing in C, where the same thing occurs. >>>>> >>>> Okay. It's just that it seems to me then that S.'s concerns about passing a >>>> huge array using the 'in' format are not warranted. However, this doesn't >>>> help out with passing huge structures >>> Oops, spoke too soon. I just tried this little test ... >>> >>> ----------------- >>> import std.stdio; >>> char[100000] a = void; >>> >>> void func(in char[100000] x) >>> { >>> x[0] = 'x'; >>> } >>> >>> void main() >>> { >>> a[0] = 'a'; >>> func(a); >>> writefln("%s", a[0]); >>> } >>> ----------------- >>> >>> So although the huge array might actually be passed via a reference, it >>> seems that the 'in' modifier is not respected. The output was 'x'. >> The 'in' modifier applies to the array reference, not the data. > > Yes I know that! But I didn't pass a reference, I passed an array. The > compiler passed the reference. But yeah, I know...this is the whole point > that people have been on about for ages. I just thought I'd highlight > another trap for coders. You may think your passing the array but you > aren't really. Nasty things could happen here. > How is that surprising, or another trap for coders ? It's the way it is done since old C to any modern day C-family language. Static arrays are (like) reference types. -- Bruno Medeiros - CS/E student "Certain aspects of D are a pathway to many abilities some consider to be... unnatural." |
February 16, 2006 Re: In, inout, out, and damn lies.... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bruno Medeiros | On Fri, 17 Feb 2006 00:51:05 +1100, Bruno Medeiros <daiphoenixNO@SPAMlycos.com> wrote: [snip] >>> The 'in' modifier applies to the array reference, not the data. >> Yes I know that! But I didn't pass a reference, I passed an array. The >> compiler passed the reference. But yeah, I know...this is the whole point >> that people have been on about for ages. I just thought I'd highlight >> another trap for coders. You may think your passing the array but you >> aren't really. Nasty things could happen here. >> > > How is that surprising, or another trap for coders ? It's the way it is done since old C to any modern day C-family language. Static arrays are (like) reference types. It is surprising if one does not have a C background and one uses normal reasoning. My code said "pass this array to the function". The compiler didn't do that. We are told that fixed length arrays and structs are created on the stack not the heap but that classes and variable length arrays are heap things. We are told that heap entities are passed by reference. We are told that structs are passed by value, so one could innocently assume that fixed length arrays, being stack entities like structs, are also passed by value. This topic doesn't warrant further consideration. -- Derek Parnell Melbourne, Australia |
February 16, 2006 Re: In, inout, out, and damn lies.... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | In article <op.s42nznti6b8z09@ginger.vic.bigpond.net.au>, Derek Parnell says... > >On Fri, 17 Feb 2006 00:51:05 +1100, Bruno Medeiros <daiphoenixNO@SPAMlycos.com> wrote: > > >[snip] > >>>> The 'in' modifier applies to the array reference, not the data. >>> Yes I know that! But I didn't pass a reference, I passed an array. The >>> compiler passed the reference. But yeah, I know...this is the whole >>> point >>> that people have been on about for ages. I just thought I'd highlight >>> another trap for coders. You may think your passing the array but you >>> aren't really. Nasty things could happen here. >>> >> >> How is that surprising, or another trap for coders ? It's the way it is done since old C to any modern day C-family language. Static arrays are (like) reference types. > >It is surprising if one does not have a C background and one uses normal reasoning. > >My code said "pass this array to the function". The compiler didn't do that. We are told that fixed length arrays and structs are created on the stack not the heap but that classes and variable length arrays are heap things. We are told that heap entities are passed by reference. We are told that structs are passed by value, so one could innocently assume that fixed length arrays, being stack entities like structs, are also passed by value. > >This topic doesn't warrant further consideration. It's interesting to note that classes passed via 'in' parameters are still passed by VALUE. Not reference. Just some food for thought. -S. |
February 16, 2006 Re: In, inout, out, and damn lies.... | ||||
---|---|---|---|---|
| ||||
Posted in reply to David Medlock | In article <dt1uqc$dut$1@digitaldaemon.com>, David Medlock says... > >import std.stdio; > >class A { int x = 1; } >struct B { int x = 1; } > >void one( in A a ) >{ > a.x = 5; >} > >void two( in B b ) >{ > b.x = 5; >} > >void main( char[][] args ) >{ > A foo = new A(); > writefln( "%s", foo.x ); > one( foo ); > writefln( "%s", foo.x ); > > B bar; > writefln( "%s", bar.x ); > two( bar ); > writefln( "%s", bar.x ); >} > > >prints: >1 >5 >1 >1 > >This is reference versus value semantics. >The class object is passed by reference, the struct is passed by value. Oops. In my test I got confused about what & was giving me. You are right. However, You've just proven there's absolutely nothing wrong with just giving me an inref keyword that is essentially an alias to the inout keyword. Which is what I requested. Have a nice day. -S. |
February 16, 2006 Re: In, inout, out, and damn lies.... | ||||
---|---|---|---|---|
| ||||
Posted in reply to S. Chancellor | In article <dt2faq$105d$1@digitaldaemon.com>, S. Chancellor says... > >In article <dt1uqc$dut$1@digitaldaemon.com>, David Medlock says... >> >>import std.stdio; >> >>class A { int x = 1; } >>struct B { int x = 1; } >> >>void one( in A a ) >>{ >> a.x = 5; >>} >> >>void two( in B b ) >>{ >> b.x = 5; >>} >> >>void main( char[][] args ) >>{ >> A foo = new A(); >> writefln( "%s", foo.x ); >> one( foo ); >> writefln( "%s", foo.x ); >> >> B bar; >> writefln( "%s", bar.x ); >> two( bar ); >> writefln( "%s", bar.x ); >>} >> >> >>prints: >>1 >>5 >>1 >>1 >> >>This is reference versus value semantics. >>The class object is passed by reference, the struct is passed by value. > > >Oops. In my test I got confused about what & was giving me. You are right. > >However, You've just proven there's absolutely nothing wrong with just giving me an inref keyword that is essentially an alias to the inout keyword. Which is what I requested. > >Have a nice day. > >-S. > How about one keyword: 'byref' as in 'in', 'out' and 'byref'. It's grep-able and should be pretty much universally understood by anyone except total programming newbies (who probably would have as much trouble grasping 'inout' anyway). Heck, modern BASICS's and even things like Windows script have 'ByVal' and 'ByRef' and I've never heard any complaints there - they are well understood even by developers who are not real familiar with pointer syntax or semantics. int foo(byref int x) { ... } foreach(byref double d; darr) { ... } As for keyword consistency using the words in and out -- 'in' will rarely be used anyway and for my money could be removed as a keyword, unless it inherits some special meaning w.r.t. 'constness' or something along those lines. - Dave |
February 16, 2006 Re: In, inout, out, and damn lies.... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dave | In article <dt2hth$132q$1@digitaldaemon.com>, Dave says... > >In article <dt2faq$105d$1@digitaldaemon.com>, S. Chancellor says... >> >>In article <dt1uqc$dut$1@digitaldaemon.com>, David Medlock says... >>> >>>import std.stdio; >>> >>>class A { int x = 1; } >>>struct B { int x = 1; } >>> >>>void one( in A a ) >>>{ >>> a.x = 5; >>>} >>> >>>void two( in B b ) >>>{ >>> b.x = 5; >>>} >>> >>>void main( char[][] args ) >>>{ >>> A foo = new A(); >>> writefln( "%s", foo.x ); >>> one( foo ); >>> writefln( "%s", foo.x ); >>> >>> B bar; >>> writefln( "%s", bar.x ); >>> two( bar ); >>> writefln( "%s", bar.x ); >>>} >>> >>> >>>prints: >>>1 >>>5 >>>1 >>>1 >>> >>>This is reference versus value semantics. >>>The class object is passed by reference, the struct is passed by value. >> >> >>Oops. In my test I got confused about what & was giving me. You are right. >> >>However, You've just proven there's absolutely nothing wrong with just giving me an inref keyword that is essentially an alias to the inout keyword. Which is what I requested. >> >>Have a nice day. >> >>-S. >> > >How about one keyword: 'byref' as in 'in', 'out' and 'byref'. It's grep-able and should be pretty much universally understood by anyone except total programming newbies (who probably would have as much trouble grasping 'inout' anyway). > >Heck, modern BASICS's and even things like Windows script have 'ByVal' and 'ByRef' and I've never heard any complaints there - they are well understood even by developers who are not real familiar with pointer syntax or semantics. > >int foo(byref int x) { ... } >foreach(byref double d; darr) { ... } > >As for keyword consistency using the words in and out -- 'in' will rarely be used anyway and for my money could be removed as a keyword, unless it inherits some special meaning w.r.t. 'constness' or something along those lines. One of the reasons there's out/inout/in keywords exist is to provide implementation details in the parameter list. But also, while we're at it, since any out keywords are obviously by reference, lets make that automatic? Whoops, we forgot we sometimes want in keywords which are references. And to answer your question, maybe eventually the different keywords will impart protections. For example, the out keyword overwrites the variable with it's initializer before allowing you to use it. -S. |
Copyright © 1999-2021 by the D Language Foundation