www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - foreach, opApply and inout

reply Kevin Bealer <Kevin_member pathlink.com> writes:
While implementing an opApply, I noticed that foreach requires "inout" in order
to modify the contents of a container during iteration, but the prototype of the
function always specifies "inout" for the delegate.

It might be useful to have "in" only versions of opApply methods:

1. foreach(inout T v; x)
--> x.opApply(int opApply (int delegate(inout T) dg)

1. foreach(T v; x)
--> x.opApply(int opApply (int delegate(in T) dg)

.. In this way, non-modifiable containers, (ie hash sets) could prepare
themselves, and other containers can prepare for, or react to, changes.

Kevin
Apr 21 2005
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Fri, 22 Apr 2005 03:34:56 +0000 (UTC), Kevin Bealer  
<Kevin_member pathlink.com> wrote:
 While implementing an opApply, I noticed that foreach requires "inout"  
 in order
 to modify the contents of a container during iteration, but the  
 prototype of the
 function always specifies "inout" for the delegate.

 It might be useful to have "in" only versions of opApply methods:

 1. foreach(inout T v; x)
 --> x.opApply(int opApply (int delegate(inout T) dg)

 1. foreach(T v; x)
 --> x.opApply(int opApply (int delegate(in T) dg)

 .. In this way, non-modifiable containers, (ie hash sets) could prepare
 themselves, and other containers can prepare for, or react to, changes.

Hmm.. it does sound useful, however D does not overload on "in", "out", "inout", so those two delegates would essentially be identical. Of course this could change, but Walter had some fairly firm reasoning for not changing it last I heard. Regan
Apr 22 2005
parent reply Kevin Bealer <Kevin_member pathlink.com> writes:
In article <opspmkl2yu23k2f5 nrage.netwin.co.nz>, Regan Heath says...
On Fri, 22 Apr 2005 03:34:56 +0000 (UTC), Kevin Bealer  
<Kevin_member pathlink.com> wrote:
 While implementing an opApply, I noticed that foreach requires "inout"  
 in order
 to modify the contents of a container during iteration, but the  
 prototype of the
 function always specifies "inout" for the delegate.

 It might be useful to have "in" only versions of opApply methods:

 1. foreach(inout T v; x)
 --> x.opApply(int opApply (int delegate(inout T) dg)

 1. foreach(T v; x)
 --> x.opApply(int opApply (int delegate(in T) dg)

 .. In this way, non-modifiable containers, (ie hash sets) could prepare
 themselves, and other containers can prepare for, or react to, changes.

Hmm.. it does sound useful, however D does not overload on "in", "out", "inout", so those two delegates would essentially be identical. Of course this could change, but Walter had some fairly firm reasoning for not changing it last I heard. Regan

I can't argue with that. It would have to use another method name, like opIndex() and opIndexAssign() do. opApply() (inout) and opInspect() (in)? The second question, can D detect whether which to call within the current type system? I would think so, since it already has the "in" vs. "inout" distinction in the foreach statement. Also, is opApply used in non-foreach situations? Kevin
Apr 22 2005
parent "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Kevin Bealer" <Kevin_member pathlink.com> wrote in message 
news:d4ccct$l8c$1 digitaldaemon.com...
 opApply() (inout) and opInspect() (in)?  The second question, can D detect
 whether which to call within the current type system?  I would think so, 
 since
 it already has the "in" vs. "inout" distinction in the foreach statement.

Under the current system, the single inout opApply doubles for both. import std.stdio; class A { int[2] a; int opApply(int delegate(inout int x) dg) { int result=0; foreach(inout int x; a) { result=dg(x); if(result) break; } return result; } } void main() { A a=new A; foreach(int x; a) { x++; writefln(x); } writefln(); foreach(int x; a) { writefln(x); } writefln("-------"); foreach(inout int x; a) { x++; writefln(x); } writefln(); foreach(int x; a) { writefln(x); } } Notice in the first iteration, x is incremented, but it doesn't have a lasting effect, as shown in the second loop. The third loop uses inout, however, and the fourth loop shows that the contents were affected. Though I suppose what you'd like is a way to explicitly have an "in" version of opApply.
Apr 23 2005