Don't speculate.  Write benchmarks for the safe and unsafe benchmark approaches using criterion and find out.  Honestly any db query will take at least 100 microseconds and any exceptions overhead plus safe ffi overhead is going to be negligible.  <div>
<br></div><div>Point being : write benchmarks. And for ANY computation that ever takes more than 1 microsecond, please use the safe ffi. <span></span><br><br>On Saturday, February 15, 2014, Nick Rudnick <<a href="mailto:nick.rudnick@gmail.com">nick.rudnick@gmail.com</a>> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

<br>
<br>
I have to admit that reading your messages has left me wondering what exactly<br>
it is that you are trying to do? What exactly is the problem that you are<br>
trying to solve?<br></blockquote><div>You exactly got the point (below)  with "Your question is how to integrate C++ code that might throw exceptions into Haskell via FFI, right?".</div><div><br></div><div>The only thing I am worried about is that, due to lacking experience, I might introduce unnecessary runtime overhead, as performance is critical. I don't want to disimprove.<br>

</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div><br>
 > I see the solution isn't as easy as just replacing e.g.<br>
 ><br>
 > void myUnexpected () {<br>
 >   std::cerr << "unexpected called\n";<br>
 >   throw 0;<br>
 > }<br>
 ><br>
 > by<br>
 ><br>
 > void myUnexpected () {<br>
 >   std::cerr << "unexpected called\n";<br>
 > }<br>
<br>
</div>I'm not sure whether the purpose of std::unexpected_handler() has become clear.<br>
That function is not supposed to handle exceptions in the sense that it makes<br>
the exception "go away" so that normal program flow can continue. Its purpose<br>
is to translate an unexpected exception -- which the program cannot handle --<br>
into a different one that the program can handle. Maybe this quote from [1]<br>
clarifies the matter:<br>
<br>
 | A user-defined std::unexpected_handler is expected to either terminate the<br>
 | program or throw an exception. If it throws an exception, one of the<br>
 | following three situations may be encountered:<br>
 |<br>
 |   1) the exception thrown by std::unexpected_handler satisfies the dynamic<br>
 |      exception specification that was violated earlier. The new exception is<br>
 |      allowed to escape the function and stack unwinding continues.<br>
 |<br>
 |   2) the exception thrown by std::unexpected_handler still violates the<br>
 |      exception specification:<br>
 |<br>
 |       a) however, the exception specification allows std::bad_exception: the<br>
 |          thrown exception object is destroyed, and std::bad_exception is<br>
 |          constructed by the C++ runtime and thrown instead.<br>
 |<br>
 |       b) the exception specification does not allow std::bad_exception:<br>
 |          std::terminate() is called.<br>
<br>
This means that the second myUnexpected() function from above is actually<br>
illegal in this context, because it neither throws an exception nor does it<br>
terminate the program.</blockquote><div>What a delicate question... :-)) :-)) :-)) Better I choose my words careful... Hmmm... certainly... In my case, it's failed DB queries that may be caused by failed SQL queries in a backend behind the C++ code; and as far as I can judge, everything is already handled neatly with no collateral damage to be feared for – roughly, these C++ exceptions say that the SQL code wasn't executed – in (a possible) interactive mode meaning merely "please repeat that query correctly...".</div>

<div><br></div><div>But currently, this appears somewhat complicated by</div><div>(1) termination of the code</div><div>(2) quite terse messages (i.e., I am interested in better debug capabilities, too)</div><div><br></div>

<div>By reading Alexander's link to <a href="http://www.cplusplus.com/reference/exception/set_unexpected/" target="_blank">http://www.cplusplus.com/reference/exception/set_unexpected/</a>, I got the impression that there is reasonable chance there is a simple mechanism behind set_unexpected(...) allows replacing some default code leading to termination by arbitrary code – very attractive under these circumstances –, and facing the question what's the meaning of 'illegal' was second to this...</div>

<div><br></div><div>Anyway, this round went to Murphy – or at least I do not see a way to get the termination avalanche stopped yet.</div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

<div>
<br>
 > The test code I have chosen for learning about the problem is hsqml by Robin<br>
 > Kay, which I consider to be very well done, usually injecting into<br>
 > HsQMLManager.{cpp|h}.hsqml_init(...),<br>
 ><br>
 > extern "C"<br>
 > void hsqml_init(void (*freeFun)(HsFunPtr), void (*freeStable)(HsStablePtr) ) throw() {<br>
 >   std::set_unexpected (myunexpected);<br>
 >   throw runtime_error("OOOPS...");<br>
 >   ...<br>
 > }<br>
<br>
</div>I am not sure what exactly the intention behind that code snippet is. I've<br>
looked into the hsqml source at [2], and the hsqml_init() function there<br>
doesn't look like that.<br></blockquote><div>Certainly, as lines were injected by me (I guess I mentioned at 1st mail) for learning about the problem – with hsqml being needed as a scaffold for this.</div><div> </div>

<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div>
<br>
 > What puzzles me currently is that, by the descriptions, I would expect<br>
 > that terminate() actually is replaced by std::cerr, so that the<br>
 > termination displayed in the result happens afterwards – but where??<br>
<br>
</div>I am not sure what you mean by that statement. std:cerr is an object, so it<br>
cannot replace std::terminate(), which is a function.<br></blockquote><div> Please excuse: s/std:cerr/std:cerr.../</div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

<div>
<br>
 > In regard of what's my question, there should be something like a<br>
 > common/best practice, shouldn't it?<br>
<br>
</div>Your question is how to integrate C++ code that might throw exceptions into<br>
Haskell via FFI, right? Please correct me if that's not the case.<br></blockquote><div>Definitely, modulo performance/overhead. </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">


<br>
There is no one true way to accomplish that. Since you cannot catch or throw<br>
C++ exceptions in Haskell, you'll probably have to pass them from C++ to<br>
Haskell manually as a value. For example, the C++ function<br>
<br>
  int do_stuff() { ... }<br>
<br>
would need a wrapper like this one:<br>
<br>
  enum exception_type { none = 0, runtime_error, logic_error, unknown };<br>
<br>
  struct either_exception_or_int<br>
  {<br>
    exception_type err;<br>
    int val;<br>
  };<br>
<br>
  void do_stuff_(either_exception_or_int * result) throw()<br>
  {<br>
    try<br>
    {<br>
      result->err = none;<br>
      result->val = do_stuff();<br>
    }<br>
    catch(std::runtime_error const &)   { result->err = runtime_error; }<br>
    catch(std::logic_error const &)     { result->err = logic_error; }<br>
    catch(...)                          { result->err = unknown; }<br>
  }<br>
<br>
Now, on the Haskell side, you'd import do_stuff_() via FFI, and then write<br>
another wrapper<br>
<br>
  do_stuff :: IO Int<br>
  do_stuff = alloca $ \result -> do<br>
    do_stuff_ result<br>
    val <- peek result<br>
    either throwCxxError return val<br>
<br>
  throwCxxError :: CxxExceptionType -> IO a<br>
  throwCxxError Runtime_error = throwIO ...<br>
  throwCxxError ...<br>
<br>
to throw an appropriate Haskell exception that corresponds to the C++ exception<br>
type.<br></blockquote><div>You exactly concretized the 'Either' approach sketched in my mail, though I would have tried to</div><div>(1) get a union instead of a struct for `either_exception_or_int'</div><div>

(2) use pointers for err/val.</div><div>What I am worried about is that exactly this might result in inappropriate overhead.</div><div><br></div><div>This directly leads to the other suggestion of my mail; to, instead of a union of 2 pointers, let `either_exception_or_int' be just a pointer – somewhat opaque for the Haskell side, which still might pipeline it very efficiently from here to there, while it would be possible to C++ to resolve the pointer addresses. </div>

<div> </div><div>So with my 'illegal' one, I see 3 approaches yet.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">


I'm not sure whether anybody has done something like that before, i.e. I cannot<br>
refer you to a concrete Haskell project that demonstrates this technique with<br>
real-world code.<br></blockquote><div><img src="cid:33A@goomoji.gmail" goomoji="33A" style="margin:0px 0.2ex;vertical-align:middle"> </div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">


 > As Alexander states, there is a pleasing zero runtime approach with C++<br>
 > exceptions.<br>
<br>
I thought Alexander said the exact opposite, i.e. that C++ does *not* have zero<br>
overhead exceptions?<br></blockquote><div>I referred to his mail just incoming when I answered to you (2014-2-14 9:11, "One unmentioned fact is that the exception mechanism in C++ is designed to allow for implementations to have zero runtime cost. ...") – what he addresses makes me quite less worried that catching C++ exceptions themselves in the FFI would introduce performance issues, than wrapping/unwrapping with Either & Co.</div>

<div><br></div><div>Cheers, Nick</div></div></div></div>
</blockquote></div>