
Below is an automatically-generated summary of the modules in the core libs I checked in earlier, including the stability/portability status of each module. I've gone through and put in a best guess for the stability/portability status, so let me know if you think any are wrong (Hugs, NHC folks: remember that every module marked "portable" is expected to be available on all implementations - so if any of these are going to cause problems, let me know). Names with a '.' after are directories, names without a trailing '.' are modules. Cheers, Simon ------------------ Control. Concurrent. CVar ( non-portable, experimental ) Chan ( non-portable, experimental ) MVar ( non-portable, experimental ) QSem ( non-portable, experimental ) QSemN ( non-portable, experimental ) SampleVar ( non-portable, experimental ) Concurrent ( non-portable, experimental ) Exception ( non-portable, experimental ) Monad. Cont ( non-portable, experimental ) Error ( non-portable, experimental ) Fix ( non-portable, experimental ) Identity ( portable, experimental ) List ( non-portable, experimental ) Monoid ( non-portable, experimental ) RWS ( non-portable, experimental ) Reader ( non-portable, experimental ) ST. Lazy ( portable, provisional ) Strict ( portable, provisional ) ST ( non-portable, experimental ) State ( non-portable, experimental ) Trans ( portable, experimental ) Writer ( non-portable, experimental ) Monad ( portable, provisional ) Parallel. Strategies ( non-portable, experimental ) Parallel ( non-portable, experimental ) Data. Array. Base ( non-portable, experimental ) IArray ( non-portable, experimental ) IO ( non-portable, experimental ) MArray ( non-portable, experimental ) ST ( non-portable, experimental ) Unboxed ( non-portable, experimental ) Array ( portable, provisional ) Bits ( portable, experimental ) Bool ( portable, experimental ) Char ( portable, provisional ) Complex ( portable, provisional ) Dynamic ( portable, experimental ) Either ( portable, experimental ) IORef ( portable, experimental ) Int ( portable, experimental ) Ix ( portable, provisional ) List ( portable, provisional ) Maybe ( portable, experimental ) PackedString ( portable, experimental ) Ratio ( portable, provisional ) STRef ( portable, experimental ) Word ( portable, experimental ) Database. Debug. Trace ( portable, provisional ) FileFormat. Foreign. C. Error ( portable, provisional ) String ( portable, provisional ) Types ( portable, provisional ) TypesISO ( portable, provisional ) C ( portable, provisional ) ForeignPtr ( portable, provisional ) Marshal. Alloc ( portable, provisional ) Array ( portable, provisional ) Error ( portable, provisional ) Utils ( portable, provisional ) Ptr ( portable, provisional ) StablePtr ( portable, provisional ) Storable ( portable, provisional ) Foreign ( portable, provisional ) GHC. Arr ( , ) Base ( , ) ByteArr ( , ) Conc ( , ) Dynamic ( , ) Enum ( , ) Err ( , ) Exception ( , ) Float ( , ) Handle ( , ) IO ( , ) IOBase ( , ) Int ( , ) List ( , ) Main ( , ) Maybe ( , ) Num ( , ) Pack ( , ) Posix ( , ) Ptr ( , ) Read ( , ) Real ( , ) ST ( , ) STRef ( , ) Show ( , ) Stable ( , ) Storable ( , ) TopHandler ( , ) Tup ( , ) Weak ( , ) Word ( , ) Hugs. Language. NHC. Network. Prelude ( portable, provisional ) System. CPUTime ( portable, provisional ) Cmd ( portable, provisional ) Environment ( portable, provisional ) Exit ( portable, provisional ) IO. Directory ( portable, provisional ) Unsafe ( portable, provisional ) IO ( portable, provisional ) Info ( portable, provisional ) Locale ( portable, provisional ) Mem. StableName ( non-portable, experimental ) Weak ( non-portable, experimental ) Random ( portable, provisional ) Time ( portable, provisional ) Text. Read ( portable, provisional ) Show. Functions ( portable, provisional ) Show ( portable, provisional )

Great work Simon.
Simon Marlow
I've gone through and put in a best guess for the stability/portability status, so let me know if you think any are wrong (Hugs, NHC folks: remember that every module marked "portable" is expected to be available on all implementations - so if any of these are going to cause problems, let me know).
(Without having looked at it at all) I'm half expecting to have to tweak the Foreign interface a bit since the low level grungy stuff is where compiler differences are hardest to hide. Does it work on NHC? (In which case changes are a lot less likely) I remember that one of the ForeignObj-like datatypes pretty much requires threads to implement it because the finaliser is an arbitrary piece of Haskell code. This would be hard to support in Hugs and I expect NHC would have problems too. -- Alastair Reid reid@cs.utah.edu http://www.cs.utah.edu/~reid/

I've gone through and put in a best guess for the stability/portability status, so let me know if you think any are wrong (Hugs, NHC folks: remember that every module marked "portable" is expected to be available on all implementations - so if any of these are going to cause problems, let me know).
Ok, I've marked against your list anything that I think is problematic for nhc98, despite being designated portable. Regards, Malcolm ------------------ Control. Monad. Identity ( portable, experimental ) *** Re-exports Control.Monad.Fix, which *** is designated non-portable. ST. Lazy ( portable, provisional ) Strict ( portable, provisional ) *** Don't both variants of ST require runtime *** system support? If so, then not yet portable. Trans ( portable, experimental ) *** I can't imagine what the name means, but *** the code does look like pure Haskell'98. Monad ( portable, provisional ) Data. Array ( portable, provisional ) Bits ( portable, experimental ) *** Not portable. requires either RTS support *** or an FFI'd implementation in C I would think. Bool ( portable, experimental ) Char ( portable, provisional ) Complex ( portable, provisional ) Dynamic ( portable, experimental ) *** Doesn't contain a data decl for Dynamic, *** but otherwise looks ok. This doesn't require *** any RTS support does it? Either ( portable, experimental ) IORef ( portable, experimental ) Int ( portable, experimental ) Ix ( portable, provisional ) *** H'98 compliance: rangeSize should now be *** a class member. List ( portable, provisional ) Maybe ( portable, experimental ) PackedString ( portable, experimental ) *** nhc98 implements only the `classic' HBC *** interface. In particular, none of the *** ByteArray ops are portable. Ratio ( portable, provisional ) STRef ( portable, experimental ) *** As with the ST monad, I believe RTS support *** or an FFI'd implementation is required? Word ( portable, experimental ) Database. Debug. Trace ( portable, provisional ) FileFormat. Foreign. *** I haven't looked at the Foreign stuff in *** detail for quite a while, so apart from *** some RTS implementation in nhc98, I'm *** assuming everything else is straightforward. GHC. Hugs. NHC. *** I'd prefer Nhc or Nhc98. All caps is horrible. Network. Prelude ( portable, provisional ) System. *** The sample implementations of many of these *** System libraries are not very portable, but *** the interfaces are probably ok. CPUTime ( portable, provisional ) Cmd ( portable, provisional ) Environment ( portable, provisional ) Exit ( portable, provisional ) IO. Directory ( portable, provisional ) *** Incorrect interface: Permissions should not *** be abstract. Unsafe ( portable, provisional ) IO ( portable, provisional ) Info ( portable, provisional ) *** A great idea. Status should be experimental. Locale ( portable, provisional ) Random ( portable, provisional ) Time ( portable, provisional ) Text. Read ( portable, provisional ) Show. Functions ( portable, provisional ) Show ( portable, provisional ) ------------------

ST. Lazy ( portable, provisional ) Strict ( portable, provisional ) *** Don't both variants of ST require runtime *** system support? If so, then not yet portable. STRef ( portable, experimental ) *** As with the ST monad, I believe RTS support *** or an FFI'd implementation is required? STRefs and the operations on them are the same in both variants. The only difference is in the >>= implementation. So you need runST either as a language extension (as in the Lazy state thread paper) or using rank 2 polymorphism. The spec should make it clear that the (slightly) more restrictive runST implementation is cool. Hmmm, an ffi'd implementation would be possible - but really ugly! Bits ( portable, experimental ) *** Not portable. requires either RTS support *** or an FFI'd implementation in C I would think. But, but, nhc is noted for having all that cool, low-level support - you really don't have bit ops??? Anyway, an FFI implementation would be useful as a reference implementation. Need to take care to properly implement the exceptional cases like: x `shiftR` 1000 == 0 (C does not guarantee this - you might get a shift of 1000 `mod` 32) Dynamic ( portable, experimental ) *** Doesn't contain a data decl for Dynamic, *** but otherwise looks ok. This doesn't require *** any RTS support does it? Needs unsafeCoerce :: a -> b GHC's implementation probably hides in their Prelude which is why you can't see it. In fact, it's hard _not_ to put it in your Prelude since Exception depends on Dynamic and Exception likes to be in the Prelude. (This was alluded to in my meeting summary last week.) Which reminds me: does/will nhc support exception handling? The semantics is tricky but the implementation is just the standard "trim the stack" kind of stuff with a little tweak for outstanding updates if you want: GHC does this, Hugs does not. The most tedious part is tweaking all the operations that return errors so that they raise exceptions instead. Hugs does pattern match failures and most primops but misses some operations and doesn't do any of the asynchronous exceptions (they're all _really_ tricky to add to Hugs). Also, Hugs doesn't implement the full exception datatype - most exceptions just return a string containing an error message rather than DivisionByZero (or whatever). Most users won't notice the difference. PackedString ( portable, experimental ) *** nhc98 implements only the `classic' HBC *** interface. In particular, none of the *** ByteArray ops are portable. I expect this goes for Hugs too. (I expect (but didn't check) that the Foreign libs need ByteArray ops...) We could consider an ffi-based implementation which puts PackedStrings in the C heap but the performance characteristics will be very different from GHC leading to continual conflicts along the lines of "but this is cheap"... "only in your implementation"... Do nhc PackedStrings live in the Haskell heap? NHC. *** I'd prefer Nhc or Nhc98. All caps is horrible. It's your choice but I'd lean against the 98 - presumably there will come a time when the 98 isn't appropriate. (I feel the same way about the 98 in the directory structure for the Hugs source code.) -- Alastair Reid reid@cs.utah.edu http://www.cs.utah.edu/~reid/

Control.Monad.ST.* ------------------ Simon:
Sorry, I thought NHC had the ST monad. Ok, I'll mark it non-portable for the time being. Actually to implement it all you need is a bit of typechecker support for runST and that's it, though.
I love it when people say "you just need to hack the type system a little bit". :-) Nhc98's implementation of type inference could do with some knowledgable volunteers to (a) help it cope with higher kinds, (b) add runST, (c) add MPTC, and (d) other cool things. In fact, a complete rewrite would probably be the ideal strategy, since no-one really understands how it works now, neither its original author nor our resident type hacker! Alastair:
So you need runST either as a language extension (as in the Lazy state thread paper) or using rank 2 polymorphism. The spec should make it clear that the (slightly) more restrictive runST implementation is cool.
Which of the two implementations is the more restrictive? Data.Bits --------- Simon:
I was thinking that Bits is required by Data.Word & Data.Int, which are in turn required by the Foreign stuff, but you can perhaps get away without exporting Bits instances from these modules.
Don't get me wrong, I think we need a Bit/Bits library. Alastair:
But, but, nhc is noted for having all that cool, low-level support - you really don't have bit ops???
nhc98 does indeed have bit-ops, but to the proposed Haskell 1.3 design, not whatever ghc ended up with. Anyway, my point was really only that the code for this library gives an very non-portable implementation, when a pure FFI one would be preferable.
Need to take care to properly implement the exceptional cases like: x `shiftR` 1000 == 0 (C does not guarantee this - you might get a shift of 1000 `mod` 32)
Or indeed, you might get a left shift, or a random bit pattern. Isn't the K&R phrase "the behaviour is undefined" just great?
Perhaps we could make 'instance Bits Integer' optional, because that's probably the hardest bit.
Blink. What exactly would such an instance mean? Data.Dynamic ------------ Alastair:
Needs unsafeCoerce :: a -> b
Simon:
It requires unsafePerformIO & IORefs, but that's all.
Ok, nhc98 has all those, so no problem.
In fact, it's hard _not_ to put it in your Prelude since Exception depends on Dynamic and Exception likes to be in the Prelude.
Ah, but we don't have Exceptions. As a point of interest, is there a good reason why the Exception type needs to be in the Prelude?
Which reminds me: does/will nhc support exception handling?
No, but would love to. Data.PackedString ----------------- Alastair:
(I expect (but didn't check) that the Foreign libs need ByteArray ops...)
No, I believe ByteArrays have been made obsolete by Foreign.Marshall.Array which provides packed arrays of any type, not just bytes.
Do nhc PackedStrings live in the Haskell heap?
Yes. NHC vs Nhc ---------- Alastair:
It's your choice but I'd lean against the 98 - presumably there will come a time when the 98 isn't appropriate.
Granted. Simon:
Ok, Nhc it is. But it looks horrible next to GHC :-)
So you know what my answer is already... :-) System.* -------- Simon:
I think it would be great if we could all use the same implementations of these libs, though.
Absolutely agreed.
The implementations of CPUTime, Cmd, Environment, Exit, Time, and Directory are all rewrites of the original GHC versions to use the new FFI & Foreign libraries, so they should be quite portable. You do need hsc2hs and a suitable config.h, though.
Some examples of small GHC-isms: module System.Cmd system "" = ioException (IOError Nothing InvalidArgument "system" "null command" Nothing) The `ioException' function and `IOError' constructor are not portable. module System.Environment foreign label "prog_argv" prog_argv_label :: Ptr (Ptr (Ptr CChar)) foreign label "prog_argc" prog_argc_label :: Ptr CInt The "prog_argv" and "prog_argc" labels are not exactly standard. None of these is a huge problem of course - when we get down to compiling and running the code, it should be pretty straightforward to rectify these little things. Regards, Malcolm

Malcolm:
I love it when people say "you just need to hack the type system a little bit". :-)
The original runST implementation (i.e., hardwire it into the typechecker) really is pretty simple. I think even I could do it (to Hugs) and I avoided ever doing anything with Hugs' typechecker the whole time I maintained it. Alastair:
The spec should make it clear that the (slightly) more restrictive runST implementation is cool.
Malcolm:
Which of the two implementations is the more restrictive?
Hmmm, that was a bit ambiguous wasn't it? I meant the one where you hardwire runST into the typechecker. Simon:
Perhaps we could make 'instance Bits Integer' optional, because that's probably the hardest bit.
Malcolm:
Blink. What exactly would such an instance mean?
1) Transform the Integer arguments into infinite streams of bits (sign extending as necessary) 2) Perform the operation in the obvious way 3) Transform Integer parts of the result back into a finite Integer operation. Employ the obvious tricks to avoid requiring infinite space and time. It helps if your Integer representation is based on binary numbers. It really sucks if your Integer representation is based on decimals (as in Hugs). Malcolm:
Ah, but we don't have Exceptions. As a point of interest, is there a good reason why the Exception type needs to be in the Prelude?
Because it's nice to unify IOError with Exception as in GHC (but not Hugs). And because you want to define error by something like: error msg = Exception.raise (Exception.Error msg) (adapting names to match Exception's export list as required). Avoiding this unification is a bit awkward. Avoiding this unification and implementing cooperative threads a la Hugs is unbelievably awkward. Malcolm:
NHC vs Nhc
Is NHC/Nhc (used as) an acronym? Elsewhere in the library we are keeping acronyms all caps (and I think that's the right thing to do). GHC is used as a (mildly anachronistic) acronym so I'd expect it to be all caps. Hugs can be explained as an acronym too but it's not used that way. Just to confuse things, I also don't think of HGL as an acronym since the H can stand for at least 3 different things... (But whatever your answer, you can still call it whatever you want.) -- Alastair Reid reid@cs.utah.edu http://www.cs.utah.edu/~reid/

The original runST implementation (i.e., hardwire it into the typechecker) really is pretty simple. I think even I could do it (to Hugs).
Well there's a recommendation indeed. Perhaps I'll take a look.
instance Bits Integer
1) Transform the Integer arguments into infinite streams of bits (sign extending as necessary)
Are these streams chunked into words, or are they of uneven lengths? Wait, that's a dumb question. Of course conceptually they can be of any length, but in practice they can be implemented any way you like that preserves the semantics, yes? Ok, I think I understand now.
As a point of interest, is there a good reason why the Exception type needs to be in the Prelude?
because you want to define error by something like: error msg = Exception.raise (Exception.Error msg)
I'm still not entirely sure I understand why a qualified import into the Prelude implementation (as you have illustrated here) is not sufficient. Does Exception need to be hardwired into the Prelude? For a comparable example, think of type Prelude.Rational which is defined as (Ratio.Ratio Prelude.Integer). The Ratio type is not in the prelude, just used by it.
NHC vs Nhc
Is NHC/Nhc (used as) an acronym?
No, it has never stood for anything in particular. Or only light-heartedly. Regards, Malcolm
participants (4)
-
Alastair David Reid
-
Malcolm Wallace
-
Malcolm Wallace
-
Simon Marlow