February 18, 2006
Derek Parnell wrote:
> If one passes the address of an int to a function, is it passing a  reference or value or data or what? Dumb question, no?

It is passing a pointer to int by value, and passing an int by reference at the same time. :)
February 19, 2006
On Sat, 18 Feb 2006 23:42:33 +0100, Ivan Senji <ivan.senji_REMOVE_@_THIS__gmail.com> wrote:
> Regan Heath wrote:
>> On Sat, 18 Feb 2006 12:44:28 +0100, Ivan Senji  <ivan.senji_REMOVE_@_THIS__gmail.com> wrote:
>>
>>> Regan Heath wrote:
>
> I'll reply to this post because it is shorter than the other one ;)

Good idea, we have sort of duplicated the effort in both places :)

>>>> Please elaborate. I don't see how this:
>>>>  struct A {}
>>>> void foo(A* p) {}
>>>>  is any more or less vague than this:
>>>>  struct A {}
>>>> void foo(byref A p) {}
>>>
>>>
>>> It is less vague. The problem is you see pointer as input, but it  obviously isn't.
>>   Given that we have 'out' for output, and 'inout' for input+output what  does that leave?
>
> Maybe pointer == input && output && input-output and what ever you want.

It can, that is true. I shouldn't because we have 'out' and 'inout'. No guarantees though.

> The good thing about inout is when writing generic code you don't have to know if you are dealing with a class or a struct or array or something else.

Agreed. "byref" would also benefit generic programming for the same reasons. A similar situation in the past resulted in template specialization being added and it should solve this problem also. I can't help but think that "byref" would be more elegant however.

> I am begining to think that byref would also have to mean compiler protecting the data from change, but then it is a C++ const story that Walter doesn't want in D.

Agreed. If "byref" could protect the data I would very much like to see it. In the past I suggested that 'in' default to protecting data to force the use of 'out' and 'inout' where appropriate. That disucssion resulted in the same conclusion, that it would require a fill 'const' like implementation and Walter wasn't ready for that, yet.

>>>>> Not only that, D set the precedent for new parameter passing syntax  with  in/inout/out and you need to break from that to use pointers.
>>>>
>>>>   'out' and 'inout' do replace the use of pointers (or passing by  reference)  for 2 cases of parameter, that is true. By I do not think  that constitutes  a precedent, it's simply a better way to handle each  of those cases. The  same cannot be said for "byref", it's not any  _better_ than a pointer.
>>>>
>>>
>>> It is, because pointer doesn't say input.
>>   There is only 1 case where it is needed. Passing a large struct by  reference, in this case what else can the use of a pointer mean?
>
> It could mean inout-but-i-come-from-c-and-really really like pointers
> :)

LOL.. yeah, you can't really guarantee anything can you.

>>  A pointer gives a reference to the struct. A reference much like a class  reference. So
>>  class B {}
>> void foo(B b) {}
>>  is 'b' not input? why not?
>
> Yes it is. But if you want a generic method that takes input parameter and write it like that, it means struct will be copyied, if you write it like (B* b) it means uglyfication of code. So conclusion: i have no idea what to do about it? Maybe just use inout in that case and fool everybody into thinking that the function changes something wich it doesn't.

For template programming "byref" would solve this nicely, without it template specialization is required, I guess.

Regan
February 19, 2006
On Sun, 19 Feb 2006 08:47:21 +1100, Derek Parnell <derek@psych.ward> wrote:
> On Sun, 19 Feb 2006 08:26:47 +1100, Regan Heath <regan@netwin.co.nz> wrote:
>
>> On Sat, 18 Feb 2006 23:15:10 +1100, Derek Parnell <derek@psych.ward> wrote:
>>> On Sat, 18 Feb 2006 18:18:05 +1100, Regan Heath <regan@netwin.co.nz> wrote:
>>>
>>> [snip]
>>>
>>>> To my mind a function taking a pointer, eg.
>>>>
>>>> struct A {}
>>>> void foo(A* ptr) {}
>>>>
>>>> says, takes a reference/pointer to an A. Isn't that what "byref" means?
>>>>
>>>> void foo(byref A ptr) {}
>>>>
>>>> So, if they mean the same thing, and they do the same thing... I prefer the pointer, it's known, it's shorter and easier to type, it exists already.
>>>
>>> The only difference I can suggest is that by using a pointer you are telling the compiler that any type of access to the referred to data is ok, but 'byref' could be saying that any attempt to change the data referred to is a mistake. The 'byref' is sugar for a pointer, true. But it adds to the compiler's understanding of the coder's intentions, namely that if the code uses 'ptr' to change the data then issue a message because it means that the coder has just made a coding mistake. The 'byref' idea can add value to the language.
>>
>> If data protection is added then I agree wholeheartedly.
>>
>> But at this stage we cannot be sure it will be, or even that it will take a form that can use "byref", so adding it might result in "another way to do the same thing" and nothing more, that is my concern.
>
> You seem to be saying that unless, and until, D can absolutely guarantee data protection then there is no value in trying to have the compiler also (in addition) detect coding mistakes of the type where the coder has expressed her desire to not attempt to change the data owned by a passed parameter, but due to an honest mistake, her code actually contains a construct that attempts to do just that *and* the compiler can detect that.
>
> (Sheesh! That has got to be the longest sentence I've ever written! <g>)

:)

I suspect for the compiler to detect the attempt to change it, a partial or complete 'const' like solution would have to be added. I don't think detecting an attempt to change it is easy, and I think that there may even be some cases which are impossible to detect (the same param passed twice, and/or several levels of indirection). Resulting in a system that works "most of the time".

Such a system might be of benefit, but I don't think Walter is convinced, I suspect he is hoping to come up with a solution that can provide a real guarantee.

In the meantime adding another method to pass a reference to a struct without any attempt at data protection seems to me to be "another way to do the same thing" and I don't really see the point. Although.. Ivan did point out that it would be useful in generic programming and I agree there.

> If this is so, then I must register my total disagreement. I hold to the idea that a major part of any compiler's job is to make life easier for coders.

I agree completely.

> One obvious way it can do that is to highlight code that is contrary to the coder's stated intentions.

I agree completely.

> The 'byref' idea could be used to declare that the intention of the coder is to not modify the parameter's data.

Currently 'in' serves that purpose. I believe the default passing method should be readonly. So, rather than "byref" I would like 'in' to enforce whatever data protection we eventually have.

However there is still the problem of seperating the 'reference' from the 'data' itself and being able to apply the usage to each part seperately, i.e. "not going to modify the referece, will modify the data" vs "not going to modify the reference or the data" etc.

Without some way to do that we're stuck passing class references as 'in' and it's not obvious what that means, or if it even means the same thing to everyone.

> This is very different to having the compiler make sure that every possible method of data protection is blocked. I'm just and only talking about explicit attempts to modify 'byref' parameter data. Such attempts mean that either the 'byref' was a mistake to add or that the code is a mistake - either way the coder is helped.

Such a solution would only catch things some percentage of the time, perhaps it's a large percentage, not sure. I think we'd all prefer a guaranteed method, if possible, it may not be. Either way it's (as always) in Walters hands.

Regan
February 23, 2006
On 2006-02-18 02:34:24 -0800, "Regan Heath" <regan@netwin.co.nz> said:

> Please elaborate. I don't see how this:
> 
> struct A {}
> void foo(A* p) {}
> 
> is any more or less vague than this:
> 
> struct A {}
> void foo(byref A p) {}

That's because that's not what I asked for.  I asked for something that was InByRef or whatever is agreed upon.    Just ByRef Is just as vague.

> 
>> Not only that, D set the precedent for new parameter passing syntax with  in/inout/out and you need to break from that to use pointers.
> 
> 'out' and 'inout' do replace the use of pointers (or passing by reference)  for 2 cases of parameter, that is true. By I do not think that constitutes  a precedent, it's simply a better way to handle each of those cases. The  same cannot be said for "byref", it's not any _better_ than a pointer.
> 
>> Thirdly D also set a precedent by treating pointers as a new type (D  changed declarations so that pointers are with the type rather than the  instance now.)
> 
> Pointers have always been a distinct type. The change D made was in how  the declaration of types is parsed, nothing more.
> 
>> Presuming that a int* is a different type
> 
> It is.
> 
>> , then what you are saying is that you want something other than an int  to manipulate. That's untrue though.
> 
> I'm not sure what you meant by this statement. Can you re-phrase please.

My argument is that asking for an Type* means you want to work on an Type*. Usually you just want to work on the Type, not actually it's location.

> 
>> So, when using a pointer in D you are doing a few things.  You are being  vague about what you do to the original value.
> 
> Not any more or less vague than a class reference. Both a pointer and a  class reference are passed 'in' and you cannot effect their value outside  the function call. Therefore the original reference/pointer is safe from  manipulation. In neither case is the content of the class/struct safe from  manipulation. eg.
> 
> struct A { int a; }
> class B  { int b; }
> 
> void foo(A* a) { a.a = 1; }
> void foo(B b)  { b.b = 1; }
> 
> void main()
> {
>    A a;
>    B b = new B();
>    foo(&a);
>    foo(b);
> }
> 
> the two cases above are essentially identical, both functions accept a  reference to the data type they wish to access, both references are passed  'in'. The only difference is that A is a value type and to get a reference  you must use a pointer.

Of course, I'm not arguing about that.  I want something that SAYS the structure is still being unmanipulated.  Whether walter could implement something like that or not is irrelevant to me.

> 
>> You also want to deal with a pointer to an int, and not actually an int.  While in some cases this is the case, most of the time all you wanted  was the value.
> 
> You have no need of pointers when passing an int:
>    - if you want to read it, you use 'in'.
>    - if you want to write to it, you use 'out'.
>    - if you want to read and write it, you use 'inout'.
> 
> In what case would you use "byref" with an 'int'? If you want to read,  write, or read+write it you'd use one of the existing modes in/out/inout,  right?

Of course, which is why my original message used a structure as an example.  You are indeed correct that it's useless for an int, since the storage required is the same for a pointer.

> 
>> Note that you can have parameters of type in that are pointers,  since  pointers are associated with variable types, and not passing method.
> 
> A pointer _is_ a variable type.

Indeed, which is why i want to define a passing method: "InRef"

-S.

February 23, 2006
On 2006-02-18 06:09:22 -0800, Bruno Medeiros <daiphoenixNO@SPAMlycos.com> said:

> S. Chancellor wrote:
>> On 2006-02-17 06:29:43 -0800, Bruno Medeiros <daiphoenixNO@SPAMlycos.com> said:
>> 
>>> S. Chancellor wrote:
>>>> On 2006-02-16 09:23:17 -0800, S. Chancellor <S._member@pathlink.com> said:
>>>>> 
>>>>> 
>>>>> It's interesting to note that classes passed via 'in' parameters are still
>>>>> passed by VALUE.  Not reference.
>>>>> 
>>>>> Just some food for thought.
>>>>> 
>>>>> -S.
>>>> 
>>>> Ignore my dipshit comment.  I ran my test incorrectly.
>>>> 
>>>> -S.
>>>> 
>>> No, what you said the first time is correct. What may be incorrect is your notion of value/reference types and their argument passing.
>> 
>> The point is the class is not passed by value.  The pointer to the class is passed by value.  What good is that?
>> 
> The class *is* the "pointer to the class". See my reply do Derek for more.

No it's not.  The "class" is a bunch of allocated data on the heap.  The pointer is just that, a pointer.  I have to agree with Derek on this one.

> 
>> -S.
>> 
>> P.S.  I have enough humility to admit my error, and you come back with a snide remark like that?  I don't even know you.
>> 
> Huh? My comment was not snide. I expressed my opinion in a direct and uninsulting way. If you do not agree, then tell me: how could have I said what I said, in a non-snide way?

You couldn't have, because your implication was snide.  You shouldn't have said it at all.

-S.

February 23, 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@netwin.co.nz> said:

> On Sat, 18 Feb 2006 12:35:39 +0100, Ivan Senji  <ivan.senji_REMOVE_@_THIS__gmail.com> wrote:
>> Regan Heath wrote:
>>> On Sat, 18 Feb 2006 11:21:27 +0100, Ivan Senji   <ivan.senji_REMOVE_@_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


February 24, 2006
Derek Parnell wrote:
> On Sun, 19 Feb 2006 04:29:50 +1100, Bruno Medeiros
> <daiphoenixNO@SPAMlycos.com> wrote:
>
>> In C++ the reference types are all explicit pointers, so it is more
>> clear what the values of the types are.
>>
>> This is the standard definition for a good reason. It is a more
>> simple/symmetric/orthogonal one (although the terminology is still
>> quite tricky).
>
> And by 'tricky' you mean 'stupid' right?
>
No.

> If one passes the address of an int to a function, is it passing a
> reference or value or data or what? Dumb question, no?
>
It is like Ivan said.

> --Derek Parnell
> Melbourne, Australia

> 
> 
> [snip]
> 
>> Here is the main point of contention. The value of a reference type is not it's referenced data, but it's reference/pointer itself. I.e. the value of a class variable is it's reference, not it's referenced instance data.
>>
>> .NET Common Type System Overview :
>> http://msdn.microsoft.com/library/en-us/cpguide/html/cpconcommontypesystemoverview.asp 
>>
>> "Values are binary representations of data, and types provide a way of interpreting this data. A value type is stored directly as a binary representation of the type's data. The value of a reference type is the location of the sequence of bits that represent the type's data."
>>
>> Java Types, Values, and Variables:
>> http://java.sun.com/docs/books/jls/second_edition/html/typesValues.doc.html 
>>
>> "The types of the Java programming language are divided into two categories: primitive types and reference types. [...] An object (ยง4.3.1) is a dynamically created instance of a class type or a dynamically created array. The values of a reference type are references to objects."
> 
> Welcome to the world of Alice. It seems that the good and intelligent people at Microsoft and Sun and taken perfectly good English word and redefined it to make it easier to sell their product. It like I gave you an ISBN and told you that I've really given you the book.
> 
> Ok, assuming their perverted definition of 'value', it boils down to saying that when passing parameters to a function, the function is getting something that enables the function to access the parameter's data. Really? Who would have guessed that!
> 
> Well, I'm afraid I'm continue to be a rebel and refuse to bow down to
> these mighty organizations and their mock-turtles.

Perverted definition of 'value'? That's very subjective and very arguable, and I disagree with it. I think the Java and C# engineers chose the appropriate definition, regardless of corporate interests (uh... in fact, how does a 'perverted' definition of value makes it any easier to sell their products at all?..).
*Actually*, saying they "chose" is misleading, because this is something that just immediately and naturally follows from the C/C++ language roots, and thus not even related to any possible corporate greediness. Indeed, and I regret not having remembered this earlier, in Kernighan and Ritchie's "The C Programming Language", it is said, is the first paragraph of page 99, that "By definition, the value of a variable or expression of type array is the address of element zero of the array.", so there ya go.

Anyway, I'm starting to get bit dizzy now.


-- 
Bruno Medeiros - CS/E student
"Certain aspects of D are a pathway to many abilities some consider to be... unnatural."
1 2 3 4 5 6 7 8 9
Next ›   Last »