In, inout, out, and damn lies....

S. Chancellor dnewsgr at mephit.kicks-ass.org
Wed Feb 22 18:13:24 PST 2006


Why do you keep referring to "ByRef"-  I wasn't asking for ByRef- this 
thread isn't about ByRef. It's about an _IN_ by reference passing 
method.  It has nothing to do with a method of restricting the 
developer, but establishing with the consumer of the function a type of 
guarantee while going along with the rest of the D passing methods.

-S.


On 2006-02-18 13:19:15 -0800, "Regan Heath" <regan at netwin.co.nz> said:

> On Sat, 18 Feb 2006 12:35:39 +0100, Ivan Senji  
> <ivan.senji_REMOVE_ at _THIS__gmail.com> wrote:
>> Regan Heath wrote:
>>> On Sat, 18 Feb 2006 11:21:27 +0100, Ivan Senji   
>>> <ivan.senji_REMOVE_ at _THIS__gmail.com> wrote:
>>> 
>>>> Regan Heath wrote:
>>>> 
>>>>> My objection to "byref" is that it adds nothing that pointers don't    
>>>>> already give us.
>>>> 
>>>> 
>>>> That is apsolutely not true. Then you might say the same about inout.
>>>   No, I would not. Lets examine the cases shall we?
>>>  void foo(int a)     //tells us 'a' is input
>>>  void foo(out int a) //tells us 'a' is output
>>> void foo(int* a)    //tells us nothing
>>>  void foo(inout int a) //tells us 'a' is input and output.
>>> void foo(int* a)      //tells us nothing
>>>  I agree that out and inout add value. If you replace 'int' above with  
>>> a  structure the same is true, however, you get the problem that  
>>> started this  thread:
>>>  struct A {}
>>> void foo(A a) //tells us 'a' is input
>>>  copies 'in' the entire structure, which may not be desirable, I  
>>> believe  the solution:
>>>  void foo(A* a) //tells us 'a' is input
>> 
>> I don't get it: passing a pointer here tells you that A is input but in 
>>  the above example with int it told you nothing? HM.
> 
> In the world where 'out' and 'inout' do not exist, a pointer represents 
> 3  cases, input, output, and input+output. In the world where 'out' and 
>  'inout' exist they replace the output and input+output cases leaving 
> only  the input case.
> 
> It's true, someone could use a pointer to handle the output or 
> input+ouput  cases, you can't guarantee they haven't, just like you 
> can't guarantee  they're not going to modify the data referenced by the 
> pointer (or class  reference). "byref" doesn't solve that problem 
> either.
> 
>>>  cannot be improved by "byref", how does "byref" make the above better?  eg.
>> 
>> The same way inout is better than *
> 
> And that way is...?
> 
> 'inout' is better than * because it allows you to use pass 'int' 
> without  dereferencing. "byref" is not required for 'int' and you don't 
> need to  dereference a struct, so no benefit there.
> 
> 'inout' tells us that the variable is being used as input+output. 'in'  
> tells us it's input, which is what a pointer is passed as, "byref" adds 
>  nothing more, so no benefit there.
> 
> What does "byref" add that a pointer cannot?
> 
>> why is
>> void foo(inout A a) better than foo(A* a) when it does the sam thing?  
>> Except the first one is simpler to use and more informative of coders  
>> intentions.
> 
> Those are the reasons why 'inout' is better, can you say the same for  "byref"?
> 
>>>  void foo(byref A a) //tells us 'a' is input
>>> 
>>>> You can do the same with pointers. It is all about abstracting some   
>>>> concepts a little higher.
>>>   I think it's about:
>>>  - making the purpose of the parameter clear
>>>  - passing it in a way to facilitate that purpose.
>>> 
>> 
>> OK, it is all about that.
> 
> Well, that's just my opinion. I believe your "abstracting concepts a  
> little higher" is essentially my "making the purpose of the parameter  
> clear" or very similar.
> 
>>> I don't see how "byref" does either of those any better than a pointer   does.
>> 
>> Yes, I see you have a problem with pointers:
>> foo(int* a) tells you nothing
>> foo(inout int a) tells you something
>> 
>> but when it comes to structs you say pointers tells us 'a' is input.
>> But that is just crazy.
> 
> Only if you ignore the cases that 'out' and 'inout' represent. My 
> initial  example was of a world where 'out' and 'inout' do not exist, 
> the C world,  I was attemting to show what we all know, that 'out' and 
> 'inout' are  valuable because they achieve the goals:
>>>  - making the purpose of the parameter clear
>>>  - passing it in a way to facilitate that purpose.
> 
> and thus add value. From that I was attempting to show how "byref" 
> doesn't  achieve those goals, or rather that it doesn't improve on what 
> a pointer  does to achieve those goals in any way.
> 
> If you believe "byref" adds value can you tell me how?
> 
>> void foo(A* a)
>> {
>>    //I don't care what is in 'a', and I am assigning something to it
>>    //so it is definitly not input but output.
>>    a.<something> = somethingelse;
>>    a.<something> = somethingelse;
>>    a.<something> = somethingelse;
>> }
> 
> The same is true for a class reference. "byref" does not solve this 
> issue,  it adds nothing over a pointer WRT data protection.
> 
>>>> Pointers are a low level construct and people should maybe have an   
>>>> option not to use them to achieve pass by reference semantics.
>>>   It's commonly said that having 2 ways to do the same thing is a bad  idea.
>>> 
>> 
>> I' shouldn't even comment on this, but I will: then let's remove inout  
>> because it can be done with pointers.
> 
> If you're suggesting this, even in jest then my attempt to show that  
> 'inout' adds value whereas "byref" does not has failed.
> 
> My point is this: 'out' and 'inout' add value over a pointer in the 
> output  and input+output cases. "byref" does not add any value over a 
> pointer _in  the input case_ (which is where "byref" would be used).
> 
>>>>> You stated "pointers are vague" could you elaborate on  that, how   
>>>>> exactly is a pointer vague?
>>>> 
>>>> 
>>>> Byref vs. pointer is like class vs allocated part of memory plus a   
>>>> couple of functions that think they are doing something usefull to  
>>>> that  part of memory, but we don't say we don't need classes.
>>>   I'm not sure what you're saying here.
>> 
>> I'm saying that int the end evrything can be done another way. You 
>> could  program everything in for example assembler, without having 
>> classes,  inout, delegates and other stuff but achieving the same 
>> effect.
> 
> Of course, but, and here is the point I am trying to make. We do things 
> in  different ways because they are "better", correct? I do not believe 
>  "byref" is "better" than a pointer in the "input" case. 'out' and 
> 'inout'  are certainly better in the output and input+output cases, 
> thus why we use  them.
> 
>>>> Pointers are sometimes a usefull thing to have, but refereneces are   
>>>> often enough. To pass a pointer to a function you have to take the   
>>>> adress of what you are passing,
>>>   True.
>>> 
>>>> and in the function you need to dereference a pointer to get to the   
>>>> thing it is pointing at.
>>>   Lets examine this shall we. On the face of it, it's perfectly  
>>> correct,  however lets consider the scenarios:
>>>  'int'
>>> void foo(int a)       //input
>>> void foo(out int a)   //output
>>> void foo(inout int a) //input and output
>>>  no need for pointers here so no need to dereference 'a'.
>>>  'struct A'
>>> void foo(A* a)       //input
>> 
>> Again that same assumption, why do you trust the writer of 'foo' that  
>> much? Did you write it? I wouldn't even trust myself that I'm using 'a' 
>>  only as input. :)
> 
> There is no difference here between an "A*" and a class reference. Do 
> you  trust this function:
> 
> class B {}
> void foo(B b) {} //input
> 
> Without some sort of data protection there is no way to guarantee the  
> function writer won't modify the data referenced by either 'a' or 'b',  
> but, what does that have to do with "byref" it doesn't solve that 
> problem  and more than a pointer does.
> 
>>> void foo(out A a)   //output
>>> void foo(inout A a) //input and output
>>>  in the case using a pointer, there is no need to dereference 'a'  
>>> because D  allows us to use '.' on the pointer to access the members.  
>>> The only time  you'd dereference 'a' is to get the address of the  
>>> structure.
>> 
>> Ups. Forgot that :)
> 
> Some of the best things about D are the simplest, the '.' operator  
> everywhere is one of them :)
> 
> Regan





More information about the Digitalmars-d mailing list