inout and function/delegate parameters

Steven Schveighoffer schveiguy at yahoo.com
Fri Feb 24 08:26:21 PST 2012


On Sun, 19 Feb 2012 09:27:42 -0500, Stewart Gordon <smjg_1998 at yahoo.com>  
wrote:

> At the moment, if a function has an inout parameter, it must have an  
> inout return type.
>
> But this prevents doing stuff like
>
>      void test(ref inout(int)[] x, inout(int)[] y) {
>          x = y;
>      }

This is a legitimate request, I think there is an effort underway by  
myself Timon and Kenji to make this work.  (well mostly Kenji and Timon)

> or passing the constancy through to a delegate instead of a return value.
>
> A typical use case of the latter is to define an opApply that works  
> regardless of the constancy of this and allows the delegate to modify  
> the iterated-through objects _if_ this is mutable.
>
>      int opApply(int delegate(ref inout(T)) dg) inout;

What you ask isn't possible given the current design of inout.  During  
inout function execution, inout is a special form of const, even if the  
object on which opApply is being called is mutable.

> But then I realised a potential ambiguity:
> (a) the constancy is passed through to the delegate
> (b) the delegate has an inout parameter in its own right
>
> If we go by interpretation (b), then each signature contains only one  
> inout, so even if we relaxed the rules to allow this it would just be  
> equivalent to
>
>      int opApply(int delegate(ref const(T)) dg) const;

Yes, this is what I think it should be equivalent to.  As I said, inside  
opApply, inout is like const, and is transitive.  So you cannot  
"temporarily" make it mutable.

> however, this won't always be true in the general case.
>
> The essence of functions with inout parameters is that they have a  
> hidden constancy parameter.  This is essentially a template parameter,  
> except that only one instance of the function is generated, rather like  
> Java generics.  If we made this parameter explicit in the code, we could  
> distinguish the two meanings:

No the constancy is not a parameter  (not even a hidden one).  The magic  
of inout happens at the call, not inside the function.  Inside, it's just  
another type of const.

However, there is an entire part of delegates that is yet untapped --  
implicit conversion of delegates.  For example, int delegate(ref const int  
x) could be implicitly converted to int delegate(ref int x).  Maybe there  
is something there that can be used to solve this problem.  Maybe there is  
a rule we could apply when calling an inout-enabled function that allows  
implicit conversion of a delegate to an inout -flavored version of the  
delegate (as long as the normal delegate matches the decided inout  
constancy factor).  But that violates transitivity.  I'm not sure Walter  
would go for this.

-Steve


More information about the Digitalmars-d mailing list