February 18, 2006
On Fri, 17 Feb 2006 23:44:29 -0800, S. Chancellor <dnewsgr@mephit.kicks-ass.org> wrote:
> On 2006-02-17 19:49:59 -0800, "Regan Heath" <regan@netwin.co.nz> said:
>
>>> If that's what you want to read...
>>  I was asking for clarification by stating the argument as I read it.
>
> No, you stated my argument in and altered form.

That's what I just said. :)

> I stated:
> "D has an ever expanding plethora of features which are useless to  quite  a few people. "
> Note the choosing of the phrase: "Quite a few people."  Note that I did not say "All People."

Sure, I missunderstood your original statement, you've restated it below so I'll go with that one.

> My argument is that while complex features which I will never use, such as complex types,
> are in D, while some sort of "inref" which is much simpler to add is not.

My objection to "byref" is that it adds nothing that pointers don't already give us. You stated "pointers are vague" could you elaborate on that, how exactly is a pointer vague?

If "byref" adds nothing then it doesn't really matter how simple it is, there would be no point in adding it, right?

>>> I said there are plenty of features that are useful to quite a few  people.
>>  No you didn't, you said the opposite:
>>>>> D has an ever expanding plethora of features which are useless to  quite  a few people.
>
> That was supposed to read:
> I said there are plenty of features that are NOT useful to quite a few  people.

NP.

>>  Then you went on to say:
>>>>> More being added by the minute, why not a simple aliased  keyword?
>>  which suggested to me that you were saying "one more useless feature can't  hurt" or similar. If that was not your intention, sorry, that is how I  read it.
>
> See above to what I said.  You implied something other than what I said by rephrasing my argument and then you tried to get me to agree with the rephrased and incorrect statement.

I was simply trying to understand the reasoning behind your statement. I was trying to trick you into anything.

>>> This one is apparently useless to you.
>>  My position is that it's totally useless, it adds nothing a pointer does  not already give us.
>
> It's either totally useless, or it's your opinion, not both.

I have no idea what you mean here. My opinion is that "byref" adds nothing of value.

Regan
February 18, 2006
On Sat, 18 Feb 2006 23:07:32 +1300, Regan Heath <regan@netwin.co.nz> wrote:
> I was simply trying to understand the reasoning behind your statement. I was trying to trick you into anything.

"was" == "wasn't" :) freud would have a field day.

Regan
February 18, 2006
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. You can do the same with pointers. It is all about abstracting some concepts a little higher. Pointers are a low level construct and people should maybe have an option not to use them to achieve pass by reference semantics.

> 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.

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, and in the function you need to dereference a pointer to get to the thing it is pointing at. All this is something a compiler can do for us if we had in-by-reference.
February 18, 2006
On Fri, 17 Feb 2006 23:58:54 -0800, S. Chancellor <dnewsgr@mephit.kicks-ass.org> wrote:
> On 2006-02-17 19:58:09 -0800, "Regan Heath" <regan@netwin.co.nz> said:
>
>> On Fri, 17 Feb 2006 18:48:49 +0000 (UTC), S. Chancellor  <S._member@pathlink.com> wrote:
>>> In article <op.s44i7ehj6b8z09@ginger.vic.bigpond.net.au>, Derek Parnell  says...
>>>>  The original poster, I think, was just saying it would be useful to have
>>>> another option available for those things that are currently passed by
>>>> value, and that option being that we can specify that instead of being
>>>> passed by value that we want it to be passed by reference *and* that we
>>>> don't want to use pointer notation to do that.
>>>  Being the original poster, I can say this is almost exactly what I meant!
>>> At least someone understands what I was talking about!
>>  I have understood what you're suggesting since your original post, my only  problem is that "byref" seems to be a duplication of what a pointer gives  us for no benefit.
>>
>>> Also, I was stating not only that we don't want to use pointers, but we  also don't want to use inout, because inout means we're going to change  the value.
>>  I agree we certainly don't want 'inout' but what reason do you have for  not using a pointer?
>
> Because pointers are vague!

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) {}

> 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.

> 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.

> 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?

> 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.

Regan
February 18, 2006
On Sat, 18 Feb 2006 00:01:37 -0800, S. Chancellor <dnewsgr@mephit.kicks-ass.org> wrote:
> On 2006-02-17 23:20:14 -0800, "Regan Heath" <regan@netwin.co.nz> said:
>
>> On Sat, 18 Feb 2006 20:18:05 +1300, Regan Heath <regan@netwin.co.nz> wrote:
>>> On Sat, 18 Feb 2006 16:35:40 +1100, Derek Parnell <derek@psych.ward>  wrote:
>>>> On Sat, 18 Feb 2006 14:56:47 +1100, Regan Heath <regan@netwin.co.nz>  wrote:
>>>>
>>>>> On Sat, 18 Feb 2006 02:41:28 +1100, Derek Parnell <derek@psych.ward>  wrote:
>>>>>> The original poster, I think, was just saying it would be useful to  have another option available for those things that are currently  passed by value, and that option being that we can specify that  instead of being passed by value that we want it to be passed by  reference *and* that we don't want to use pointer notation to do that.
>>>>>  What I want to know is why not use a pointer?
>>>>  I'm probably reading into this, but maybe what's being requested is a  special sort of pointer. One that allows you to use it to fetch data  with, but does not allow to use it to store data. In other words, one  that (pretends?) to point to read-only RAM.
>>>  I believe we've been there before and discovered that it's simply not  possible to implement this, or rather that Walter could implement  C++ "const" but is not happy that C++ "const" actually solves the  problem. That a partial solution doesn't cover enough, or not enough for  many people.
>>>  I thought we'd come to that conclusion (again) in this thread. And that  "byref" was being proposed regardless. Am I mistaken?
>>  To clarify. My impression of the proposal is that "byref" would cause a  value type to be passed by reference and that it would not guarantee or  attempt any protection whatsoever.
>
> That is correct.  That's not to say that protections would be unwelcomed if they were implementable, or good ones could be defined.

Thanks for clarifying. Lets continue in the other 2 threads.

Regan
February 18, 2006
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

cannot be improved by "byref", how does "byref" make the above better? eg.

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.

I don't see how "byref" does either of those any better than a pointer does.

> 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.

>> 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.

> 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
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. In the case where you actually want the address of the structure you have to use a pointer because "byref" will not give you that value.

> All this is something a compiler can do for us if we had in-by-reference.

It is something the compiler is already doing for us with pointers.

Regan
February 18, 2006
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.

> 
> cannot be improved by "byref", how does "byref" make the above better? eg.

The same way inout is better than *

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.

> 
> 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.

> 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.

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;
}

> 
>> 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.

>>> 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.

> 
>> 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. :)

> 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 :)

> In the case  where you actually want the address of the structure you have to use a  pointer because "byref" will not give you that value.
> 
>> All this is something a compiler can do for us if we had in-by-reference.
> 
> 
> It is something the compiler is already doing for us with pointers.

Again: no it isn't.
February 18, 2006
Regan Heath wrote:
> 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.

> 
>> 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.
February 18, 2006
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.


-- 
Derek Parnell
Melbourne, Australia
February 18, 2006
Derek Parnell wrote:
> On Sat, 18 Feb 2006 01:28:01 +1100, Bruno Medeiros
> <daiphoenixNO@SPAMlycos.com> wrote:
>
>> Derek Parnell wrote:
>>> This topic doesn't warrant further consideration.
>>>
>> Huh, why? I barely said anything, and I find the above mentioned
>> comment relevant.
>
> Because we, and others, have been saying the same things over and over
> again without resolution or advancement. None of these discussions is
> going to change D.
>
> The 'in' qualifier [...]
Ah, I thought you were talking about my comment. My comment was not actually related to this thread's topic.

[...]
>> And also: *all* variables in D are by default passed by value, including classes and arrays. What happens is that they are reference values. This   conceptualization may look similar, but it's not, and it's a very important notion to have.
> 
> That is very wrong.
> 
> When passing a class instance, the data which is owned by that object is not passed (its value) but as you say, an address of a RAM structure that represents the object is passed (its reference). The 'reference' is not the 'value'.
> 
> When passing an array, the bits that go in into making the value of the data that is owned by the array is not passed (its value) but an address of an 8-byte structure (in the case of variable length arrays) or the address of the data (in the case of fixed length arrays) is passed (its reference). The 'reference' is not the 'value'.
> 
Yes, of course. Note that we both know correctly how the gears work, our
divergence lies only in the terminology, see below:

> So, some things are passed by reference (which is not its value) and some things are passed by value (which is not its reference).
> 
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."

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). It allows one to say that assignments work on the variable's value, for any type. It allows one to say that all variables/parameters in D (or any C-family language) are by default passed by value (or called-by-value). And conversely that  "inout" or "out" in D, "type &" in C++, "ref" and "out" in C# make a parameter passed by reference (or called-by-reference).
(http://en.wikipedia.org/wiki/Call_by_reference#Call_by_value)
(http://en.wikipedia.org/wiki/Call_by_reference#Call_by_reference)

So, looking back at what you said before, that class instance data(aka object data) is passed by reference. In a way it is right in that it is "... by reference" but the problem is that a class instance data is not "passed" at all. There are no variables types (and thus no parameters) of the kind "class instance data" (unlike C++). There are only reference types, which, like all other variables are passed by value.

It's a tricky duality.


-- 
Bruno Medeiros - CS/E student
"Certain aspects of D are a pathway to many abilities some consider to
be... unnatural."