unboxed arrays for nhc/jhc

Bulat Ziganshin bulat.ziganshin at gmail.com
Wed Mar 8 04:18:33 EST 2006

Hello John,

Wednesday, March 8, 2006, 5:55:26 AM, you wrote:

>> this implementation is already compatible with Hugs and GHC, now i
>> plan to make it NHC-compatible. i have the following question - is NHC
>> implements
>> 1) strict ST monad
>> 2) unsafeIOtoST operation
>> 3) Data.Array.*
>> if nhc don't supports ST/unsafeIOtoST, then i plan to use the
>> following ST monad emulation:
>> type ST a = IO a
>> unsafeIOtoST = id
>> runST = unsafePerformIO
>> also i plan to use this emulation layer for JHC. is this can work?

JM> jhc now supports rank-n polymorphism natively, so there is no need for
JM> emulation. the ST monad can be implemented just like it is in GHC.

can you implement it himself? then i will just download current jhc codebase

JM> so, I can do 1 and 2, but no Data.Array yet as MPTC's arn't supported
JM> yet, (but a concrete interface would do just fine for now)

now i say only about unboxed arrays. it's implementation is very
simple - just alloc memory block and use Storable interface to
read/write values. Unboxed references also implemented in this way. of
course it's generic way for almost any Haskell compiler, there is also
faster ghc-specific implementation. so, if jhc supports
Storable/ForeignPtr/ST/unsafeIOtoST then unboxed arrays/references
should work automagically (ForeignPtr required to attach finalizer
which will free() memory occupied by array). on the other side, if you
will suggest some better way to implement this in jhc, i'll add
jhc-specific path like i already added ghc-specific one

about boxed Arrays - i still recommend you to duplicate interface used
in existing compilers, it's very-very close in ghc and nhc while hugs
primitives are more higher-level. just implement interface like this

section "Arrays"
        {Operations on Array\#.}

primop  NewArrayOp "newArray#" GenPrimOp
   Int# -> a -> State# s -> (# State# s, MutArr# s a #)
   {Create a new mutable array of specified size (in bytes),
    in the specified state thread,
    with each element containing the specified initial value.}
   usage       = { mangle NewArrayOp [mkP, mkM, mkP] mkM }
   out_of_line = True

primop  SameMutableArrayOp "sameMutableArray#" GenPrimOp
   MutArr# s a -> MutArr# s a -> Bool
   usage = { mangle SameMutableArrayOp [mkP, mkP] mkM }

primop  ReadArrayOp "readArray#" GenPrimOp
   MutArr# s a -> Int# -> State# s -> (# State# s, a #)
   {Read from specified index of mutable array. Result is not yet evaluated.}
   usage = { mangle ReadArrayOp [mkM, mkP, mkP] mkM }

primop  WriteArrayOp "writeArray#" GenPrimOp
   MutArr# s a -> Int# -> a -> State# s -> State# s
   {Write to specified index of mutable array.}
   usage            = { mangle WriteArrayOp [mkM, mkP, mkM, mkP] mkR }
   has_side_effects = True

primop  IndexArrayOp "indexArray#" GenPrimOp
   Array# a -> Int# -> (# a #)
   {Read from specified index of immutable array. Result is packaged into
    an unboxed singleton; the result itself is not yet evaluated.}
   usage = { mangle  IndexArrayOp [mkM, mkP] mkM }

primop  UnsafeFreezeArrayOp "unsafeFreezeArray#" GenPrimOp
   MutArr# s a -> State# s -> (# State# s, Array# a #)
   {Make a mutable array immutable, without copying.}
   usage            = { mangle UnsafeFreezeArrayOp [mkM, mkP] mkM }
   has_side_effects = True

primop  UnsafeThawArrayOp  "unsafeThawArray#" GenPrimOp
   Array# a -> State# s -> (# State# s, MutArr# s a #)
   {Make an immutable array mutable, without copying.}
   usage       = { mangle UnsafeThawArrayOp [mkM, mkP] mkM }
   out_of_line = True

all other higher-level machinery can be made compiler-independent

Best regards,
 Bulat                            mailto:Bulat.Ziganshin at gmail.com

More information about the Libraries mailing list