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