Thread overview
foreach, opApply and inout
Apr 22, 2005
Kevin Bealer
Apr 22, 2005
Regan Heath
Apr 23, 2005
Kevin Bealer
April 22, 2005
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



April 22, 2005
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
April 23, 2005
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



April 23, 2005
"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.