Jump to page: 1 2 3
Thread overview
ref arguments
Sep 21, 2009
#ponce
Sep 22, 2009
#ponce
Sep 22, 2009
Jeremie Pelletier
Sep 21, 2009
Jeremie Pelletier
Sep 21, 2009
Jeremie Pelletier
Sep 21, 2009
Jeremie Pelletier
Sep 21, 2009
Bill Baxter
Sep 21, 2009
Saaa
Sep 21, 2009
Jeremie Pelletier
Sep 22, 2009
Saaa
Sep 22, 2009
Jeremie Pelletier
Sep 22, 2009
Saaa
Sep 22, 2009
Jeremie Pelletier
Sep 29, 2009
Saaa
September 21, 2009
Is there a reason to use ref instead of in, inout or out ? I'm using D1 and it's not in the spec.


September 21, 2009
On Mon, Sep 21, 2009 at 11:12 AM, #ponce <aliloko@gmail.com> wrote:
> Is there a reason to use ref instead of in, inout or out ? I'm using D1 and it's not in the spec.

'ref' and 'inout' are identical. 'ref' was introduced after D1 was finalized for future expansion - 'inout' return values don't make much sense.
September 21, 2009
On Mon, 21 Sep 2009 11:12:49 -0400, #ponce <aliloko@gmail.com> wrote:

> Is there a reason to use ref instead of in, inout or out ?
> I'm using D1 and it's not in the spec.

ref and inout are synonymous, ref is preferred, as inout is essentially a defunct keyword.

in means that it's a reference that cannot be changed.  In D1, it means you cannot change the value, but if the value contains a reference to something else (like an array), you can change what it points to.  In D2, it is synonymous with ref const scope (although the scope attribute doesn't yet mean anything), so you cannot change anything it points to.

out means that it's a reference that you are always going to overwrite.  I believe the compiler even initializes the value for you upon function entry.

So in summary:

inout: don't use it.
ref: Use this for pass by reference for a value that you may or may not change.
in: Use this for pass by reference for a value that you won't change
out: Use this for pass by reference for a value that you will *always* change.

-Steve
September 21, 2009
On Mon, Sep 21, 2009 at 11:43 AM, Steven Schveighoffer <schveiguy@yahoo.com> wrote:

> in means that it's a reference that cannot be changed.  In D1, it means you cannot change the value, but if the value contains a reference to something else (like an array), you can change what it points to.

> in: Use this for pass by reference for a value that you won't change

No, sorry, this is wrong. In D1, 'in' is the default (pass by value)
and does nothing.
September 21, 2009
On Mon, 21 Sep 2009 11:51:28 -0400, Jarrett Billingsley <jarrett.billingsley@gmail.com> wrote:

> On Mon, Sep 21, 2009 at 11:43 AM, Steven Schveighoffer
> <schveiguy@yahoo.com> wrote:
>
>> in means that it's a reference that cannot be changed.  In D1, it means you
>> cannot change the value, but if the value contains a reference to something
>> else (like an array), you can change what it points to.
>
>> in: Use this for pass by reference for a value that you won't change
>
> No, sorry, this is wrong. In D1, 'in' is the default (pass by value)
> and does nothing.

Oh, that's... um useless...  Pardon me for thinking it meant something ;)

I'm pretty sure it means something in D2 though.

-Steve
September 21, 2009
Steven Schveighoffer wrote:
> On Mon, 21 Sep 2009 11:51:28 -0400, Jarrett Billingsley <jarrett.billingsley@gmail.com> wrote:
> 
>> On Mon, Sep 21, 2009 at 11:43 AM, Steven Schveighoffer
>> <schveiguy@yahoo.com> wrote:
>>
>>> in means that it's a reference that cannot be changed.  In D1, it means you
>>> cannot change the value, but if the value contains a reference to something
>>> else (like an array), you can change what it points to.
>>
>>> in: Use this for pass by reference for a value that you won't change
>>
>> No, sorry, this is wrong. In D1, 'in' is the default (pass by value)
>> and does nothing.
> 
> Oh, that's... um useless...  Pardon me for thinking it meant something ;)
> 
> I'm pretty sure it means something in D2 though.
> 
> -Steve

'in' means 'const scope' in D2, which is using pass-by-value semantics.

I myself stay out of 'ref' and 'out' params since they do not yet optimize and add quite a lot of overhead making temporary "safe" copies of the data.

Also 'scope' params have a meaning, when a delegate parameter is declared as scope, it allows a closure to use stack storage instead of the usual heap storage.
September 21, 2009
On Mon, 21 Sep 2009 12:23:46 -0400, Jeremie Pelletier <jeremiep@gmail.com> wrote:

> Steven Schveighoffer wrote:
>> On Mon, 21 Sep 2009 11:51:28 -0400, Jarrett Billingsley <jarrett.billingsley@gmail.com> wrote:
>>
>>> On Mon, Sep 21, 2009 at 11:43 AM, Steven Schveighoffer
>>> <schveiguy@yahoo.com> wrote:
>>>
>>>> in means that it's a reference that cannot be changed.  In D1, it means you
>>>> cannot change the value, but if the value contains a reference to something
>>>> else (like an array), you can change what it points to.
>>>
>>>> in: Use this for pass by reference for a value that you won't change
>>>
>>> No, sorry, this is wrong. In D1, 'in' is the default (pass by value)
>>> and does nothing.
>>  Oh, that's... um useless...  Pardon me for thinking it meant something ;)
>>  I'm pretty sure it means something in D2 though.
>>  -Steve
>
> 'in' means 'const scope' in D2, which is using pass-by-value semantics.

Yes, you are right.  I can't see the benefit to it, so I guess my recommendation is not to ever use in (use const instead).

> I myself stay out of 'ref' and 'out' params since they do not yet optimize and add quite a lot of overhead making temporary "safe" copies of the data.

I understand the problem behind not optimizing  (inline), but I'm not sure what you mean by making temporary "safe" copies.

> Also 'scope' params have a meaning, when a delegate parameter is declared as scope, it allows a closure to use stack storage instead of the usual heap storage.

yes, but in the context of an 'in' parameter, most of the time you are not passing a delegate using in, so scope doesn't mean much there.

-Steve
September 21, 2009
Steven Schveighoffer wrote:
> On Mon, 21 Sep 2009 11:12:49 -0400, #ponce <aliloko@gmail.com> wrote:
>
>> Is there a reason to use ref instead of in, inout or out ? I'm using D1 and it's not in the spec.

It is here in the spec: Function Parameters http://www.digitalmars.com/d/1.0/function.html

>
> ref and inout are synonymous, ref is preferred, as inout is essentially a defunct keyword.
>
> in means that it's a reference that cannot be changed.  In D1, it means you cannot change the value, but if the value contains a reference to something else (like an array), you can change what it points to.

The spec says: (http://www.digitalmars.com/d/1.0/function.html)
"For dynamic array and object parameters, which are passed by reference,
in/out/ref apply only to the reference and not the contents."
And: (http://www.digitalmars.com/d/1.0/abi.html)
"When passing a static array to a function, the result, although declared as
a static array, will actually be a reference to a static array."

Shouldn't it thus be:
"For array and object parameters, which are passed by reference..."
??

My interpretation for:
   void  func(in/out/ref int[10]arr)
"in" arr is a new reference pointing to the passed array.
"out" arr is a new array of 10 ints initialized to 0.
"ref" arr is the original reference you passed
Same for dynamic arrays/objects.

> In D2,  it is synonymous with ref const scope (although the scope attribute  doesn't yet mean anything), so you cannot change anything it points to.
>
> out means that it's a reference that you are always going to overwrite.  I believe the compiler even initializes the value for you upon function entry.
>
> So in summary:
>
> inout: don't use it.
> ref: Use this for pass by reference for a value that you may or may not
> change.
> in: Use this for pass by reference for a value that you won't change
> out: Use this for pass by reference for a value that you will *always*
> change.
What do you mean by: "pass by reference for a value"?
It reads like it creates a reference to a value.
in and out don't create a reference, do they?


My interpretation for:
   void  func(in/out/ref int i)
"in" i is a new int initialized to the passed int.
"out" i is a new int set to 0.
"ref" i is a reference to the original passed int?

Are my interpretations correct??
Anyways, I think this deserves a bit more explaination in the spec.
Ref is never explained.

>
> -Steve


September 21, 2009
Steven Schveighoffer wrote:
> On Mon, 21 Sep 2009 12:23:46 -0400, Jeremie Pelletier <jeremiep@gmail.com> wrote:
> 
>> Steven Schveighoffer wrote:
>>> On Mon, 21 Sep 2009 11:51:28 -0400, Jarrett Billingsley <jarrett.billingsley@gmail.com> wrote:
>>>
>>>> On Mon, Sep 21, 2009 at 11:43 AM, Steven Schveighoffer
>>>> <schveiguy@yahoo.com> wrote:
>>>>
>>>>> in means that it's a reference that cannot be changed.  In D1, it means you
>>>>> cannot change the value, but if the value contains a reference to something
>>>>> else (like an array), you can change what it points to.
>>>>
>>>>> in: Use this for pass by reference for a value that you won't change
>>>>
>>>> No, sorry, this is wrong. In D1, 'in' is the default (pass by value)
>>>> and does nothing.
>>>  Oh, that's... um useless...  Pardon me for thinking it meant something ;)
>>>  I'm pretty sure it means something in D2 though.
>>>  -Steve
>>
>> 'in' means 'const scope' in D2, which is using pass-by-value semantics.
> 
> Yes, you are right.  I can't see the benefit to it, so I guess my recommendation is not to ever use in (use const instead).

I disagree, I have different uses for both. I use 'in' when the reference will not leave the function's scope and const when it does. Both are immutable views on the data but with different usage semantics. The different semantics aren't yet implemented in D2 but they are most useful to determine whether I can, for example, decide whether to send a slice (to in parameters) or a copy (to const parameters).

>> I myself stay out of 'ref' and 'out' params since they do not yet optimize and add quite a lot of overhead making temporary "safe" copies of the data.
> 
> I understand the problem behind not optimizing  (inline), but I'm not sure what you mean by making temporary "safe" copies.

Right now the compiler makes a temporary copy of referenced parameters on the stack, calls the function with a pointer to the stack copy, and once the function returns copies the modified temporary back to its original location. This is quite considerable overhead.

>> Also 'scope' params have a meaning, when a delegate parameter is declared as scope, it allows a closure to use stack storage instead of the usual heap storage.
> 
> yes, but in the context of an 'in' parameter, most of the time you are not passing a delegate using in, so scope doesn't mean much there.

The implied 'scope' in 'in' has no effect yet due to a current compiler bug. You have to explicitly use 'scope' when declaring delegate parameters. Just like the 'in' vs 'const' have different semantics, 'in' vs plain 'scope' also have different semantics, which should get fixed soon.

For example, consider the following:

void Foo(scope delegate() bar) { bar(); }
void Foo2(delegate() bar) { bar(); }

// This method uses stack storage, the implied scope in 'in' should also work here, but is bugged right now so explicit 'scope' is needed
void Test() {
    void Bar() {}
    Foo(&Bar);
}

// This method uses heap storage allocated on the GC through _d_allocmemory
// Notice how the only difference is the 'scope' qualifier of Foo2()
void Test2() {
    void Bar() {}
    Foo2(&Bar);
}

Jeremie
September 21, 2009
Saaa wrote:
> Steven Schveighoffer wrote:
>> On Mon, 21 Sep 2009 11:12:49 -0400, #ponce <aliloko@gmail.com> wrote:
>>
>>> Is there a reason to use ref instead of in, inout or out ?
>>> I'm using D1 and it's not in the spec.
> 
> It is here in the spec: Function Parameters
> http://www.digitalmars.com/d/1.0/function.html
> 
>> ref and inout are synonymous, ref is preferred, as inout is essentially a defunct keyword.
>>
>> in means that it's a reference that cannot be changed.  In D1, it means you cannot change the value, but if the value contains a reference to something else (like an array), you can change what it points to.
> 
> The spec says: (http://www.digitalmars.com/d/1.0/function.html)
> "For dynamic array and object parameters, which are passed by reference, in/out/ref apply only to the reference and not the contents."
> And: (http://www.digitalmars.com/d/1.0/abi.html)
> "When passing a static array to a function, the result, although declared as a static array, will actually be a reference to a static array."
> 
> Shouldn't it thus be:
> "For array and object parameters, which are passed by reference..."
> ??
> 
> My interpretation for:
>    void  func(in/out/ref int[10]arr)
> "in" arr is a new reference pointing to the passed array.
> "out" arr is a new array of 10 ints initialized to 0.
> "ref" arr is the original reference you passed
> Same for dynamic arrays/objects.

You cannot have static array be ref or out. You must use int[] arr instead and let the caller specify the length.

Array in D are already references to their data, it's a 8bytes (or 16bytes on x64) value containing a pointer and a length. So the following prototype:

void func(<none>/in/ref/out int[] arr);

would have the following semantics:

"<none>" copies the array reference, the referenced data is mutable. Modifying the local reference does not change the caller's reference.
"in" copies the array reference, the local reference AND the referenced data are immutable in the method's scope.
"ref" passes a reference to the caller's array reference, the referenced data is mutable. Modifying the local reference also changes the caller's reference.
"out" passes a reference to the caller's array reference. The referenced  array reference is zeroed and can be modified by the local reference.

If you want a mutable reference to an immutable view on the referenced data, use const(int)[], which can also be ref or out.

>> In D2,  it is synonymous with ref const scope (although the scope attribute  doesn't yet mean anything), so you cannot change anything it points to.
>>
>> out means that it's a reference that you are always going to overwrite.  I believe the compiler even initializes the value for you upon function entry.
>>
>> So in summary:
>>
>> inout: don't use it.
>> ref: Use this for pass by reference for a value that you may or may not change.
>> in: Use this for pass by reference for a value that you won't change
>> out: Use this for pass by reference for a value that you will *always* change.
> What do you mean by: "pass by reference for a value"?
> It reads like it creates a reference to a value.
> in and out don't create a reference, do they?
> 
> 
> My interpretation for:
>    void  func(in/out/ref int i)
> "in" i is a new int initialized to the passed int.
> "out" i is a new int set to 0.
> "ref" i is a reference to the original passed int?
> 
> Are my interpretations correct??
> Anyways, I think this deserves a bit more explaination in the spec.
> Ref is never explained.
> 
>> -Steve 
> 

"<none>" would be a mutable copy.
"in" would be immutable copy.
"out" is a reference to the caller's int initialized to 0.
"ref" is a reference to the caller's int.

"in" and "const" are only really useful with types which are already references, such as pointers, arrays and objects.

Jeremie
« First   ‹ Prev
1 2 3