Generic collection/element function signatures in D2 versus D1

Steven Schveighoffer schveiguy at yahoo.com
Wed Sep 8 10:14:54 PDT 2010


On Wed, 08 Sep 2010 12:38:44 -0400, Pelle <pelle.mansson at gmail.com> wrote:

> On 09/08/2010 02:24 PM, Steven Schveighoffer wrote:
>> On Tue, 07 Sep 2010 14:06:58 -0400, Steven Schveighoffer
>> <schveiguy at yahoo.com> wrote:
>>
>>> On Tue, 07 Sep 2010 11:37:20 -0400, Pelle <pelle.mansson at gmail.com>
>>> wrote:
>>>
>>>> On 09/07/2010 04:33 PM, Steven Schveighoffer wrote:
>>>>> Yes, a valid return. Your function should be:
>>>>>
>>>>> void foo(void delegate(const(C) f) const
>>>>>
>>>>> It helps to understand that inout/const/immutable has NOTHING to do
>>>>> with
>>>>> code generation, it only has to do with limiting what compiles. For
>>>>> this
>>>>> reason, an inout function is compiled once, and works on all three
>>>>> constancies (4 if you have a nested inout function). For the entire
>>>>> function any inout variable is treated as a non-changeable value,  
>>>>> just
>>>>> like const. Then when you return, it's converted at the call site  
>>>>> back
>>>>> to the constancy with which it was called. If the return value is  
>>>>> void,
>>>>> then there's nothing to convert, and no reason to use inout over  
>>>>> const.
>>>>>
>>>>> I'll repeat -- there is no benefit to inout if you are not returning
>>>>> anything.
>>>>>
>>>>> -Steve
>>>>
>>>> That's not an equivalent function signature. Or maybe it is, but look
>>>> at this (sorry it's so long):
>>>>
>>>> class C {
>>>> int x;
>>>> this(int y) { x = y; }
>>>>
>>>> inout(int*) foo() inout {
>>>> return &x;
>>>> }
>>>> void bar(void delegate(int*) f) {
>>>> f(&x);
>>>> }
>>>> void bar(void delegate(const(int*)) f) const {
>>>> f(&x);
>>>> }
>>>> void bar(void delegate(immutable(int*)) f) immutable {
>>>> f(&x);
>>>> }
>>>> }
>>>>
>>>> void main() {
>>>>
>>>> immutable(int)* wah;
>>>> void wahwah(immutable(int*) x) {
>>>> wah = x;
>>>> }
>>>> auto c = new immutable(C)(10);
>>>> wahwah(c.foo); // why is this privilegied with inout
>>>> c.bar(&wahwah); // and this not?
>>>>
>>>> writeln(*wah);
>>>>
>>>> }
>>>>
>>>> Can't use void delegate(const(int*)) there.
>>>
>>> Thanks for clarifying, I didn't quite understand the usage before.
>>>
>>> This is a limitation of inout's design. Technically inout requires a
>>> single inout output, and can have multiple inout inputs. Your example
>>> matches that description, so in theory it's possible.
>>
>> I realized last night that this won't work. Simple reason -- during an
>> inout function, the function promises to treat the arguments as if they
>> were const.
>>
>> If your class instance was mutable, this would not be true, e.g.:
>>
>> class C
>> {
>> int x;
>> void bar(void delegate(inout(int)* f) inout { f(&x); }
>> }
>>
>> void main() {
>>
>> auto c = new C;
>> void dg(int *f) {*f = 10;}
>> c.bar(&dg); // modifies c, even though the function is marked as inout
>> }
>>
>> -Steve
>
> Well, inout was conceived as a counter to where you need to write the  
> exact same function for every type of constness, was it not? :-)

Not exactly, it was conceived as a solution for the case where you would  
normally write a const function, but you don't want it to alter your const  
contract with the object in question.  Basically, you want a function that  
promises not to alter the parameters, but gives you back one of your  
parameters or a portion of one of them in the same constancy you pass in.   
The classic example is a property getter.

If you are not returning a portion of the input, then you can use const  
instead.

-Steve


More information about the Digitalmars-d-learn mailing list