ANN: H98 FFI Addendum 1.0, Release Candidate 12

2003-07-31 Thread Manuel M T Chakravarty
Dear Haskell Folks,

Release Candidate 12 of the H98 FFI Addendum 1.0 is now
available from

  http://www.cse.unsw.edu.au/~chak/haskell/ffi/

Since the release of RC 11 (12 June), there was only one
small change (which was already under discussion before RC
11 was published).  Hence, I consider Version 1.0 of the FFI
Addendum to be completed; no changes except linguistic ones
and plain error corrections will be accepted anymore for
this version.

Cheers,
Manuel

-=-

Changes since RC11:
* 5.5: Swapped argument order of `newForeignPtr' and `addForeignPtrFinalizer'

Note to FFI people, there were at least three votes
(Alastair, Sven, and me) for this change and none against.
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: *safe* coerce, for regular and existential types

2003-07-31 Thread Derek Elkins
Throughout this message you imply, if not outright state, that Dynamics
requires unsafeCoerce/unsafePerformIO.  This is simply not the case. 
GHC implements Dynamics with unsafeCoerce, or did last time I checked,
but it can easily be implemented using only existentials. (I presume
that this decision was made either for efficiency, simplicity, and/or
simply that another (readily useable) technique was not known when the
library was made.)

Anyways, as I have often mentioned, "A Lightweight Implementation of
Generics and Dynamics" has an unsafePerformIO/Coerce free implementation
of Dynamics as well as Generics as the title suggests.


___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: Text I/O library proposal, first draft

2003-07-31 Thread Glynn Clements

Ben Rudiak-Gould wrote:

> module System.TextIOFirstDraft (...) where
> 
> -- A BlockRecoder takes source and destination buffers and does some sort
> -- of translation between them. It returns the number of values (not
> -- bytes!) consumed and the number of values produced. It does not have to
> -- empty the input buffer or fill the output buffer on each call, but it
> -- must do something (i.e. it's not acceptable to return (0,0)). Coders
> -- will in general have internal state which is updated on each call.

It would be preferable if this wasn't all within the IO monad. It
shouldn't be necessary, even for stateful encodings.

-- 
Glynn Clements <[EMAIL PROTECTED]>
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


*safe* coerce, for regular and existential types

2003-07-31 Thread oleg

This message describes functions safeCast and sAFECoerce implemented
in Haskell98 with common, pure extensions. The functions can be used
to 'escape' from or to existential quantification and to make
existentially-quantified datatypes far easier to deal with. Unlike
Dynamic, the present approach is pure, avoids unsafeCoerce and
unsafePerformIO, and permits arbitrary multiple user-defined typeheaps
(finite maps from types to integers and values).

An earlier message [1] introduced finite type maps for
purely-functional conversion of monomorphic types to unique
integers. The solution specifically did not rely on Dynamic and
therefore is free from unsafePerformIO. This message shows that the
type maps can be used for a safe cast, in particular, for laundering
existential types. The code in this message does NOT use
unsafePerformIO or unsafeCoerce. To implement safe casts, we define a
function sAFECoerce -- which works just like its impure
counterpart. However the former is pure and safe. sAFECoerce is a
library function expressed in Haskell with common extension. The
safety of sAFECoerce is guaranteed by the typechecker itself.

This whole message is self-contained, and can be loaded as it is in
GHCi, given the flags
  -fglasgow-exts -fallow-undecidable-instances -fallow-overlapping-instances

This message was inspired by Amr Sabry's problem on existentials.  In
fact, it answers an unstated question in Amr Sabry's original message.


It has been observed on this list that existentially-quantified
datatypes are not easy to deal with [2]. For example, suppose we have
a value of a type

> data EV = forall a. (TypeRep a TI)=> EV a

(please disregard the second argument of TypeRep for a moment).

The constructor EV wraps a value. Suppose we can guess that the
wrapped value is actually a boolean. Even if our guess is correct, we
*cannot* pass that value to any function of booleans:

*> *Main> case (EV False) of (EV x) -> not x
*>
*> :1:
*> Inferred type is less polymorphic than expected
*> Quantified type variable `a' is unified with `Bool'
*> When checking an existential match that binds
*> x :: a
*> and whose type is EV -> Bool
*> In a case alternative: (EV x) -> not x

A quantified type variable cannot be unified with any regular type --
or with another quantified type variable. Values of existentially
quantified types cannot be passed to monomorphic functions, or to
constrained polymorphic functions (unless all their constrains have
been mentioned in the declaration of the existential). That limitation
guarantees safety -- on the other hand, it significantly limits the
convenience of existential datatypes [2].

To overcome the limitation, it _seemed_ that we had to sacrifice
purity. If we are positive that a particular existentially quantified
value has a specific type (e.g., Bool), we can use unsafeCoerce to
cast the value into the type Bool [3]. This approach is one of the
foundations of the Dynamic library. The other foundation is an ability
to represent a type as a unique run-time value, provided by the
methods of the class like TypeRep. Given an existentially quantified
value and a value of the desired type, Dynamic compares type
representations of the two values. If they are the same, we can
confidently use unsafeCoerce to cast the former into the type of the
latter.

This works, yet leaves the feeling of dissatisfaction. For one thing,
we had to resort to an impure feature. More importantly, we placed our
trust in something like TypeRep and its members, that they give an
accurate and unique representation of types. But what if they lie to
us, due to a subtle bug in their implementation? What if they give the
same representation for two different types? unsafeCoerce will do its
dirty work nevertheless. Using the result would lead to grave
consequences, however.

This message describes sAFECoerce and the corresponding safe cast.
Both functions convert the values of one type into the target type.
One or both of these types may be existentially quantified.  When the
source and the target types are the same, both functions act as the
identity function. The safe cast checks that the type representations
of the source and the target types are the same. If they are, it
invokes sAFECoerce. Otherwise, we monadically fail. The function
sAFECoerce does the conversion without any type checking. It always
returns the value of the target type. If the source type was the same
as the target type, the return value has the same "bit pattern" as the
argument. If the types differ, the return value is just some default
value of the right type. The user can specify the default value as he
wishes.

Therefore, we can now write

*> *Main> case (EV False) of (EV x) -> not $ sAFECoerce x
*> True

We can also try

*> *Main> case (EV 'a') of (EV x) -> not $ sAFECoerce x
*> *** Exception: Prelude.undefined

The default value was 'undefined'.

The function safeCast is actually trivial

> safeCas

Re: Text I/O library proposal, first draft

2003-07-31 Thread John Meacham
presumably if you are doing random access on the file, it is in a known
nonarbitrary text encoding (like utf8). in which case you can
read/access the file with the binary routines and just use the
appropriate text conversions to get data out. 
John

On Thu, Jul 31, 2003 at 03:55:44PM -0700, Hal Daume wrote:
> Hi Ben,
> 
> > Bad things:
> > 
> >   * There's no way to implement fgetpos/fsetpos type functionality,
> > because coders don't expose their internal state. (In fact, there
> > would need to be a way to explicitly copy the state, since it may
> > well include IORefs, Ptrs, etc.) Is this a serious problem?
> 
> Yes!  This is an enormously serious problem.  At least for me.
> 
> It's not a problem for writing files, but I really really really need
> this functionality when reading files.  Reason: I'm often tooling around
> in very large (1gb or greater) files which happen to be sorted on some
> sort of index and I need to do binary search in them.  To load all the
> file into Haskell or to do linear search is impossible.
> 
> Other than that, I rather like the design.
> 
>  - Hal
> -- 
> Haskell mailing list
> [EMAIL PROTECTED]
> http://www.haskell.org/mailman/listinfo/haskell
> 

-- 
---
John Meacham - California Institute of Technology, Alum. - [EMAIL PROTECTED]
---
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


RE: Text I/O library proposal, first draft

2003-07-31 Thread Hal Daume
Hi Ben,

> Bad things:
> 
>   * There's no way to implement fgetpos/fsetpos type functionality,
> because coders don't expose their internal state. (In fact, there
> would need to be a way to explicitly copy the state, since it may
> well include IORefs, Ptrs, etc.) Is this a serious problem?

Yes!  This is an enormously serious problem.  At least for me.

It's not a problem for writing files, but I really really really need
this functionality when reading files.  Reason: I'm often tooling around
in very large (1gb or greater) files which happen to be sorted on some
sort of index and I need to do binary search in them.  To load all the
file into Haskell or to do linear search is impossible.

Other than that, I rather like the design.

 - Hal
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Text I/O library proposal, first draft

2003-07-31 Thread Ben Rudiak-Gould
[Crossposted to Haskell and Libraries. Replies to Libraries.]

{-
Good things about this text library design:

  * Efficient implementation should be straightforward

  * Character coder interface is public, so users can supply their own
encodings, or write coder transformers (there are some in the
proposal)

Bad things:

  * There's no way to implement fgetpos/fsetpos type functionality,
because coders don't expose their internal state. (In fact, there
would need to be a way to explicitly copy the state, since it may
well include IORefs, Ptrs, etc.) Is this a serious problem?
-}


module System.TextIOFirstDraft (...) where

-- A BlockRecoder takes source and destination buffers and does some sort
-- of translation between them. It returns the number of values (not
-- bytes!) consumed and the number of values produced. It does not have to
-- empty the input buffer or fill the output buffer on each call, but it
-- must do something (i.e. it's not acceptable to return (0,0)). Coders
-- will in general have internal state which is updated on each call.

type BlockRecoder from to =
  Ptr from -> BlockLength -> Ptr to -> BlockLength
   -> IO (BlockLength,BlockLength)

type TextEncoder = BlockRecoder Word32 Octet
type TextDecoder = BlockRecoder Octet Word32

-- IO TextEncoder and IO TextDecoder below denote "coder factories" which
-- produce a new coder in its initial state each time they're called.

compatibilityEncoder :: IO TextEncoder  -- "mod 256"
currentLocaleEncoder :: IO TextEncoder
iso88591Encoder :: IO TextEncoder
latin1Encoder = iso88591Encoder

utf8Encoder, utf16BEEncoder, utf16LEEncoder,
  utf32BEEncoder, utf32LEEncoder :: IO TextEncoder

compatibilityDecoder :: IO TextDecoder
currentLocaleDecoder :: IO TextDecoder
iso88591Decoder :: IO TextDecoder
latin1Decoder = iso88591Decoder

utf8Decoder, utf16BEDecoder, utf16LEDecoder,
  utf32BEDecoder, utf32LEDecoder :: IO TextDecoder

-- An attempt at supporting setlocale-type locale strings.

lookupEncoder :: String -> Maybe (IO TextEncoder)
lookupDecoder :: String -> Maybe (IO TextDecoder)

-- prependBOM takes an existing UTF encoder and causes it to prepend
-- a BOM (byte-order mark) to its output. autodetectUTF takes an existing
-- decoder and modifies it to check for a BOM, switching to the
-- appropriate type of UTF decoding if one is found.

prependBOM :: IO TextEncoder -> IO TextEncoder
autodetectUTF :: IO TextDecoder -> IO TextDecoder

-- Attaches a TextInputChannel to the supplied InputChannel. After
-- this operation the InputChannel should be considered owned by the
-- TextInputChannel; any attempt to use it directly will cause
-- unpredictable results. This takes a decoder factory rather than a
-- decoder to prevent the error of attaching the same decoder to more than
-- one channel.

icAttachTextDecoder :: InputChannel -> IO TextDecoder -> IO TextInputChannel

ticGetChar :: TextInputChannel -> IO Char
ticGetLine :: TextInputChannel -> IO String
ticLazyGetContents :: TextInputChannel -> IO String

ocAttachTextEncoder :: OutputChannel -> IO TextEncoder -> IO TextOutputChannel

tocPutChar  :: TextOutputChannel -> Char -> IO ()
tocPutStr   :: TextOutputChannel -> String -> IO ()
tocPutStrLn :: TextOutputChannel -> String -> IO ()

-- ... etc ...


-- Ben

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


RE: a breaking monad

2003-07-31 Thread Hal Daume
> This looks like a bizarre rendition of the Error/Exception monad.

Yes, of course.  *Hal slaps himself*

Thanks.

> Also, your motivating example is ambiguous.  I think you mainly care
> about the case where the test is testing for some "exceptional"
> condition.  I personally wouldn't want to use this style every place I
> would use an if.

Definitely not!  :)

 - Hal
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Raw I/O library proposal, second (more pragmatic) draft

2003-07-31 Thread Ben Rudiak-Gould
[Crossposted to Haskell and Libraries. Replies to Libraries.]


-- More comments, please. Bad names? Important missing functionality?
-- Still unimplementable?


module System.RawIOSecondDraft (...) where

data File   -- now essentially a file handle
data InputChannel   -- renamed for less confusing function prefixes
data OutputChannel

-- | A Moniker is a slight generalization of a pathname. In principle this
-- could be extended to support URIs, host:port SSL connections, memory
-- buffers, and so on, though it might be better to give them their own
-- functions.

-- "Compatibility" refers to compatibility with existing Haskell
-- implementations, which treat Char values like octets. RawPathname is
-- there to avoid an octet -> string -> octet translation in cases where
-- that's undesirable. This is slightly problematic on Win32, where
-- pathnames really *are* strings.

type Moniker
  = Pathname String
  | CompatibilityPathname String
  | RawPathname [Octet]

{- if supported, maybe:
  | DirectoryEntry Directory String
  | ResourceFork Moniker
  | NamedFork String Moniker
-}


-- * File and channel creation functions

-- I still use "lookup" rather than "open" to emphasize that there's an
-- irreversible and time-dependent translation going on here.

lookupFileRO  :: Moniker -> IO File
lookupFileRW  :: Moniker -> IO File
lookupInputChannel:: Moniker -> IO InputChannel
lookupOutputChannelAppend :: Moniker -> IO OutputChannel
createOutputChannel   :: Moniker -> IO OutputChannel

-- * File access functions

-- | Indicates that a File value will never be used again. Calling
-- fRelease is not mandatory, but it assists the implementation in
-- closing file handles as early as possible. It is an error to use the
-- argument in any way after making this call.

fRelease :: File -> IO ()

-- | Returns a new File value which is identical to the argument except
-- that calling fRelease on one does not affect the other.

fDup :: File -> IO File

-- | Returns True if fRelease has not been called on the File value.

fIsValid :: File -> IO Bool

-- | Reads from a file to a memory buffer. If the read extends beyond the
-- end of the file, the extra buffer space is filled with zeroes and the
-- return value is the number of octets which actually came from the file.
-- Otherwise the return value is the same as the length argument.

fReadBuf :: File -> FilePos -> BlockLength -> Ptr Word8 -> IO BlockLength

-- | Writes to a file from a memory buffer.

fWriteBuf:: File -> FilePos -> BlockLength -> Ptr Word8 -> IO ()

-- | Returns the current size of the file.

fGetSize :: File -> IO FilePos

-- | If the size argument is less than the current file size, the file size
-- is reduced, destroying any octets beyond the new end of the file. If the
-- size argument is greater than the current file size, the file may or may
-- not be increased in length. If it is increased, the contents of the file
-- beyond the old end of file are undefined.

fSetSize :: File -> FilePos -> IO ()

fIsReadable  :: File -> IO Bool
fIsWritable  :: File -> IO Bool

-- * Layering channels on files

-- | Opens an input channel (octet source) which reads from the specified
-- file, starting at the specified offset. Effectively fDups the File
-- argument, so the original File value may be released at any later time
-- without affecting the channel.

fInputChannelFrom :: File -> FilePos -> IO InputChannel

-- | Opens an output channel (octet source) which writes to the specified
-- file, starting at the specified offset. Because input and output
-- channels may be buffered, the result of an fRead call on a file region

fOutputChannelFrom :: File -> FilePos -> IO OutputChannel

-- | Like fInputChannelFrom, but stops after reading the octet which
-- immediately precedes the second FilePos argument, or at end of file,
-- whichever comes first.

fInputChannelFromTo :: File -> FilePos -> FilePos -> IO InputChannel

-- * Standard channels

stdin :: InputChannel
stdout, stderr :: OutputChannel

-- * Input channel access functions

-- | Indicates that no more octets will be read from the InputChannel.
-- It is not necessary to call this function if all available octets
-- have already been read.

icRelease :: InputChannel -> IO ()

icGet :: InputChannel -> IO Octet

icGetBuf  :: InputChannel -> Ptr a -> BlockLength -> IO BlockLength

icAtEnd   :: InputChannel -> IO Bool

-- | Returns the File associated with its argument, if any. May fail even
-- on a channel created with fInputChannel, since the channel is permitted
-- to release its internal File value on reaching end-of-input. May succeed
-- on a channel not created with fInputChannel, such as stdin. The caller
-- is responsible for releasing the returned File.

icTellFile :: InputChannel -> IO Maybe File

-- | Returns the current read offset in the underlying file, if any. May
-- succeed even if icTellFile fails. Always succe

Re: a breaking monad

2003-07-31 Thread Derek Elkins
On Thu, 31 Jul 2003 13:18:40 -0700
"Hal Daume" <[EMAIL PROTECTED]> wrote:

> so, my questions are: does this exist in some other form I'm not aware
> of?  is there something fundamentally broken about this (sorry for the
> pun)?  any other comments, suggestions?

This looks like a bizarre rendition of the Error/Exception monad.

I believe the function "breakable" would be fairly accurately
represented with '\b -> runErrorT b >>= either return return' and use
throwError for break.

Also, your motivating example is ambiguous.  I think you mainly care
about the case where the test is testing for some "exceptional"
condition.  I personally wouldn't want to use this style every place I
would use an if.

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


a breaking monad

2003-07-31 Thread Hal Daume
i've noticed in a lot of my imperative-looking monadic code, i have lots
of stuff that looks like:

> ... = do
>   q <- some test
>   if q
> then return some constant
> else do
>   major code body here

lots of these things embedded makes the code hard to read and introduces
way too much indentation (i'm one of those who doesn't like curly
braces).

one solution to this is to write it as:

> ... = do
>   q <- some test
>   if q then return some constant else do
>   major code body here

but this is ugly, IMO :).

my solution was to fashion a monad transformer that supports a break
statement.  basically, it looks like:

> data Break b m a = Break { runBreak :: m (Maybe b, a) }
> 
> instance MonadTrans (Break b) where
>   lift x = Break $ do a <- x; return (Nothing, a)
> 
> instance Monad m => Monad (Break b m) where
>   return a = Break $ return (Nothing, a)
>   b >>= k  = Break $ runBreak b >>= \ (broken, a) ->
>   case broken of
> Nothing -> runBreak (k a)
> Just br -> return (Just br, undefined)
> 
> breakable :: Monad m => Break a m a -> m a
> breakable b = runBreak b >>= \ (broken, a) ->
> case broken of
>   Nothing -> return a
>   Just br -> return br
> 
> break :: Monad m => b -> Break b m a
> break b = Break (return (Just b, undefined))

essentially you introduce code blocks with the "breakable" function and
then can break with the break function.  a useful combinator i've found
is:

> breaksTo :: Monad m => m Bool -> b -> Break b m ()
> breaksTo k b = lift k >>= \x -> if x then break b else return ()

using this, you can write stuff which looks like:

> test1 :: IO [String]
> test1 = breakable $ do
>   lift $ putStrLn "Enter something, or nothing to quit:"
>   l <- lift $ getLine
>   when (null l) $ break []
>   rest <- lift test1
>   return (l:rest)
> 
> test2 :: IO ()
> test2 = breakable $ repeatM $ do 
>   x <- lift $ getLine >>= passThrough putStrLn
>   when (null x) $ break ()
> 
> test3 :: Handle -> IO [String]
> test3 h = breakable $ do
>   hIsEOF h `breaksTo` []
>   lift $ do 
> l <- hGetLine h
> rest <- test3 h
> return (l:rest)

where passThrough and repeatM are:

> repeatM :: Monad m => m () -> m ()
> repeatM x = x >> repeatM x
> 
> passThrough :: Monad m => (a -> m b) -> a -> m a
> passThrough f a = f a >> return a

so, my questions are: does this exist in some other form I'm not aware
of?  is there something fundamentally broken about this (sorry for the
pun)?  any other comments, suggestions?


--
 Hal Daume III   | [EMAIL PROTECTED]
 "Arrest this man, he talks in maths."   | www.isi.edu/~hdaume
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: ANNOUNCE: GHC version 6.0.1

2003-07-31 Thread Wolfgang Thaller

   =
The (Interactive) Glasgow Haskell Compiler -- version 6.0.1
   =
A Mac OS X package id now available at:

http://www.uni-graz.at/imawww/haskell/GHC.6.0.1.dmg

Cheers,

Wolfgang

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


RE: New Haskell and FP merchandise logos for review

2003-07-31 Thread David Bergman
I seldom post things here, but Fritz, you are a genius!

/David


___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


New Haskell and FP merchandise logos for review

2003-07-31 Thread Fritz K Ruehr
John Peterson recently handed over control of the Haskell Merchandise
area of haskell.org to me and, in celebration, I've created a bunch of
provisional designs for new Haskell, FP and types-related "swag".

The logos include the original and new haskell.org logos and about 
15 others, designed around traditional T-shirt logo aesthetics (puns, 
strident dogmatic posturings and mild sexual suggestion). I've tried to 
represent a range of Haskell community viewpoints, from pure/theory to 
systems/"hacker". (A couple of the designs will likely appeal to a very
limited audience, for example the catamorphism evaluation law expressed 
with *real* banana brackets ... ).

For now the logos are just graphic files in PNG format, available from
this URL, linked from thumbnails and accompanied by a few comments: 



My intent is to convert them, as called for, into products on the 
CafePress site and link them in via the Haskell Merchandise page
(see the docs at the URL for more details).

I'm not sure exactly what the protocol for selecting logo/product 
combinations should be, but for now I will just take e-mails from 
people (if this becomes laborious maybe a Wiki page would be better). 
I am open to suggestions for changes or additions, or to other peoples' 
designs. Note that neither I nor haskell.org will make any profit, 
but there is some possibility of using a modest charge to off-set a 
more convenient CafePress set-up (again, go to the URL for details).

  --  Fritz Ruehr
  
PS: replies to haskell-cafe please!

PPS to whomever requested the new haskell.org logo: sorry for the delay, 
I will consider your request as first in the queue and open a new store 
presently. But write me with your specific interest for a product 
(i.e., white t-shirt, grey t-shirt, tank-top, etc.).

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


RE: Ann: HAllInOne bug fix release

2003-07-31 Thread Koen Claessen
Simon Peyton-Jones wrote:

 | I don't know why the all in one version might go
 | slower though.

How about some (artificial) cut-offs during optimization
phases? Optimizing a hugs module could lead to some kind of
combinatorial explosion (which gets cut off by the
optimizer) which does not happen when you have separate
modules?

Just my 2 öre!

/Koen

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


RE: Ann: HAllInOne bug fix release

2003-07-31 Thread Graham Klyne
At 08:44 31/07/03 +0100, Simon Peyton-Jones wrote:
I don't know why the all in one version might go slower though
Virtual memory thrashing?  (Hal did say something about needing lots of RAM.)

#g

---
Graham Klyne
<[EMAIL PROTECTED]>
PGP: 0FAA 69FF C083 000B A2E9  A131 01B9 1C7A DBCA CB5E
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


RE: Ann: HAllInOne bug fix release

2003-07-31 Thread Simon Peyton-Jones
Something very odd is going on.  GHC does not generate programs than run
3x faster between GHC versions.  

If, perhaps, you compiled both without -O, no cross-module inlining
takes place.  That would account for a big slow down when using separate
compilation.  I see you use -O2 this time.

I don't know why the all in one version might go slower though

S

| -Original Message-
| From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On
Behalf Of Hal Daume
| Sent: 31 July 2003 00:23
| To: Wolfgang Jeltsch; The Haskell Mailing List
| Subject: RE: Ann: HAllInOne bug fix release
| 
| Ah, apparently it is not (at least not the Cygwin version).
| 
| I recompiled NHC with GHC -O2, both the separate compilation version
and
| the all-in-over version.  Averaged over five runs, we see that the
| separate compilation version is actually *faster* than the ai1
version:
| 
| standard nhc compiled with ghc:
| 
| real0m27.167s
| user0m9.991s
| sys 0m1.304s
| 
| nhc all-in-one:
| 
| real0m31.411s
| user0m10.007s
| sys 0m1.299s
| 
| 
| 
| i am completely unable to explain this.  someone want to hazard a
guess?
| 
|  - hal, who is a bit disappointed now :(
| 
|  --
|  Hal Daume III   | [EMAIL PROTECTED]
|  "Arrest this man, he talks in maths."   | www.isi.edu/~hdaume
| 
| 
| > -Original Message-
| > From: [EMAIL PROTECTED]
| > [mailto:[EMAIL PROTECTED] On Behalf Of Wolfgang Jeltsch
| > Sent: Wednesday, July 30, 2003 2:59 PM
| > To: The Haskell Mailing List
| > Subject: Re: Ann: HAllInOne bug fix release
| >
| >
| > On Wednesday, 2003-07-30, 23:36, CEST, Hal Daume III wrote:
| > > [...]
| >
| > > A few people have asked me for speed-up results from
| > All-In-One-ifying code,
| > > so here's a good one.  We take two versions of NHC.  One is
| > the original
| > > binary distribution and the other is the All-In-One-ified
| > version, compiled
| > > by GHC.
| >
| > Hi,
| >
| > is the original binary distribution compiled with GHC? If
| > not, the speed-up
| > may also be the result of using a different compiler (i.e., GHC).
| >
| > > [...]
| >
| > Wolfgang
| >
| > ___
| > Haskell mailing list
| > [EMAIL PROTECTED]
| > http://www.haskell.org/mailman/listinfo/haskell
| >
| ___
| Haskell mailing list
| [EMAIL PROTECTED]
| http://www.haskell.org/mailman/listinfo/haskell


___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell