On 02/24/2012 05:26 PM, Steven Schveighoffer wrote:
On Sun, 19 Feb 2012 09:27:42 -0500, Stewart Gordon <smjg_1...@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.


The call site has enough information to type check the call given that there is some syntax to tie the two inout qualifiers together. inout shouldn't imply const, we already have const for that.

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.


inout means 'some qualifier but we don't know which one'. The call site on the other hand knows which qualifier it is. If the call is made to work there is no 'making it mutable', because it is mutable all the time. The inout function cannot change the data because it cannot know what the constancy is.


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.

The same is (mostly) true for Java generics.

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.


Unfortunately this violates type safety. Also see:
http://d.puremagic.com/issues/show_bug.cgi?id=7542




Reply via email to