Using Haskell programs and libraries with different compilers and/or
interpreters (or even with different versions of the same system!) is
currently quite a frustrating experience. This is can be attributed to
the following problems:

   * Different language versions (1.3, 1.4, 98, ...) exist. This is
     inevitably so for any language which is in use, see C++, Java, ...

   * There is no really portable way to level those language
     differences. IMHO, piping Haskell through cpp is a hack and has
     its own problems: nhc13 defines __HASKELL_98__, GHC __HASKELL98__;
     nhc13 defines __HASKELL__=3, ghc __HASKELL1__=5, and hbc
     __HASKELL_1_3__. Hugs does not come with a Haskell-compatible
     preprocessor at all. We use hscpp from the ghc distribution for
     this, but hscpp only knows about a -v flag. No chance to define
     something else via the command line. Not to mention continuation
     lines/string gaps...

   * Compilers don't agree on their command line flags, e.g. -I for nhc13
     is a combination of ghc's -i/-I and a superset of hbc's -i.

   * If you upgrade your version of GHC, its libraries change in such a
     way that you have to recompile all your code: A compiler-generated
     entity (ds42, lvl1, tpl60, ...) from one version can mean quite a
     different thing in the next. Compare this with C libs: You don't have
     to completely re-install your whole *nix after switching to another
     C compiler. I'm not sure if things are better with nhc13 or hbc, but
     I fear they are not.

   * Libraries differ vastly between systems, although there is some hope
     for Hugs/GHC.

   * There is no universal tool for easy compilation of simple multi-module
     programs. OK, there is make, hmake, hbcmake, Hugs' import chasing...
     But there is a real need for something like Java's "javac Main.java"
     or Pizza's "pizza *.pizza". This topic pops up from time to time in
     the mailing lists, but no real progress has been made yet.

After these remarks here are my pleas:

   * Implementors: Write a Haskell-aware preprocessor. Include details
     about it in the next language report. A preprocessor-free and at
     the same time evolving language is a dream, but nothing more. In
     the meantime, at least make your systems agree on the preprocessor
     constants (see above).

   * While we are at preprocessing: What about a pragma {-# line 42 #-} ?
     Debugging Happy/Green Card/... output is no fun without it.

   * Write down and implement an (extensible) standard for the compilers'
     command line flags. Don't forget runtime flags, too.

   * Make compilation of simple programs a simple thing for Joe User.

   * The Haskell 98 libraries are nice, but by no means sufficient.
     A quick(!) agreement on libs to include in every system is necessary,
     because languages live and die with libraries. Compare Scheme and Java:
     Scheme's approach to "get everything right the first time" has lead
     to a crawling development (How many changes between R^4RS and R^5RS?
     Any standardized and non-trivial libs out there?). The Java hype on
     the other hand can mainly be attributed to the enormous availability
     of standard libs.

   * Programmers: Try to make your programs run on newer systems without
     any cpp-trickery, it's not that hard. The casual user should not need
     to be aware of the things aeons ago. The following example e.g. works
     on Hugs98 and GHC without anything special. nhc13 needs
     "-cpp '-DANCIENT_HASKELL_BEGIN=-}' '-DANCIENT_HASKELL_END={-'
     '-DHASKELL98_BEGIN=\end{code}' '-DHASKELL98_END=\begin{code}'".

     -- Main.lhs ----------------------------------------------------------
     \begin{code}
     
     import Char
     
     {- ANCIENT_HASKELL_BEGIN
     
     isAlphaNum = isAlphanum   -- one of my favourite changes in Haskell 98
     
     ANCIENT_HASKELL_END -}
     
     {-
     HASKELL98_BEGIN
     -}
     
     accumulate :: Monad a => [a b] -> a [b]
     accumulate = sequence   -- another one
     
     {-
     HASKELL98_END
     -}
     
     main :: IO ()
     main = do accumulate [ print (isAlphaNum 'x') ]
               putStrLn "This is portable!"
     
     \end{code}
     ----------------------------------------------------------------------

     Alas, this does not work with hbc (at least not with our version
     0.9999.4, 1997 Apr 09), because hbc first unlits and then pipes things
     through cpp. This kind of interaction should be specified in the
     report, too. (BTW: When using dove tails in the first line of literate
     scripts, Hugs fails with a "Program line next to comment". I stumbled
     over this when trying a different version of the above program).

With a big *sigh*,
   Sven
-- 
Sven Panne                                        Tel.: +49/89/2178-2235
LMU, Institut fuer Informatik                     FAX : +49/89/2178-2211
LFE Programmier- und Modellierungssprachen              Oettingenstr. 67
mailto:[EMAIL PROTECTED]            D-80538 Muenchen
http://www.pms.informatik.uni-muenchen.de/mitarbeiter/panne


Reply via email to