On Tue, 06 Mar 2012 05:11:34 -0500, Timon Gehr <timon.g...@gmx.ch> wrote:

On 03/06/2012 12:27 AM, Steven Schveighoffer wrote:
...

There are two parts to inout, one is that it can be one function called
3 different ways, the other is that you know it's constant during
function execution. Some people like that second part, even if it
doesn't fully guarantee everything. I.e. there's a reason people use
const in C++ besides it being trendy.


By passing a delegate that changes an inout-matched argument it is made explicit that inout data may change. Technically, none of the existing guarantees are lost, we just add some expressiveness to the type system.

Yes, I understand that it works. I know that it doesn't violate technically any const guarantees.

In fact, I think this is valid D code:

int i;
const int *pi = &i;
int *p = cast()pi;
*p = 5; // legal because I know this points at i, and i is really mutable

But from an API point of view, I look at at inout as guaranteeing anything the parameter points at won't change while inside the function *using that parameter*. Even though it's legal, it's disingenuous (at least as long as we define inout that way).

An interesting side note is that inout (if designed in this way) can allow the above code snippit to be modularized.




I'm not saying we cannot bend the rules to allow for this, because
clearly it doesn't violate the "true" constancy type of the data passed
in, but I don't think it's a straightforward change conceptually. I'm
not a compiler writer, so I don't know how this works in their minds,
I'd like to have their input.

Implementation of what you propose should be quite simple. The issue
is with the design, i.e. allowing both tying the inout in the delegate
parameter signature to the inout in the enclosing signature and having
an independent inout delegate parameter needs workable syntax.

I think it can be done:

1. determine inout match based on existing rules, excluding delegate
parameters.
2. change delegate parameter inouts to matched value.
3. Use implicit delegate conversion (using contravariance) to allow
passing delegates of proper type.

For example:

void foo(inout(int)* x, void delegate(inout(int)* y) dg);

void main()
{
int mx;
immutable int ix;
const int cx;

void bar1(int *mp) {}
void bar2(immutable(int) *ip) {}
void bar3(const(int) *cp) {}
void bar4(inout(int) *iop) {}

// inout matched as mutable due to mx, signature becomes void foo(int
*x, void delegate(int *y) dg);
foo(&mx, &bar1); // fine, direct match of both parameters
foo(&mx, &bar2); // not fine, immutable delegate does not implicitly
convert to mutable
foo(&mx, &bar3); // fine, const delegate can implicitly convert to mutable foo(&mx, &bar4); // fine, inout delegate can implicitly convert to mutable

// signature becomes void foo(immutable(int) *x, void
delegate(immutable(int) *y) dg);
foo(&ix, &bar1); // error
foo(&ix, &bar2); // ok
foo(&ix, &bar3); // fine, const delegate can implicitly convert to
immutable
foo(&ix, &bar4); // fine, inout delegate can implicitly convert to
immutable

// signature becomes void foo(const(int) *x, void delegate(const(int)
*y) dg);
foo(&cx, &bar1); // error
foo(&cx, &bar2); // error
foo(&cx, &bar3); // ok
foo(&cx, &bar4); // ok

// etc...
}

I understand, but how would you support this use case?:

inout(int)[] foo(inout(int)[] delegate(inout(int)[] dg), inout(int)[] arr){
     int[] x = dg(new int[16]);
     immutable(int)[] y = dg(new immutable(int)[16]);
     // ...
     inout(int)[] z = dg(arr);
     return foo(z,y,z);
}

As usual, you find and poke holes in all my arguments :) I'm thinking that in order to make this work we need a way to specify an inout modifier really represents the matched type rather than a full-fledged inout parameter.

This is not a good thing -- inout is already pretty weird and hard to understand.

Need to do some more thinking, maybe there's an easy way.

Note that Walter has explicitly rejected contravariance conversion for
delegates.

That is unfortunate.

You have good persuasive skills, maybe you can help :) See
bug http://d.puremagic.com/issues/show_bug.cgi?id=3180 and
http://d.puremagic.com/issues/show_bug.cgi?id=3075


IIRC Kenji Hara has already started attempts to loosen the restrictions regarding delegate implicit conversions. Hopefully Walter will reconsider.

I hope so.  This is a vastly awesome untapped low-hanging fruit.

-Steve

Reply via email to