| So, how about the following? Instead of the | | newtype Window = Window ForeignObj | | way of wrapping foreign ADTs that we used so far, should we | use | | newtype WindowTag = WindowTag () | type Window = ForeignObj WindowTag A fine idea. I accept what you say about ADTs, but if it's really so, we woudn't need the objectionable
withForeignObj :: ForeignObj -> (Ptr a -> IO b) -> IO b
because all ForeignObj-manipulating things would be foreign imported foreign import f :: Window -> IO () Anyway, it strikes me as good to tag each ForeignObj with an indication of what it points to, just so that one does not mix up ForeignObjs that should not be mixed. But it's just a suggestion. You guys who are deeply into the FFI should decide. It would be nice to get to closure on this FFI stuff -- it's been going on a long time! Simon
On Fri, 1 Dec 2000, Simon Peyton-Jones wrote:
if it's really so, we woudn't need the objectionable
withForeignObj :: ForeignObj -> (Ptr a -> IO b) -> IO b
because all ForeignObj-manipulating things would be foreign imported
foreign import f :: Window -> IO ()
It's not always that foreign objects are abstract from the Haskell's point of view. Often, but not always. There is a large intermediate area, where foreign objects store structures which don't have a Haskell equivalent to put in the argument of the ForeignObj type, but programs refer to their fields directly. hsc2hs provides a way to access those fields: withForeignObj obj $ \ptr -> do x <- (#peek struct foo, field1) ptr y <- (#peek struct foo, field2) ptr ... I am not strongly arguing for either option (ForeignObj or ForeignObj a). Both are OK. Beware that in case of ForeignObj a the type will often be tagged with a void type or () - neither will be used as the argument of the corresponding Ptr in a useful way (neither is Storable). -- Marcin 'Qrczak' Kowalczyk
"Marcin 'Qrczak' Kowalczyk" <mk167280@zodiac.mimuw.edu.pl> wrote,
On Fri, 1 Dec 2000, Simon Peyton-Jones wrote:
if it's really so, we woudn't need the objectionable
withForeignObj :: ForeignObj -> (Ptr a -> IO b) -> IO b
because all ForeignObj-manipulating things would be foreign imported
foreign import f :: Window -> IO ()
It's not always that foreign objects are abstract from the Haskell's point of view. Often, but not always.
There is a large intermediate area, where foreign objects store structures which don't have a Haskell equivalent to put in the argument of the ForeignObj type, but programs refer to their fields directly. hsc2hs provides a way to access those fields:
withForeignObj obj $ \ptr -> do x <- (#peek struct foo, field1) ptr y <- (#peek struct foo, field2) ptr ...
I am not strongly arguing for either option (ForeignObj or ForeignObj a). Both are OK. Beware that in case of ForeignObj a the type will often be tagged with a void type or () - neither will be used as the argument of the corresponding Ptr in a useful way (neither is Storable).
I agree, but you *can* use a meaningful tag - as I outlined with the window example - instead of just (). So, it is up to the programmer whether to use that additional bit of type safety or not. Given that there is some use to having parametrised ForeignObjs and that it would make the interface a little bit more orthogonal (as Ptr is parametrised), I weakly vote in favour of having the type argument. Cheers, Manuel
participants (3)
-
Manuel M. T. Chakravarty -
Marcin 'Qrczak' Kowalczyk -
Simon Peyton-Jones