Re: [Haskell-cafe] two problems with Data.Binary and Data.ByteString
So am I understanding you correctly that you believe this is not a bug? That the use Data.Binary.decodeFile function leaks a file descriptor and this is proper behavior? I still don't understand your explanation of how isEmpty can return True without having read to EOF. The ByteString continues to contain more data until an EOF is reached. Doesn't one of return (B.null s && L.null ss) force getContents to read until EOF? On Wed, 13 Aug 2008, Don Stewart wrote: newsham: Ok, surely at least everyone must agree that this is a bug: force :: Word8 -> IO Word8 force x = print x >> return x -- force = return . (`using` rnf) main = do d <- force =<< decodeFile stateFile encodeFile stateFile d where stateFile = "1word32.bin" test8.hs: 1word32.bin: openBinaryFile: resource busy (file is locked) Remember that decodeFile f = liftM decode (L.readFile f) and readFile :: FilePath -> IO ByteString readFile f = openBinaryFile f ReadMode >>= hGetContents where hGetContents sits in a loop, reading chunks, loop = do c <- S.hGetNonBlocking h k if S.null c then do eof <- hIsEOF h if eof then hClose h >> return Empty else hWaitForInput h (-1) >> loop else do cs <- lazyRead return (Chunk c cs) while isEmpty is just, isEmpty :: Get Bool isEmpty = do S s ss _ <- get return (B.null s && L.null ss) That is, it checks the parsed chunk, it doesn't demand any more reading be done. So the only way you're going to get that Handle closed by readFile is to ensure you read till EOF is hit. After you decode, just ask keep asking for bytes till EOF, or close it yourself, decodeFile f = do h <- openFile f ReadMode ss <- L.hGetContents h let e = decode ss rnf e `seq` hClose h or some such, where you can confirm the decoding as taken place. Tim Newsham http://www.thenewsh.com/~newsham/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] two problems with Data.Binary and Data.ByteString
newsham: > Ok, surely at least everyone must agree that this is a bug: > > force :: Word8 -> IO Word8 > force x = print x >> return x > -- force = return . (`using` rnf) > > main = do > d <- force =<< decodeFile stateFile > encodeFile stateFile d > where stateFile = "1word32.bin" > > test8.hs: 1word32.bin: openBinaryFile: resource busy (file is locked) > Remember that decodeFile f = liftM decode (L.readFile f) and readFile :: FilePath -> IO ByteString readFile f = openBinaryFile f ReadMode >>= hGetContents where hGetContents sits in a loop, reading chunks, loop = do c <- S.hGetNonBlocking h k if S.null c then do eof <- hIsEOF h if eof then hClose h >> return Empty else hWaitForInput h (-1) >> loop else do cs <- lazyRead return (Chunk c cs) while isEmpty is just, isEmpty :: Get Bool isEmpty = do S s ss _ <- get return (B.null s && L.null ss) That is, it checks the parsed chunk, it doesn't demand any more reading be done. So the only way you're going to get that Handle closed by readFile is to ensure you read till EOF is hit. After you decode, just ask keep asking for bytes till EOF, or close it yourself, decodeFile f = do h <- openFile f ReadMode ss <- L.hGetContents h let e = decode ss rnf e `seq` hClose h or some such, where you can confirm the decoding as taken place. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] two problems with Data.Binary and Data.ByteString
Ok, surely at least everyone must agree that this is a bug: force :: Word8 -> IO Word8 force x = print x >> return x -- force = return . (`using` rnf) main = do d <- force =<< decodeFile stateFile encodeFile stateFile d where stateFile = "1word32.bin" test8.hs: 1word32.bin: openBinaryFile: resource busy (file is locked) the built-in Data.Binary.decodeFile function doesn't close its handle when it is done (same reason as my earlier examples). However, I think probably the real blame here should probably go to Data.Binary which doesn't attempt to check that it has consumed all of its input after doing a "decode". If "decode" completes and there is unconsumed data, it should probably raise an error (it already raises errors for premature EOF). There's no reason for it not to, since it does not provide the unconsumed data to the caller when its done, anyway... I would have expected this to fix my problems: binEof :: Get () binEof = do more <- not <$> isEmpty when more $ error "expected EOF" decodeFully :: Binary b => B.ByteString -> b decodeFully = runGet (get << binEof) where a << b = a >>= (\x -> b >> return x) but even when using decodeFully, it still doesn't close the handle. Shouldn't Data.Binary.Get.isEmpty force a file handle close in the case that it returns True? Tim Newsham http://www.thenewsh.com/~newsham/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Bug with QuickCheck 1.1 and GHC 6.8.2
The bug is in the "variant" function in QuickCheck. I replaced variant :: Int -> Gen a -> Gen a variant v (Gen m) = Gen (\n r -> m n (rands r !! (v+1)) where rands r0 = r1 : rands r2 where (r1, r2) = split r0 with variant :: Int -> Gen a -> Gen a variant v (Gen m) = Gen (\n r -> m n (rands r !! v')) where v' = abs (v+1) `mod` 1 rands r0 = r1 : rands r2 where (r1, r2) = split r0 and now everything works fine. "1" seems like a reasonable value here, but one could hard-code a lower or higher value as well. Can someone make sure this gets fixed in the next version of QuickCheck? I'm not sure who the maintainer is. Patrick ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] two problems with Data.Binary and Data.ByteString
On Wed, Aug 13, 2008 at 5:02 PM, Tim Newsham <[EMAIL PROTECTED]> wrote: > > However, I think probably the real blame here should probably go > to Data.Binary which doesn't attempt to check that it has consumed > all of its input after doing a "decode". If "decode" completes > and there is unconsumed data, it should probably raise an error > (it already raises errors for premature EOF). There's no reason > for it not to, since it does not provide the unconsumed data to > the caller when its done, anyway... > Would the error be raised in 'decode' or in 'runGet'? On a project in progress I rely on 'runGet' to toss out padding bytes for me. -Antoine ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Bug with QuickCheck 1.1 and GHC 6.8.2
I'm running into problems with generating an arbitrary function of type Double -> Double. Specifically, the following code: {-# LANGUAGE PatternSignatures #-} import Test.QuickCheck import Text.Show.Functions prop_ok (f :: Double -> Double) = f (-5.5) `seq` True prop_bug (f :: Double -> Double) = f (-5.6) `seq` True main = do putStr "prop_ok:\t" >> quickCheck prop_ok putStr "prop_bug:\t" >> quickCheck prop_bug On an Intel Core 2 Duo running Mac OS 10.5.4 with GHC 6.8.2 the output I get is prop_ok:OK, passed 100 tests. prop_bug: Test: Prelude.(!!): negative index On Intel Xeon running RedHat with GHC 6.8.2 both tests hang. Has anyone seen this before? Is it fixed in QuickCheck2? Thanks, Patrick ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: whatever happened to sendFile?
John Meacham <[EMAIL PROTECTED]> wrote: > There isn't a standard unix sendfile, while a few different > ones have functions called 'sendfile', they have different > meanings/prototypes in general. If 'sendfile(2)' is going to > be exposed, it should be in a low level platform specific > library, however, since you are dealing with deciding to use > unportable behavior, it is hard to see what this will gain > over a manual FFI wrapper. Well, for my purposes, I need to have at least three of them -- Linux, Darwin (BSD) and Windows. However, I think you are ultimately right, the heterogenity of sendfile() suggests that one should not stomp all over it with yet another variant. Maybe a reasonable compromise is a function that is more limited by design, with a distinctive name -- `fileSock`? -- that offers access to a universal subset of the functionality of sendfile() -- namely, pushing a file's contents over a socket efficiently. -- _jsn ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: whatever happened to sendFile?
On Wed, Aug 13, 2008 at 03:40:43PM -0700, Jason Dusek wrote: > A cross platfrom implementation would cover the case we most > care about -- writing services that pass static files back to > clients -- but would have to cut some functionality from the > *NIX sendfile(). There isn't a standard unix sendfile, while a few different ones have functions called 'sendfile', they have different meanings/prototypes in general. If 'sendfile(2)' is going to be exposed, it should be in a low level platform specific library, however, since you are dealing with deciding to use unportable behavior, it is hard to see what this will gain over a manual FFI wrapper. John -- John Meacham - ⑆repetae.net⑆john⑈ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: whatever happened to sendFile?
It looks like there could be a Haskell sendfile for Windows as as well *NIX. However, the *NIX implementations are: :: File Descriptor -> File Descriptor -> IO () while the Windows version is: :: File Descriptor -> Socket -> IO () A cross platfrom implementation would cover the case we most care about -- writing services that pass static files back to clients -- but would have to cut some functionality from the *NIX sendfile(). |...for Windows...| http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.sendfile.aspx -- _jsn ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] whatever happened to sendFile?
On 2008 Aug 13, at 18:25, Jason Dusek wrote: Brandon S. Allbery KF8NH <[EMAIL PROTECTED]> wrote: Right. I intended that to be a heads-up in both directions: it is not simply a library convenience function, so one needs to think about when to use it. In particular, it's possible that overuse of sendfile() in the wrong circumstances will create additional system load instead of reducing it. Can you say more about this? I assume that sending static images back and forth is a good fit for sendfile(). Your previously stated use case sounds like a good fit. I can easily imagine sendfile() implementations starving other network operations, though (and IIRC linux's early sendfile() implementation did so). It's essentially an optimization specific to web servers. -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] [EMAIL PROTECTED] system administrator [openafs,heimdal,too many hats] [EMAIL PROTECTED] electrical and computer engineering, carnegie mellon universityKF8NH ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] whatever happened to sendFile?
Brandon S. Allbery KF8NH <[EMAIL PROTECTED]> wrote: > Right. I intended that to be a heads-up in both directions: > it is not simply a library convenience function, so one needs > to think about when to use it. In particular, it's possible > that overuse of sendfile() in the wrong circumstances will > create additional system load instead of reducing it. Can you say more about this? I assume that sending static images back and forth is a good fit for sendfile(). -- _jsn ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] What's in a name?
> Do we have a formal convention for the naming of > packages and/or the naming of the modules they contain? There is a recommended set of categories and in general I believe library authors try and follow the previously established names. > How are name > collisions supposed to be avoided? In the case of pureMD5 I looked at the other modules and decided to name mine something with a proper hierarchy that doesn't collide with 'Crypto'. Hence the extra "Pure" part of the module name. I believe that an informal process, such as what I did, is much better than formalizing every aspect of Haskell/Hackage libraries. The cost in terms of processes / bureaucracy are just too much to formalize everything. Suggestion: Have Hackage warn when a library is uploaded that has Module conflicts with other libraries. Thomas ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] two problems with Data.Binary and Data.ByteString
newsham: > >Should the file be closed when the last byte is read (in this > >case its definitely reading all four bytes) or when the first > >byte after that is read (in this case it probably doesn't > >attempt to read more than 4 bytes)? > > I'll answer my own question. Both Prelude.readFile and > Data.ByteString.Lazy.Char8.readFile will keep the file open > after reading the last byte and close it when trying to > read further. Proof: > > module Main where > import Control.Applicative > -- import qualified Data.ByteString.Lazy.Char8 as B > import Prelude as B > > stateFile = "1word32.bin" > main = do > x <- B.take 4 <$> B.readFile stateFile > -- x <- B.take 5 <$> B.readFile stateFile > print x > B.writeFile stateFile x > > This works for Prelude and ByteString when taking 5 (there are > exactly 4 bytes in "1word32.bin") and fail when taking 4. > > I'm not sure that this behavior is so bad.. there might be some > advantages... but it might be nice to have it close after the last > byte is read... > > However, I think probably the real blame here should probably go > to Data.Binary which doesn't attempt to check that it has consumed > all of its input after doing a "decode". If "decode" completes > and there is unconsumed data, it should probably raise an error > (it already raises errors for premature EOF). There's no reason > for it not to, since it does not provide the unconsumed data to > the caller when its done, anyway... > This is perhaps a use case for Data.Binary.Strict then. -- Don ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] two problems with Data.Binary and Data.ByteString
Should the file be closed when the last byte is read (in this case its definitely reading all four bytes) or when the first byte after that is read (in this case it probably doesn't attempt to read more than 4 bytes)? I'll answer my own question. Both Prelude.readFile and Data.ByteString.Lazy.Char8.readFile will keep the file open after reading the last byte and close it when trying to read further. Proof: module Main where import Control.Applicative -- import qualified Data.ByteString.Lazy.Char8 as B import Prelude as B stateFile = "1word32.bin" main = do x <- B.take 4 <$> B.readFile stateFile -- x <- B.take 5 <$> B.readFile stateFile print x B.writeFile stateFile x This works for Prelude and ByteString when taking 5 (there are exactly 4 bytes in "1word32.bin") and fail when taking 4. I'm not sure that this behavior is so bad.. there might be some advantages... but it might be nice to have it close after the last byte is read... However, I think probably the real blame here should probably go to Data.Binary which doesn't attempt to check that it has consumed all of its input after doing a "decode". If "decode" completes and there is unconsumed data, it should probably raise an error (it already raises errors for premature EOF). There's no reason for it not to, since it does not provide the unconsumed data to the caller when its done, anyway... Thoughts? Tim Newsham http://www.thenewsh.com/~newsham/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] "Prompt" Monad
No problem. Let me know what you end up doing with it, or if you have any questions! -- ryan On Tue, Aug 12, 2008 at 11:32 PM, Martin Hofmann <[EMAIL PROTECTED]> wrote: > Thanks a lot. That is exactly what I have been looking for. > > > Cheers, > > Martin > > > On Tue, 2008-08-12 at 10:28 -0700, Ryan Ingram wrote: >> Latest code is on hackage: >> http://hackage.haskell.org/cgi-bin/hackage-scripts/package/MonadPrompt >> >> There is a "sample" file with lots of other monads implemented in >> terms of Prompt included, along with some links to other samples; I >> seem to recall there being a "guess a number" game on paste.lisp.org >> that used Prompt to switch between user control and AI control. >> >> Let me know if you have any problems building it and I'll patch it up. >> >> -- ryan >> >> On Tue, Aug 12, 2008 at 5:50 AM, Martin Hofmann >> <[EMAIL PROTECTED]> wrote: >> > I just came across last year's thread about Ryan Ingram's "Prompt" monad >> > ( http://www.mail-archive.com/haskell-cafe@haskell.org/msg33040.html ) >> > and wondered if it might be useful for debugging and program analysis >> > purposes. In particular, I thought about enforcing program decisions >> > interactively. Consider for example modifying the heuristic function of >> > a search algorithm at specific breakpoints. >> > >> > Is this possible with the "Prompt" monad? Furthermore, could somebody >> > post the full code of it (and maybe a short example how to use it if at >> > hand)? I was not able to run the code from the previous posts and the >> > referring links are dead. >> > >> > Thanks a lot, >> > >> > Martin >> > >> > >> > >> > >> > >> > ___ >> > Haskell-Cafe mailing list >> > Haskell-Cafe@haskell.org >> > http://www.haskell.org/mailman/listinfo/haskell-cafe >> > > -- > --- > Dipl.-Wirtsch.Inf. (E.M.B.Sc.) Martin Hofmann > Cognitive Systems Group > Faculty Information Systems and Applied Computer Science > University of Bamberg > http://www.cogsys.wiai.uni-bamberg.de/members/hofmann > http://www.inductive-programming.org > > > ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] What's in a name?
The naming of cats is a difficult matter... Ahem. So as you may have noticed, we seem to have a profusion of packages all called "binary" or something dangeriously similar. There's also several "MD5" packages. I could point out a few others. So what I'm wondering is... Do we have a formal convention for the naming of packages and/or the naming of the modules they contain? How are name collisions supposed to be avoided? (E.g., Java uses domain names for this. If I write a package named Foo, I put all the classes in orphi.me.uk.Foo.*) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Phantoms
Bulat Ziganshin wrote: Hello Andrew, Wednesday, August 6, 2008, 10:09:43 PM, you wrote: Here's the thing though... How do I get it so that "Foo Int" and "Foo Double" produce slightly different strings when printed? instnace Show (Foo Int) ... instnace Show (Foo Double) ... ...WHY did I not think of this myself? o_O ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] help
- 雅虎邮箱,您的终生邮箱!___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] two problems with Data.Binary and Data.ByteString
Ah, that would be a bug in older ByteString implementations, that were a bit incautious about closing handles. This example works for me with bytestring-0.9.1.0 Yup, thank you Don and Duncan for pointing this out. I updated my bytestring library and the test case no longer fails. However, I'm still having problems and not sure why. I was able to distill the problem down to this: $ od -x 1word32.bin 000 05002ca4 $ runhaskell test6.hs loading... saving... test6.hs: 1word32.bin: openFile: resource busy (file is locked) $ cat test6.hs module Main where import Control.Applicative import Control.Parallel.Strategies (rnf, NFData, using) import Data.Binary import qualified Data.ByteString.Lazy.Char8 as B import Data.Word stateFile = "1word32.bin" loadState :: IO Word32 loadState = decode <$> B.readFile stateFile saveState :: Word32 -> IO () saveState db = B.writeFile stateFile $ encode db {- -- Works! loadState = B.readFile stateFile saveState = B.writeFile stateFile -} -- force x = print x >> return x force = return . (`using` rnf) main = do putStrLn "loading..." d <- force =<< loadState putStrLn "saving..." saveState d I tried this both with "print" and "rnf" to the same effect. It looks like there still might be some situations where the file isn't being closed? Should the file be closed when the last byte is read (in this case its definitely reading all four bytes) or when the first byte after that is read (in this case it probably doesn't attempt to read more than 4 bytes)? Tim Newsham http://www.thenewsh.com/~newsham/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] whatever happened to sendFile?
Brandon S. Allbery KF8NH <[EMAIL PROTECTED]> wrote: > I should clarify: what sendfile() is supposed to optimize > isn't writing large strings, or even the user<->kernel > roundtrips; it's an optimization to the kernel network stack > (network buffer management, to be specific). Web servers use > it to serve static content (e.g. icons, images, stylesheets) > because it significantly reduces system load. Indeed, and it my intention to use it for just this purpose -- serving numerous large images from a Haskell network server. However -- and here is the weird part -- it needs to work on Windows as well, because the server must be able to run locally for clients. -- _jsn ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] whatever happened to sendFile?
On 2008 Aug 13, at 15:26, Chaddaï Fouché wrote: 2008/8/13 Brandon S. Allbery KF8NH <[EMAIL PROTECTED]>: I should clarify: what sendfile() is supposed to optimize isn't writing large strings, or even the user<->kernel roundtrips; it's an optimization to the kernel network stack (network buffer management, to be specific). Web servers use it to serve static content (e.g. icons, images, stylesheets) because it significantly reduces system load. Ok, so it could still be useful in a restricted area (but then it should be easy to write a FFI wrapper for it anyway). Right. I intended that to be a heads-up in both directions: it is not simply a library convenience function, so one needs to think about when to use it. In particular, it's possible that overuse of sendfile() in the wrong circumstances will create additional system load instead of reducing it. -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] [EMAIL PROTECTED] system administrator [openafs,heimdal,too many hats] [EMAIL PROTECTED] electrical and computer engineering, carnegie mellon universityKF8NH ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] whatever happened to sendFile?
2008/8/13 Brandon S. Allbery KF8NH <[EMAIL PROTECTED]>: > > I should clarify: what sendfile() is supposed to optimize isn't writing > large strings, or even the user<->kernel roundtrips; it's an optimization to > the kernel network stack (network buffer management, to be specific). Web > servers use it to serve static content (e.g. icons, images, stylesheets) > because it significantly reduces system load. > Ok, so it could still be useful in a restricted area (but then it should be easy to write a FFI wrapper for it anyway). -- Jedaï ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] whatever happened to sendFile?
On 2008 Aug 13, at 15:04, Brandon S. Allbery KF8NH wrote: On 2008 Aug 13, at 15:01, Chaddaï Fouché wrote: 2008/8/13 Jason Dusek <[EMAIL PROTECTED]>: I found an old lib for it: http://www.haskell.org/ghc/docs/6.0/html/unix/System.Sendfile.html Hoogle turns up nothing, though. That don't sound very useful... Maybe when we only had String it was much more performant for big transfert, but now we can recode this in one short line of ByteString code and get the same performance as C. sendfile() is actually a system call, not a library function. I should clarify: what sendfile() is supposed to optimize isn't writing large strings, or even the user<->kernel roundtrips; it's an optimization to the kernel network stack (network buffer management, to be specific). Web servers use it to serve static content (e.g. icons, images, stylesheets) because it significantly reduces system load. -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] [EMAIL PROTECTED] system administrator [openafs,heimdal,too many hats] [EMAIL PROTECTED] electrical and computer engineering, carnegie mellon universityKF8NH ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] whatever happened to sendFile?
Chaddaï Fouché <[EMAIL PROTECTED]> wrote: > Maybe when we only had String it was much more performant for > big transfert, but now we can recode this in one short line of > ByteString code and get the same performance as C. Oh? Using lazy ByteString? -- _jsn ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] whatever happened to sendFile?
On 2008 Aug 13, at 15:01, Chaddaï Fouché wrote: 2008/8/13 Jason Dusek <[EMAIL PROTECTED]>: I found an old lib for it: http://www.haskell.org/ghc/docs/6.0/html/unix/System.Sendfile.html Hoogle turns up nothing, though. That don't sound very useful... Maybe when we only had String it was much more performant for big transfert, but now we can recode this in one short line of ByteString code and get the same performance as C. sendfile() is actually a system call, not a library function. -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] [EMAIL PROTECTED] system administrator [openafs,heimdal,too many hats] [EMAIL PROTECTED] electrical and computer engineering, carnegie mellon universityKF8NH ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] whatever happened to sendFile?
2008/8/13 Jason Dusek <[EMAIL PROTECTED]>: > I found an old lib for it: > >http://www.haskell.org/ghc/docs/6.0/html/unix/System.Sendfile.html > > Hoogle turns up nothing, though. > That don't sound very useful... Maybe when we only had String it was much more performant for big transfert, but now we can recode this in one short line of ByteString code and get the same performance as C. -- Jedaï ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Cyclic Inclusions
Hello, The Haskell'98 report does not specify if/how recursive modules should work. I wrote a paper a long time ago that formalizes and implements this feature (http://www.purely-functional.net/yav/publications/modules98.pdf). I very much doubt that separate compilation is much of a problem in practise because you only need to compile modules that are _recursive_ at the same time, and usually these tend to be fairly small. Figuring out the interface of the modules is a bit trickier in some pathological cases involving module re-exports, but this is already the case with non-recursive modules. One real technical problem that I remember was implementing "defaulting", which is specified in terms of a single module. With recursive modules, one could get mutually recursive functions from different modules, in which case it is not clear which set of defaulting rules to apply or how to combine them. Hope that this helps, -Iavor On Wed, Aug 13, 2008 at 4:30 AM, <[EMAIL PROTECTED]> wrote: > G'day. > > Quoting "C.M.Brown" <[EMAIL PROTECTED]>: > >> However I saw no real argument for not having cyclic inclusions. You >> say we shouldn't have to spend time writing hi-boot files, and yet you >> also think >> that GHC should not do it automatically. So we have to restrict all >> programmers to never writing cyclic inclusions? :) > > GHC generates .hi files for most modules automatically. The only reason > why hi-boot files are needed for cyclic imports is because of the > possibility that you can't generate a .hi file from the module alone. If > you could do that, then you could support cyclic imports without needing > hi-boot files. > > Cheers, > Andrew Bromage > ___ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] whatever happened to sendFile?
I found an old lib for it: http://www.haskell.org/ghc/docs/6.0/html/unix/System.Sendfile.html Hoogle turns up nothing, though. -- _jsn ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Haskell Weekly News: Issue 81 - August 13, 2008
--- Haskell Weekly News http://sequence.complete.org/hwn/20080813 Issue 81 - August 13, 2008 --- Welcome to issue 81 of HWN, a newsletter covering developments in the [1]Haskell community. This week saw some interesting talks at [2]AngloHaskell, and some cool new packages to hit Hackage, like [3]Language.C, [4]AERN-Real, [5]FTGL, and [6]Hoogle. What are you waiting for? Get out there and build something! Announcements Initial release of Language.C (language-c-0.3). Benedikt Huber [7]announced the [8]first release of [9]Language.C, a library for analysing and generating C code. This release features a reasonably well tested parser, a pretty printer, and a preview of the analysis framework. darcs roadmap. Jason Dagit [10]wrote to the list to thank everyone for their support for darcs, and to announce a webpage with a [11]roadmap for future darcs features. Darcs is alive and well! Anglo Haskell 2008 -- slides and audio. Matthew Sackman [12]announced that [13]slides and audio from Anglo Haskell 2008 are now available. BLAS bindings for haskell, version 0.5. Patrick Perry [14]announced a new release of the Haskell BLAS bindings, including a number of new features and improvements. Tutorial on information visualization and visual analytics in Haskell. Jefferson Heard [15]announced the [16]tutorial he will be presenting at DEFUN 2008, to give everyone a sneak peek at the long version of the tutorial before he's done with it. Comments and questions are welcome and encouraged. interval and polynomial enclosure arithmetics. Michal Konecny [17]announced the release of the [18]AERN-Real and [19]AERN-RnToRm packages, which model and reasonably efficiently implement exact real arithmetic. FTGL 1.0. Portable truetype font rendering in OpenGL. Jefferson Heard [20]announced the release of [21]Haskell bindings to FTGL, an easy to use library for portable rendering of TrueType fonts in OpenGL. Google Summer of Code Progress updates from participants in the 2008 [22]Google Summer of Code. GHC plugins. Max Bolingbroke is working on dynamically loaded plugins for GHC. [23]This week, he gave [24]a talk at AngloHaskell. Language.C. Benedikt Huber (visq) is [25]working on Language.C, a standalone parser/pretty printer library for C99. This week, he [26]announced the [27]first release of the [28]Language.C package. Hoogle 4. Neil Mitchell (ndm) is working on [29]Hoogle 4. [30]This week, he released several [31]command-line versions and a [32]web version of Hoogle 4, updated the manual, and gave [33]a talk at AngloHaskell. Next week, he plans to work on generating better Hoogle databases, and some bug fixes. DPH physics engine. Roman Cheplyaka (Feuerbach) is working on a [34]physics engine using [35]Data Parallel Haskell. [36]This week, he added complete support for general polyhedra, and fixed some bugs in the collision handler. He also added support for bounding spheres, although the results so far are disappointing, due to delays in the GHC implementation of parallel arrays. Next week, he plans to implement static bodies and BSP trees. Generic tries. Jamie Brandon is working on a library for efficient maps using generalized tries. GHC API. Thomas Schilling (nominolo) is working on [37]improvements to the GHC API. Cabal dependency framework. Andrea Vezzosi (Saizan) is working on a [38]make-like dependency analysis framework for Cabal. Blog noise [39]Haskell news from the [40]blogosphere. * >>> Nicholas Lativy: [41]Haskell in less than five minutes. Nicholas refreshes his memory of Haskell. * Douglas M. Auclair (geophf): [42]Monoid use. * Roman Cheplyaka: [43]Status report: week 11-12. * Douglas M. Auclair (geophf): [44]Combinatory Birds as Types. * Douglas M. Auclair (geophf): [45]Getting Better, part ][. * Neil Mitchell: [46]GSoC Hoogle: Week 11. * Max Bolingbroke: [47]Compiler Plugins AngloHaskell Talk. * London Haskell Users Group: [48]Video: Paradise, a DSEL for Derivatives Pricing. * Roman Cheplyaka (Feuerbach): [49]Compiling GHC. Roman records his experiences building the latest development version of GHC. * Luke Palmer: [50]Mindfuck: The Reverse State Monad. * Dan Piponi (sigfpe): [51]Untangling with Continued Fractions: Part 0. * Joachim Breitner: [52]Xmonad on my mobile phone. * Luke Palmer: [53]Composable Input for Fruit. * >>> Louis: [54]A Gentle Introduction to Haskell. Louis is learning Haskell by working through the Gentle Introduction. * >>> Bryan St. Amour: [55]Some Project Euler. Bryan learns some Haskell the good old-fashione
[Haskell-cafe] Re: ``Orphan instances'' should be avoided anyway.
On Wed, 13 Aug 2008, Yitzchak Gale wrote: Why is it that when I say import Control.Monad.Error (throwError, runErrorT) there is no way to prevent also getting a surprising Monad Either instance? Never mind how things should have been named in Control.Monad.Error - that's the way it is right now. I need to be able to import the module without getting the instance. Indeed, the instances that are imported without request contradict to the module concept. In case of Control.Monad.Error I suggest to give http://darcs.haskell.org/explicit-exception/src/Control/Monad/Exception/Synchronous.hs a try. I'm working on it as counter-proposal to the extensible extension proposal. This module defines exceptions without abusing the Either type. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] The Italian Haskellers Summer Meeting is Over: What Next?
E cosi' il primo incontro balnear/ricreativo degli Haskeller Italiani si e' felicemente concluso. Come da programma, rigidamente rispettato, abbiamo fatto il bagno e mangiato pizza e gelato ma soprattutto ci siamo conosciuti ed abbiamo discusso di tutto e di piu', prevalentemente Haskell (folds, arrows, happs, sviluppo web) ma non solo (democrazia elettronica, la crisi economica, mercato ed autosufficienza). Non si puo' dire che l'affluenza sia stata oceanica ma non dimentichiamo che con 3 persone si puo' fare una cellula rivoluzionaria e con una cellula rivoluzionaria si puo' cominciare a pensare a fare la rivoluzione :-) Insomma e' stato piacevole ed utile e lo riorganizzeremo certamente il prossimo anno. Ed adesso? E' evidente, dobbiamo organizzare un incontro invernale, sullo stile di AngloHaskell, per presentare e discutere progetti di sviluppo, idee per futuri progetti ed iniziative che possano servire a rafforzare ed estendere la comunita' Haskell Italiana. Interessati? Date uno sguardo a http://www.haskell.org/haskellwiki/ItaloHaskell Saluti, titto -- Pasqualino "Titto" Assini, Ph.D. 25 Heath Road - CO79PT Wivenhoe - Colchester - U.K. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] two problems with Data.Binary and Data.ByteString
On Tue, 2008-08-12 at 14:13 -1000, Tim Newsham wrote: > I also noticed another issue while testing. If my program loads > the data at startup by calling loadState then all later calls to > saveState give an error: > >Log: savedState.bin: openFile: resource busy (file is locked) You're not using an old version of bytestring are you, anything older than 0.9.0.4? We had a bug where the handle was not closed as soon as we got to the end of the stream, so even forcing the whole input didn't help. Duncan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Cyclic Inclusions
G'day. Quoting "C.M.Brown" <[EMAIL PROTECTED]>: However I saw no real argument for not having cyclic inclusions. You say we shouldn't have to spend time writing hi-boot files, and yet you also think that GHC should not do it automatically. So we have to restrict all programmers to never writing cyclic inclusions? :) GHC generates .hi files for most modules automatically. The only reason why hi-boot files are needed for cyclic imports is because of the possibility that you can't generate a .hi file from the module alone. If you could do that, then you could support cyclic imports without needing hi-boot files. Cheers, Andrew Bromage ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Cyclic Inclusions
On 13 Aug 2008, at 13:18, [EMAIL PROTECTED] wrote: G'day all. Quoting Thomas Davie <[EMAIL PROTECTED]>: To be honest, ghc compiles things so fast (at least on any of my systems) that I couldn't care less if it took 10 times as long (I would however like some added convenience for that time spent) Have you ever compiled GHC itself? Just curious what you'd think about a 10x speed hit there. On the machine I'm sat at now, it takes 20 minutes. Secondly, you would *only* pay the speed penalty when you had cyclic includes, and you didn't use the flag to use an hi-boot file, so it would continue to take 20 minutes. If it helps, think about the lifetime of a program. If you assume that a program grows linearly over time, and that recompilations occur at a roughly constant rate, it follows that the time spent recompiling is O(n^2). Constant factors matter. But the penalty would be no where near that big -- unless you happened to have *all* your modules depend on *all* other modules. If I compile a module on which lots of other modules depend, I have to do lots of recompilation... If I compile a module which is in a cyclic dependancy group, I have to do lots of recompilation, I don't see that there's a difference here. If you only change the implementation of a module, not its interface, you don't need to recompile anything that imports it. (At least, this is true at -O0, which if you care about fast recompilation because you're deep in development, you're probably doing.) Well, if this turned out to take a long time, then I'd probably switch to writing an hi-boot file... Something that I wouldn't have to waste time doing at all if it happened that ghc was still "fast enough" without providing one. Bob ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Cyclic Inclusions
G'day all. Quoting Thomas Davie <[EMAIL PROTECTED]>: To be honest, ghc compiles things so fast (at least on any of my systems) that I couldn't care less if it took 10 times as long (I would however like some added convenience for that time spent) Have you ever compiled GHC itself? Just curious what you'd think about a 10x speed hit there. If it helps, think about the lifetime of a program. If you assume that a program grows linearly over time, and that recompilations occur at a roughly constant rate, it follows that the time spent recompiling is O(n^2). Constant factors matter. If I compile a module on which lots of other modules depend, I have to do lots of recompilation... If I compile a module which is in a cyclic dependancy group, I have to do lots of recompilation, I don't see that there's a difference here. If you only change the implementation of a module, not its interface, you don't need to recompile anything that imports it. (At least, this is true at -O0, which if you care about fast recompilation because you're deep in development, you're probably doing.) That's a fair point about programming style, otoh, I don't think it's a reason to restrict users to not using cyclic dependancies. As previously noted, cyclic dependencies alone aren't the problem. Cheers, Andrew Bromage ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Cyclic Inclusions
Andrew, > > But isn't this exactly the point I was trying to make!? The whole point, > > to me, in functional programming, is that we shouldn't have to worry about > > the underlying implementation. > > It is not exposing an underlying implementation detail to mandate that > modules should have well-defined interfaces. If anything, it's > enforcing good programming practice. I agree absolutely that having well-defined interfaces is a good thing. I wasn't actually referring to that, I apologise for not being clear. However I saw no real argument for not having cyclic inclusions. You say we shouldn't have to spend time writing hi-boot files, and yet you also think that GHC should not do it automatically. So we have to restrict all programmers to never writing cyclic inclusions? :) Kind Regards, Chris. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Cyclic Inclusions
G'day all. Quoting "C.M.Brown" <[EMAIL PROTECTED]>: But isn't this exactly the point I was trying to make!? The whole point, to me, in functional programming, is that we shouldn't have to worry about the underlying implementation. It is not exposing an underlying implementation detail to mandate that modules should have well-defined interfaces. If anything, it's enforcing good programming practice. Cheers, Andrew Bromage ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: ``Orphan instances'' should be avoided anyway.
I wrote: >> ...there must be some >> way to control the import and export of instances, just as we can >> now control the import and export of every other kind of symbol >> binding. Henning Thielemann wrote: > For me it's most often the case that an instance is missing. > If there is no way to change existing instance definitions, > then you must use 'newtype'. Yes, in that case newtype is a work-around, often messy. > Generalized newtype deriving simplifies to adapt the instances you want. That's only one part of it. Using a newtype can sometimes spew wreckage all over the place. But a more difficult case is when you need to use two libraries that already define conflicting instances. That requires a newtype plus however many adaptor functions you need, all inside a wrapper module. What a mess. These cases are likely to arise most often in large software projects. So there hasn't been a big enough demand yet for this feature to be implemented in any compiler, resulting in it being rejected from Haskell', unfortunately. But for large projects it has to work the other way around - the language features need to be there already for the language to be adopted for the project. Or to keep project managers from cursing themselves later on if they do choose Haskell. Anyway, I find the current behavior to be ugly and unintuitive. Why is it that when I say import Control.Monad.Error (throwError, runErrorT) there is no way to prevent also getting a surprising Monad Either instance? Never mind how things should have been named in Control.Monad.Error - that's the way it is right now. I need to be able to import the module without getting the instance. Regards, Yitz ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Cyclic Inclusions
Andrew, [...] > For the record, I have no problem with modules depending on each other, > so long as they only depend on their well-defined interfaces. > > > Finally, as chris suggests, if separate compilation is important to > > you, why not have a flag in ghc -frequire-hi-boot or something? > > Well, if I wanted separate header files, and the inevitable multiple- > maintenance headaches associated with them, I'd program in C. Except > for mutually recursive modules, GHC can and does generate header files > automatically, so I don't see why my time should be wasted doing the > job of a compiler. > > If something is preventing the compiler from doing that job, then that > something should be fixed. But isn't this exactly the point I was trying to make!? The whole point, to me, in functional programming, is that we shouldn't have to worry about the underlying implementation. What you've listed above are the restrictions of a particular compiler implementation. All of which, if needed, can be controlled by a flag if compilation performance is so important. Regards, Chris. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Cyclic Inclusions
On 13 Aug 2008, at 11:10, Henning Thielemann wrote: On Wed, 13 Aug 2008, Thomas Davie wrote: On 13 Aug 2008, at 05:06, [EMAIL PROTECTED] wrote: Quoting Thomas Davie <[EMAIL PROTECTED]>: Why is separate compilation important? I'm a little shocked that anyone on this list should have to ask this question. Two people have asked it now. Really? So you're using YHC then? It after all compiles *much* faster than GHC, but produces slower binaries. To be honest, ghc compiles things so fast (at least on any of my systems) that I couldn't care less if it took 10 times as long (I would however like some added convenience for that time spent) It's the ubiquitous "computers are fast enough today" argument. I don't buy it. We don't have compile time to waste. There will always be computers that are much slower and have less memory than the current customer desktop computers, there are always tasks that a computer can do instead of doing slowed down compilation. I'm glad that we have overcome C's way of concatening all header files together before starting compilation. If you don't want to be slowed down by the compiler, why aren't you writing machine code directly? The point is that time saved with convenience (often) comes at the cost of time spent while compiling. Adding an option to ghc to allow you to not waste time writing hi-boot files allows me to make an informed decision about whether it will take me longer to (a) figure out *how* to write an hi-boot file (b) actually do the writing, or if it'll take less time/effort to just let the compiler do it for me. Bob ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Cyclic Inclusions
On Wed, 13 Aug 2008, Thomas Davie wrote: On 13 Aug 2008, at 05:06, [EMAIL PROTECTED] wrote: Quoting Thomas Davie <[EMAIL PROTECTED]>: Why is separate compilation important? I'm a little shocked that anyone on this list should have to ask this question. Two people have asked it now. Really? So you're using YHC then? It after all compiles *much* faster than GHC, but produces slower binaries. To be honest, ghc compiles things so fast (at least on any of my systems) that I couldn't care less if it took 10 times as long (I would however like some added convenience for that time spent) It's the ubiquitous "computers are fast enough today" argument. I don't buy it. We don't have compile time to waste. There will always be computers that are much slower and have less memory than the current customer desktop computers, there are always tasks that a computer can do instead of doing slowed down compilation. I'm glad that we have overcome C's way of concatening all header files together before starting compilation. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Cyclic Inclusions
On 13 Aug 2008, at 05:06, [EMAIL PROTECTED] wrote: G'day all. Quoting Thomas Davie <[EMAIL PROTECTED]>: Why is separate compilation important? I'm a little shocked that anyone on this list should have to ask this question. Two people have asked it now. The simplest answer is that unless your program fits in cache, it takes longer to compile two modules concurrently than it takes to compile them separately. This is even more true if one of those modules does not actually need recompilation. The longer answer is that in the Real World, programmer time is far, far more precious than computer time. Every second that the programmer waits for the computer to finish some task, there is a priority inversion. Really? So you're using YHC then? It after all compiles *much* faster than GHC, but produces slower binaries. To be honest, ghc compiles things so fast (at least on any of my systems) that I couldn't care less if it took 10 times as long (I would however like some added convenience for that time spent) It's therefore highly desirable that jobs done by computer are as fast as possible or, failing that, as predictable as possible, so the programmer knows to do something else while waiting. Separate compilation puts a predictable upper bound on the amount of recompilation that has to be done given some set of changes. True, so does requiring recompilation of a package as a whole, but Haskell development would then be notorious for its sluggishness. It does? If I compile a module on which lots of other modules depend, I have to do lots of recompilation... If I compile a module which is in a cyclic dependancy group, I have to do lots of recompilation, I don't see that there's a difference here. I can understand your point about a module on it's own not being analyzable, and that that's an odd property -- on the other hand, the rapidly emerging "atomic" unit in Haskell is the package, so I see no reason why modules within one package shouldn't depend on each other. Implicit in my working definition of "module" is that a module has a well-defined interface. Am I the only one who has that understanding? (Well, me and David Parnas, at any rate.) For the record, I have no problem with modules depending on each other, so long as they only depend on their well-defined interfaces. That's a fair point about programming style, otoh, I don't think it's a reason to restrict users to not using cyclic dependancies. Finally, as chris suggests, if separate compilation is important to you, why not have a flag in ghc -frequire-hi-boot or something? Well, if I wanted separate header files, and the inevitable multiple- maintenance headaches associated with them, I'd program in C. Except for mutually recursive modules, GHC can and does generate header files automatically, so I don't see why my time should be wasted doing the job of a compiler. If something is preventing the compiler from doing that job, then that something should be fixed. Something *does* prevent the compiler doing that job -- the fact that ghc can't deal with cyclic module includes without an hi-boot file. This is *exactly* my point -- I don't see why my time should be wasted doing the job of the compiler just because I happen to have a cyclic dependancy, that the compiler could quite happily sort out, by making my compile time in this situation slightly longer. If I *really* think I'm going to save more time by writing a hi-boot file, then I would be able to turn on the option! Bob ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Dealing with heterogeneously-typed lists?
On 13 Aug 2008, at 00:44, Leif Warner wrote: Hi all, I'm dealing with some datatype, say: data Invoice = Invoice { invoiceNum:: String, dollarAmt :: Currency, printDate :: Date, dueDate :: Date, vendorNum :: Int, vendorName:: String, isStock :: Bool, } You probably don't want to put these things into a list at all. Instead, you want to define an Instance of the Show class for Invoice. Bob ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] two problems with Data.Binary and Data.ByteString
ketil: > Don Stewart <[EMAIL PROTECTED]> writes: > > >> You really, really want to be using rnf for this job, instead of > >> turning your brain into a pretzel shape. > > > The Pretzel being one of the lesser-known lazy, cyclic, functional data > > structures. > > So "pretzel-brain" is actually a honorific, rather than derogative term? > /me makes mental note. Yes, bestowed upon those who've read Okasaki, and can tie-the-knot. -- Don ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe