www.digitalmars.com         C & C++   DMDScript  

D - foreach using "in" rather than "inout"?

reply "Matthew Wilson" <matthew stlsoft.org> writes:
In the KeySequence class I have the following apply() function defined:

    int apply(int delegate(inout  Key key) dg);

and in the client code I have the foreach statement:

    foreach(Key key; classesRoot.get_SubKeys())


But it is not appropriate for the delegate to be inout. However, if I define

    int apply(int delegate(in  Key key) dg);

I get :

    win32_reg_test.d(15): function apply (int delegate(Key key)dg) does not
match argument types (int delegate(inout Key __applyArg))

And trying

    foreach(Key in key; classesRoot.get_SubKeys())

or

    foreach(in Key key; classesRoot.get_SubKeys())


doesn't help. Any ideas? (I'm sure I'm doing something dumb :))

Matthew
Sep 13 2003
parent reply "Walter" <walter digitalmars.com> writes:
"Matthew Wilson" <matthew stlsoft.org> wrote in message
news:bk0qpo$6en$1 digitaldaemon.com...
 In the KeySequence class I have the following apply() function defined:

     int apply(int delegate(inout  Key key) dg);

 and in the client code I have the foreach statement:

     foreach(Key key; classesRoot.get_SubKeys())


 But it is not appropriate for the delegate to be inout. However, if I

     int apply(int delegate(in  Key key) dg);

 I get :

     win32_reg_test.d(15): function apply (int delegate(Key key)dg) does

 match argument types (int delegate(inout Key __applyArg))

 And trying

     foreach(Key in key; classesRoot.get_SubKeys())

 or

     foreach(in Key key; classesRoot.get_SubKeys())


 doesn't help. Any ideas? (I'm sure I'm doing something dumb :))

The delegate must be declared with inout (so the same apply() function can work with both inout and in foreaches). But the foreach does not, just leave off the 'in' and it should work fine.
Sep 13 2003
parent reply "Matthew Wilson" <matthew stlsoft.org> writes:
 The delegate must be declared with inout (so the same apply() function can
 work with both inout and in foreaches). But the foreach does not, just

 off the 'in' and it should work fine.

Understood. So I only get inout if I specify it in the client code? The problem is that maybe it is not appropriate to provide inout for all client code - we might want to mandate non-mutable iteration - in which case we must trust the user? (Normally catastrophic strategy!) Am I understanding correctly?
Sep 13 2003
parent reply "Walter" <walter digitalmars.com> writes:
"Matthew Wilson" <matthew stlsoft.org> wrote in message
news:bk125i$fph$2 digitaldaemon.com...
 The delegate must be declared with inout (so the same apply() function


 work with both inout and in foreaches). But the foreach does not, just

 off the 'in' and it should work fine.

Understood. So I only get inout if I specify it in the client code?

Yes.
 The problem is that maybe it is not appropriate to provide inout for all
 client code - we might want to mandate non-mutable iteration - in which

 we must trust the user? (Normally catastrophic strategy!) Am I

 correctly?

Yes. If it would be catastrophic, just pass a copy of it to the delegate. Then assert if it changes!
Sep 14 2003
parent reply "Matthew Wilson" <matthew stlsoft.org> writes:
"Walter" <walter digitalmars.com> wrote in message
news:bk16f2$mpo$1 digitaldaemon.com...
 "Matthew Wilson" <matthew stlsoft.org> wrote in message
 news:bk125i$fph$2 digitaldaemon.com...
 The delegate must be declared with inout (so the same apply() function


 work with both inout and in foreaches). But the foreach does not, just

 off the 'in' and it should work fine.

Understood. So I only get inout if I specify it in the client code?

Yes.
 The problem is that maybe it is not appropriate to provide inout for all
 client code - we might want to mandate non-mutable iteration - in which

 we must trust the user? (Normally catastrophic strategy!) Am I

 correctly?

Yes. If it would be catastrophic, just pass a copy of it to the delegate. Then assert if it changes!

That chews. Though the right-to-change issue is the most important one (and your remedy is not taken seriously ;)), the one I had was that I had to create a temporary to pass to the delegate, since it required an lvalue, i.e. else if(0 == res) { Key key = m_key.get_SubKey(sName[0 .. cchName]); result = dg(key); } rather than the neater else if(0 == res) { result = dg(m_key.get_SubKey(sName[0 .. cchName])); } I can live with that, but not with the facilitation of potential illegal client code acts.
Sep 14 2003
parent reply "Walter" <walter digitalmars.com> writes:
"Matthew Wilson" <matthew stlsoft.org> wrote in message
news:bk174v$nhv$1 digitaldaemon.com...
 Yes. If it would be catastrophic, just pass a copy of it to the


 Then assert if it changes!

That chews. Though the right-to-change issue is the most important one (and your

 is not taken seriously ;)), the one I had was that I had to create a
 temporary to pass to the delegate, since it required an lvalue, i.e.

Your solution is the same one I suggested <g>.
    else if(0 == res)
    {
     Key key = m_key.get_SubKey(sName[0 .. cchName]);

     result = dg(key);
    }

 rather than the neater

    else if(0 == res)
    {
     result = dg(m_key.get_SubKey(sName[0 .. cchName]));
    }

 I can live with that, but not with the facilitation of potential illegal
 client code acts.

Sep 14 2003
parent "Matthew Wilson" <matthew stlsoft.org> writes:
 "Matthew Wilson" <matthew stlsoft.org> wrote in message
 news:bk174v$nhv$1 digitaldaemon.com...
 Yes. If it would be catastrophic, just pass a copy of it to the


 Then assert if it changes!

That chews. Though the right-to-change issue is the most important one (and your

 is not taken seriously ;)), the one I had was that I had to create a
 temporary to pass to the delegate, since it required an lvalue, i.e.

Your solution is the same one I suggested <g>.

But that sucks. Now the user thinks they're changing something when they're not. Is it really that hard to refuse to compile foreach(inout T t; coll) {} when the apply() delegate takes in, rather than inout?
Sep 14 2003