unsafePerformIO around FFI calls

I'm curious exactly what is "safe" and what is "unsafe" to wrap unsafePerformIO around when it comes to FFI calls. If there's a general discussion of this somewhere and someone could send me a pointer that would be another acceptable solution. I googled for "unsafePerformIO FFI" but nothing relevant turned up. Anyway, here's the issue at hand. I have a function which takes a value and an IO action, allocates some memory, put the value in there, executes the IO action (which is an FFI function), gets the result, deallocates the memory and then returns the rest. For instance, we have an FFI function from LAPack which computes, say, eigenvalues. Because this is from fortran and in fortran everything is by reference, the function is an IO action of (simplified) type:
maxEigenvalue :: HMatrix -> IO Double
implemented using FFI. We also have the CPS function to make the HMatrix:
withMatrix :: [[Double]] -> (HMatrix -> IO Double) -> IO Double
which looks basically like (I'm on vacation so I don't have the real code right now):
withHMatrix m action = do memory <- allocate memory hm <- write m into memory result <- action hm deallocate memory return result
(it's slightly more complex because i need to make it safe in the case that action throws an exception and the memory is still deallocated before the exception is re-raised.) i can then wrap these together and say:
compEig :: [[Double]] -> IO Double compEig m = withHMatrix m maxEigenvalue
so the question is: Under what circumstances is it safe to make instead:
compEig' :: [[Double]] -> Double compEig' m = unsafePerformIO $ withHMatrix m maxEigenvalue
??? Thanks! - Hal p.s., Please continue to CC Carl as this issue came up in conversations with him -- Hal Daume III "Computer science is no more about computers | hdaume@isi.edu than astronomy is about telescopes." -Dijkstra | www.isi.edu/~hdaume

Hal Daume
I'm curious exactly what is "safe" and what is "unsafe" to wrap unsafePerformIO around when it comes to FFI calls.
Here's a simple test: Could you imagine an alternative implementation of the same API in pure Haskell? (Don't consider efficiency or effort required to write the implementation, just whether it can be done.) If so, then it is ok to use unsafePerformIO and the ffi to implement the API instead. If it fails that test, it is incredibly unlikely that it is ok and a proof that it is ok is likely to be pretty complex - maybe worth a PLDI paper or some such. -- Alastair Reid alastair@reid-consulting-uk.ltd.uk Reid Consulting (UK) Limited http://www.reid-consulting-uk.ltd.uk/alastair/
participants (2)
-
Alastair Reid
-
Hal Daume III