Re: This feels wrong

2016-02-03 Thread Shachar Shemesh via Digitalmars-d

On 02/02/16 21:24, Ali Çehreli wrote:

On 02/02/2016 07:21 AM, Shachar Shemesh wrote:

 > it is a potential pitfall when implementing that I don't think is
 > documented.

Good catch! Please either open a documentation bug for this or fork the
repo and fix it yourself. :) (Hopefully, there is an 'Improve this page'
link on that page.)

Ali



https://github.com/D-Programming-Language/dlang.org/pull/1224


Re: This feels wrong

2016-02-02 Thread Steven Schveighoffer via Digitalmars-d

On 2/2/16 10:21 AM, Shachar Shemesh wrote:

On 02/02/16 17:00, Steven Schveighoffer wrote:


Just put try around the opApply specific parts you want to monitor.
Don't guard the call to dg.

The call to dg is, obviously, part of a loop. That whole loop body is
inside a try/catch.


I don't see a big difference from this:

int opApply( scope int delegate(int) dg ) {
foreach(int i; 0 .. 50) {
int res = dg(i);
try {
if( res!=0 ) {
writefln("Delegate returned %s", res);
return res;
}
} catch(Exception ex) {
writefln("Caught in loop: %s", ex.msg);
}
}

return 0;
}


My problem isn't so much the actual how to solve it, but rather that it
is a potential pitfall when implementing that I don't think is documented.


OK, I understand what you are saying. It could be listed in the docs as 
something to avoid.


-Steve



Re: This feels wrong

2016-02-02 Thread Ali Çehreli via Digitalmars-d

On 02/02/2016 07:21 AM, Shachar Shemesh wrote:

> it is a potential pitfall when implementing that I don't think is
> documented.

Good catch! Please either open a documentation bug for this or fork the 
repo and fix it yourself. :) (Hopefully, there is an 'Improve this page' 
link on that page.)


Ali



Re: This feels wrong

2016-02-02 Thread Shachar Shemesh via Digitalmars-d

On 02/02/16 17:00, Steven Schveighoffer wrote:


Just put try around the opApply specific parts you want to monitor.
Don't guard the call to dg.
The call to dg is, obviously, part of a loop. That whole loop body is 
inside a try/catch.


What I ended up doing, instead, was to put a flag, and the call to dg 
is, effectively:


stuff...
{
scope(failure) flags=true;
dg();
}
more stuff...

and then, the catch:

catch(Exception ex) {
if( flags )
throw ex;

other stuff...
}

My problem isn't so much the actual how to solve it, but rather that it 
is a potential pitfall when implementing that I don't think is documented.


Shachar


Re: This feels wrong

2016-02-02 Thread Steven Schveighoffer via Digitalmars-d

On 2/2/16 4:44 AM, Shachar Shemesh wrote:

Please consider the following program:
import std.stdio;

struct A {
 int opApply( scope int delegate(int) dg ) {
 foreach(int i; 0 .. 50) {
 try {
 int res = dg(i);
 if( res!=0 ) {
 writefln("Delegate returned %s", res);
 return res;
 }
 } catch(Exception ex) {
 writefln("Caught in loop: %s", ex.msg);
 }
 }

 return 0;
 }
}

void main() {
 try {
 A a;
 foreach(i; a) {
 writefln("Loop got %s", i);

 if( i==10 ) {
 throw new Exception("Excccption");
 }

 if( i==20 ) {
 break;
 }
 }
 } catch( Exception ex ) {
 writefln("Caught outside of loop: %s", ex.msg);
 }
}

When run, I expected the loop to break after 10 iterations due to the
exception being thrown. Instead, the loop continued.

The problem with this is that, sometimes, the task generating the loop
might, itself, require exception handling. Distinguishing between the
exceptions thrown inside the delegate and outside it becomes a somewhat
tricky exercise.

At the very least, I think this behaviour should be documented.

Thoughts?


Just put try around the opApply specific parts you want to monitor. 
Don't guard the call to dg.


-Steve



This feels wrong

2016-02-02 Thread Shachar Shemesh via Digitalmars-d

Please consider the following program:
import std.stdio;

struct A {
int opApply( scope int delegate(int) dg ) {
foreach(int i; 0 .. 50) {
try {
int res = dg(i);
if( res!=0 ) {
writefln("Delegate returned %s", res);
return res;
}
} catch(Exception ex) {
writefln("Caught in loop: %s", ex.msg);
}
}

return 0;
}
}

void main() {
try {
A a;
foreach(i; a) {
writefln("Loop got %s", i);

if( i==10 ) {
throw new Exception("Excccption");
}

if( i==20 ) {
break;
}
}
} catch( Exception ex ) {
writefln("Caught outside of loop: %s", ex.msg);
}
}

When run, I expected the loop to break after 10 iterations due to the 
exception being thrown. Instead, the loop continued.


The problem with this is that, sometimes, the task generating the loop 
might, itself, require exception handling. Distinguishing between the 
exceptions thrown inside the delegate and outside it becomes a somewhat 
tricky exercise.


At the very least, I think this behaviour should be documented.

Thoughts?

Shachar


Re: This feels wrong

2016-02-02 Thread Marc Schütz via Digitalmars-d
It seems this is a natural consequence of the lowering. As such, 
I'm not surprised by the behaviour, of course under the 
assumption I - as an end user - actually know that the given 
opApply catches the exception. I guess there could be a 
recommendation in opApply's specification that implementors 
shouldn't needlessly catch exceptions, especially not unspecific 
ones like `Exception`, but if they do, they should rethrow them, 
or better yet use scope(exit/finally) and try/finally as 
appropriate.