FFI, safe vs unsafe

Simon Marlow simonmar at microsoft.com
Wed Mar 29 05:15:27 EST 2006

On 29 March 2006 09:11, John Meacham wrote:

> It would be nice if we can deprecate the not very informative  'safe'
> and 'unsafe' names and use more descriptive ones that tell you what is
> actually allowed.
> 'reentrant' - routine might call back into the haskell run-time
> 'blockable' - routine might block indefinitly

I've been meaning to bring this up.  First, I don't think 'blockable' is
the right term here.  This relates to Malcolm's point too:

> Another piece of terminology to clear up.  By "non-blocking foreign
> call", you actually mean a foreign call that *can* block.  As a
> consequence of the fairness policy, you wish to place the
> requirement on implementations that such a blocking foreign call
> _should_not_ block progress of other Haskell threads.  The
> thread-nature of the foreign call is "blocking".  The Haskell-API
> nature is desired to be "non-blocking".

Malcolm correctly notes that when I say "non-blocking" I'm referring to
the behaviour from Haskell's point of view, not a property of the
foreign code being invoked.

In fact, whether the foreign code being invoked blocks or not is largely
immaterial.  The property we want to capture is just this:

  During execution of the foreign call, other Haskell threads
  should make progress as usual.

It doesn't matter whether the foreign call "blocks" or not (although
that is a common use for this feature).  I'd rather call it
'concurrent', to indicate that the foreign call runs concurrently with
other Haskell threads.

Back to 'reentrant' vs. 'blockable'.  I'm not convinced that 'blockable
unsafe' is that useful.  The reason is that if other Haskell threads
continue running during the call, at some point a GC will be required,
at which point the runtime needs to traverse the stack of the thread
involved in the foreign call, which means the call is subject to the
same requirements as a 'reentrant' call anyway.  I don't think it's
necessary to add this finer distinction.  Unless perhaps you have in
mind an implementation that doesn't do GC in the traditional way... but
then I'm concerned that this is requiring programmers to make a
distinction in their code to improve performance for a minority
implementation technique, and that's not good language design.

If 'reentrant' in its full glory is too hard to implement, then by all
means don't implement it, and emit a run-time error if someone tries to
use it.


More information about the Haskell-prime mailing list