Thread overview
Modifiable typesafe variadic arguments
Jun 15, 2006
Deewiant
Jun 15, 2006
Daniel Keep
Jun 15, 2006
Deewiant
Jun 15, 2006
BCS
Jun 16, 2006
Daniel Keep
June 15, 2006
Trying to do something like this doesn't work:

void foo(int[] arr...) {
	for (int i = 0; i < arr.length; ++i)
		arr[i] = 3;
}

foo(x, y, z);

The variables passed retain their original values. Defining arr as inout or out doesn't work, since that would be modifying the array reference, and as such the compiler doesn't allow it.

Is there any way of doing it other than using pointers, like in the following?

void foo(int*[] arr...) {
	for (int i = 0; i < arr.length; ++i)
		*arr[i] = 3;
}

foo(&x, &y, &z);

My guess is there isn't, since std.stream.InputStream.readf, for instance, uses pointers for this as well. Any ideas?
June 15, 2006

Deewiant wrote:
> Trying to do something like this doesn't work:
> 
> void foo(int[] arr...) {
> 	for (int i = 0; i < arr.length; ++i)
> 		arr[i] = 3;
> }
> 
> foo(x, y, z);
> 
> The variables passed retain their original values. Defining arr as inout or out doesn't work, since that would be modifying the array reference, and as such the compiler doesn't allow it.
> 
> Is there any way of doing it other than using pointers, like in the following?
> 
> void foo(int*[] arr...) {
> 	for (int i = 0; i < arr.length; ++i)
> 		*arr[i] = 3;
> }
> 
> foo(&x, &y, &z);
> 
> My guess is there isn't, since std.stream.InputStream.readf, for instance, uses pointers for this as well. Any ideas?

Not that I can find after a quick squiz at the docs.  Honestly, I think that when you ever pass something to a function that it can change, there should be some explicit notice of this (like having to pass the argument by address).

Well, ok, you could always play the "write a template for every possible argument length and use THAT to pass the arguments by address to the *real* function", but I think that's probably unnecessary :)

	-- Daniel

-- 
Unlike Knuth, I have neither proven or tried the above; it may not even make sense.

v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP  http://hackerkey.com/
June 15, 2006
Daniel Keep wrote:
> Honestly, I think that when you ever pass something to a function that it can change, there should be some explicit notice of this (like having to pass the argument by address).

I agree. Hence I still hope for my suggestion (which was originally someone else's idea, but I wrote it up at the D wish list, http://all-technology.com/eigenpolls/dwishlist/ ) requesting usage of explicit out/inout when calling to be implemented. Meaning, whenever you call a function with out/inout arguments, you specify out/inout at the call point as well as at the function definition.

> Well, ok, you could always play the "write a template for every possible argument length and use THAT to pass the arguments by address to the *real* function", but I think that's probably unnecessary :)
> 
> 	-- Daniel
> 

Of course, and I think that's unnecessary as well, not to mention somewhat tedious. ;-)
June 15, 2006
Deewiant wrote:
> Daniel Keep wrote:
> 
>>Honestly, I think that when you ever pass something to a function that it can
>>change, there should be some explicit notice of this (like having to pass the
>>argument by address).
> 
> 
> I agree. Hence I still hope for my suggestion (which was originally someone
> else's idea, but I wrote it up at the D wish list,
> http://all-technology.com/eigenpolls/dwishlist/ ) requesting usage of explicit
> out/inout when calling to be implemented. Meaning, whenever you call a function
> with out/inout arguments, you specify out/inout at the call point as well as at
> the function definition.
> 
> 
On that thought, what is the easiest way to pass a copy in an inout arg or a dummy for an out?

this would be the effect, but its a bit verbose.

int  foo(inout int i, out int j)
{
	j = i;
	i = 1;
	return i+j;
}
...
	int i=1, k;
...
	{	// don't care about i or j's returned value;
		int i_ = i, j_;
		k = foo(i_, j_);
	}
...

something like this would be nice:


...
	int i=1, k;
...
	k = foo(i.dup, auto);
...

	
June 16, 2006

BCS wrote:
> Deewiant wrote:
>> Daniel Keep wrote:
>>
>>> Honestly, I think that when you ever pass something to a function
>>> that it can
>>> change, there should be some explicit notice of this (like having to
>>> pass the
>>> argument by address).
>>
>>
>> I agree. Hence I still hope for my suggestion (which was originally
>> someone
>> else's idea, but I wrote it up at the D wish list,
>> http://all-technology.com/eigenpolls/dwishlist/ ) requesting usage of
>> explicit
>> out/inout when calling to be implemented. Meaning, whenever you call a
>> function
>> with out/inout arguments, you specify out/inout at the call point as
>> well as at
>> the function definition.
>>
>>
> On that thought, what is the easiest way to pass a copy in an inout arg or a dummy for an out?
> 
> this would be the effect, but its a bit verbose.
> 
> int  foo(inout int i, out int j)
> {
>     j = i;
>     i = 1;
>     return i+j;
> }
> ...
>     int i=1, k;
> ...
>     {    // don't care about i or j's returned value;
>         int i_ = i, j_;
>         k = foo(i_, j_);
>     }
> ...
> 
> something like this would be nice:
> 
> 
> ...
>     int i=1, k;
> ...
>     k = foo(i.dup, auto);
> ...

Or you could do what Visual Basic did: allow the programmer to pass an immediate value as an 'inout' or 'out' parameter: in which case, it stores the immediate value somewhere, calls the function, then discards the value.

I've always found it somewhat amusing that VB is the only language I've ever seen that allowed this nice little shortcut.  I can't decide if that's because it's a bad idea, or because it's just really hard to do.

Knowing VB, it's probably the former.

	-- Daniel

-- 
Unlike Knuth, I have neither proven or tried the above; it may not even make sense.

v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP  http://hackerkey.com/