opApply/opApplyReverse return value types
Bill Baxter
dnewsgroup at billbaxter.com
Tue Oct 17 17:42:41 PDT 2006
Bill Baxter wrote:
> Max Samuha wrote:
>> The question might seem idle but why opApply/opApplyReverse return int
>> instead of bool, anyway?
>
> Actually, why do they have to return anything? It seems like it should
> be possible to make this work:
>
> void opApply(void delegate(inout ArgT) dg)
> {
> for (int i=0; i<length; i++)
> {
> if (dg(array[i]))
> break;
> }
> }
>
> I haven't totally grokked the code, but I see the magic is happening in
> statement.c, ForeachStatement::semantic somewhere. That function is
> constructing the delegate that wraps the loop body. I don't see why the
> delegate wrapper can't just store the value it returns to me so I don't
> have to keep track of it. It seems weirdly low-level for me to have to
> be the shephard of some value who's meaning is totally opaque to me.
I tried a little more to figure out statement.c, but it's definitely
over my head for now without studying more about the internals of the
compiler. Still, I'd like to understand how this foreach/opApply
business works, so let me explain how I think it works in principle, and
hopefully someone can tell me where I'm wrong.
I'm thinking that basically when you write:
foreach( T val; aggregate )
/loopBody/
Conceptually what happens is that d makes some wrapper around your loop
body:
class loopWrapper(T)
{
int doOneLoop(T val)
{
/setup code/
/loopBody/
/cleanup code/
return ret;
}
}
And then it calls your opApply passing it a delegate to that wrapper.
wrap = new loopWrapper();
int ret = aggregate.opApply( &wrap.doOneLoop );
Then my opApply does something like the standard:
int opApply(int delegate(inout ArgT) doOneLoop)
{
int ret;
for (int i=0; i<length; i++)
{
ret = doOneLoop(myArray[i]);
if (ret)
break;
}
return ret;
}
But D owns the loopWrapper and controls what goes into doOneLoop's
/setup code/ and /cleanup code/, so D should know what its return value
is without having to ask the aggregate to return it. Why not stash
the return value in the loopWrapper so the user doesn't have to worry
about it? Like this:
class loopWrapper(T)
{
void doOneLoop(T val)
{
/setup code/
/loopBody/
/cleanup code/
retCode = ret; // ADDED
return;
}
int retCode; // ADDED
}
Then D could just get the return code from the wrapper:
wrap = new loopWrapper();
aggregate.opApply( &wrap.doOneLoop );
int ret = wrap.retCode;
and not bother every opApply function with having to handle it with
boiler plate code that a) they can easily mess up, and b) obfuscates the
underlying idea.
So why wouldn't that work?
--bb
More information about the Digitalmars-d-learn
mailing list