Re: Portability dreams
On Fri, May 28, 1999 at 04:18:57AM -0700, Simon Marlow wrote: [...] * Make compilation of simple programs a simple thing for Joe User. We could include ghcmake with ghc - then it's just a case of typing 'ghcmake' in a directory that contains at least Main.hs. I've got hmake to run with ghc4 with just a few Haskell 98 tweaks. As hmake doesn't depend on those lml things, I think that could be a way to go. Regards, Hannah.
RE: Portability dreams
[...] What you're really saying is: "if the libraries that you compiled your program against change, you have to recompile your program." Not doing this is dodgy at best, even for C. Sven Panne: Huh? Doing this perfectly fine, see Giuliano's mail. Let me elaborate: you can't link your program against a different version of the libraries than the ones it was originally compiled against, and expect it to work. It should also be the case that if you refrain from using -O then GHC won't export any of its internal symbols, and you should get much less recompilation. If you want more optimisation, then more info gets percolated from one module to another, so more recompilation is ncessary if you make changes. At least that is the tradeoff that GHC tries to give you. Simon
RE: Portability dreams
[ moved to glasgow-haskell-users from haskell ... ] Simon Marlow: [...] What you're really saying is: "if the libraries that you compiled your program against change, you have to recompile your program." Not doing this is dodgy at best, even for C. Sven Panne: Huh? Doing this perfectly fine, see Giuliano's mail. Let me elaborate: you can't link your program against a different version of the libraries than the ones it was originally compiled against, and expect it to work. That's why shared library major/minor versions exist, for one thing. A minor version change is supposed to be backwards compatible, but not a major version change. In GHC, we simply don't do this kind of versioning, although we could. It should be the case that, for a new version of a library: - if new version of the library only adds types and functions w.r.t. the old library interface, *and* - the locations of the exported functions/types remained the same (i.e. the module names in the library didn't change, and functions/types weren't moved from module to module), *and* - your program and the library were compiled with the same compiler, *and* - your program (or the library) was compiled without optimisation, then it should be possible to interchange library versions. The third restriction is necessary because of ghc's cross-module inlining and strictness analysis etc. Cheers, Simon
Re: Portability dreams
Sven Panne wrote: * 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. This is also partly true for c++ compilers. C compiles have a VERY simple symbols which is simply a name. More advanced languages have complex symbols that store additional necessary information. C++ stores type information in the symbol to resolve overloading. Ghc might do a similar thing. Than again Haskell overloading is nothing like C++ overloading so maybe not. * Libraries differ vastly between systems, although there is some hope for Hugs/GHC. The trick here is to have free portable libraries that can compile under any valid Haskell compiler so that if you need something simply include the library with your program. 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). I have a better idea. Have a pragma to allow the preprocessing to be done my some arbitrary haskell function. An optional module may be specified. The function should have the signature of String - String - [String] - String. The First string is the actual file, the second string is the name of the file being processed, the third is a list of preprocess options from the command line and the Output is the processed file. The pragma should look something like this {-# pre haskell function #-} or {-# prewModule module name haskell function #-}. Because the actual text may not a valid haskell program it should look for this string anywhere within the first 5 lines of the file. The function naturally should be totally independent from the rest of the file. If no preprocess is specified use a default one. This will allow different styles of literate programing to be used with out any additional fuss amoung other things. * 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. See my above note. -- Kevin Atkinson [EMAIL PROTECTED] http://metalab.unc.edu/kevina/
Re: Portability dreams
On Thu, May 27, 1999 at 03:51:57PM +0200, Sven Panne wrote: 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: [snip] And: no versioning of standard and run-time system libraries (unlike C) At least in the case of GHC. By way of explanation, I can have libc4, libc5 and libc6 happily coexist on my system. The run-time loader knows which programs need which library. This would go some way to alleviating the hassles with compiler and RTS changes. I'm not sure how much work this would involve! Giuliano.
Re: Portability dreams
Simon Marlow wrote: [...] We (GHC) are compatible with hbc in this area I think - hbc defines __HASKELL1__=3 for Haskell 1.3, we define __HASKELL1__=5 and __HASKELL98__. Hmmm, I must have missed the equation Haskell 1.5 = Haskell 98 somehow...:-) [...] I don't see a problem with standardising on either __HASKELL_98__ or __HASKELL98__, let's just pick one. Votes? The report calls it "Haskell 98" and not "Haskell98", so I vote for __HASKELL_98__. [...] What you're really saying is: "if the libraries that you compiled your program against change, you have to recompile your program." Not doing this is dodgy at best, even for C. Huh? Doing this perfectly fine, see Giuliano's mail. [...] GHC has this by the way - it's just that Happy doesn't generate them (yet...). Ooops, I didn't know this. Just another one for the report/docs. And please don't forget Green Card / HDirect (= Sigbjorn? :-). * Make compilation of simple programs a simple thing for Joe User. We could include ghcmake with ghc - then it's just a case of typing 'ghcmake' in a directory that contains at least Main.hs. ... and 'ghcmake MyMain1.hs', 'ghcmake MyMain2.hs', ... should be possible, too. I'd really love to have this for teaching. Cheers, Sven -- Sven PanneTel.: +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
Re: Portability dreams
Sven Panne writes: 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. I agree. And as the current maintainer of one of the Haskell systems, I'd like to work both with frustrated users and with other compiler writers to help make things easier. * Different language versions (1.3, 1.4, 98, ...) exist. This is inevitably so for any language which is in use, see C++, Java, ... Yes, but the explicit goal of Haskell 98 is that it should *replace* all earlier versions of the language. Any confusion between 1.3/1.4/98 code should only be temporary: as stable implementations of the 98 standard emerge, all 1.3/1.4 code should be converted or thrown away. (Why? Because we know that 98 will be around for a long time.) * There is no really portable way to level those language differences. IMHO, piping Haskell through cpp is a hack and has its own problems: nhc98 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... Yep. Part of the problem here is that none of these cpp symbols are documented, so one compiler writer has no idea what another compiler writer is using, and makes his/her own choice. Ideally, once the 98 standard settles down, none of these symbols will be required any longer. (But we will still be left with __GLASGOW_HASKELL__, __HBC__, and __NHC__ to determine compiler-specific differences as opposed to language-version differences. These symbols are not documented anywhere either!) * Libraries differ vastly between systems, although there is some hope for Hugs/GHC. Ideally, libraries should be stand-alone, portable to any Haskell system. And every Haskell system should have an easy standard way to link against ready-compiled-and-installed libraries. * There is no universal tool for easy compilation of simple multi-module programs. OK, there is make, hmake, hbcmake, Hugs' import chasing... Apart from Hugs, which is something of a special case in this regard, I believe hmake does exactly what you want across all the other platforms. I have been promising a release of hmake (separate from the nhc98 distribution) for a while now, but other things have got in the way. Unfortunately it will still be several weeks before I have the time to look at this again. * Write down and implement an (extensible) standard for the compilers' command line flags. Don't forget runtime flags, too. I think this is a good goal. Any volunteers? * The Haskell 98 libraries are nice, but by no means sufficient. A quick(!) agreement on libs to include in every system is necessary, I think a clean, portable, way of linking in arbitrary pre-compiled libraries (ideally determined automatically by hmake, based on import-chasing) is a desirable precursor. But I'd also like to see lots of portably-written libraries made available too. * 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}'". That's a little unfair! For one thing, you are comparing two Haskell 98 systems with a Haskell 1.3 system (soon to be obsolete). For another, you have chosen to use deliberately obfuscatory preprocessor directives. Were you to compare against nhc98, none of that trickery would be necessary. Regards, Malcolm
Re: Portability dreams
\begin{sarcasm} Malcolm Wallace wrote: [...] all 1.3/1.4 code should be converted or thrown away. HaXml? ;-)) [...] so one compiler writer has no idea what another compiler writer is using, "man grep" :-) [...] For another, you have chosen to use deliberately preprocessor directives. [...] Hmmm, defining symbols is obfuscating...? \end{sarcasm} Cheers, Sven -- Sven PanneTel.: +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
Re: Portability dreams
Kevin Atkinson wrote: [...] C++ stores type information in the symbol to resolve overloading. Ghc might do a similar thing. Than again Haskell overloading is nothing like C++ overloading so maybe not. There's nothing wrong with this kind of name mangling: When the library is updated, the names for procedures/functions/methods/members/[insert your favourite name here] of the same type stay the same. My guess is that lambda lifting and cross-module inlining are the real problems in the case of Haskell. [...] I have a better idea. Have a pragma to allow the preprocessing to be done my some arbitrary haskell function. [...] Hmmm, apart from the fact that in this case every compiler has to include some kind of Haskell interpreter it sounds like a real sledgehammer: Most people don't want to write a program transformer just to replace isAlphanum by isAlphaNum. "Keep the common case simple". As an additional tool it could be nice. Cheers, Sven -- Sven PanneTel.: +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
Portability dreams
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..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 PanneTel.: +49/89/2178-2235 LMU, Institut fuer Informatik FAX : +49/89/2178-2211 LFE Programmier- und Modellierungssprachen