Re: [Haskell-cafe] I read somewhere that for 90% of a wide class of computing problems, you only need 10% of the source code in Haskell, that you would in an imperative language.
On Wed, Sep 30, 2009 at 9:32 AM, Andrew Coppin andrewcop...@btinternet.com wrote: I might also point out that 90% of all desktop computers run Windows, and yet every single C library binding on Hackage fails to compile on Windows. That really needs to be fixed. (Not to mention some of the standard I/O functions doing slightly strange things because GHC is calling POSIX compatibility functions rather than native I/O functions. For example, doesDirectoryExist C:\\ = False.) This is a problem of C / Posix, not a problem of Haskell. Haskell C bindings compile on Windows without issues IF the corrisponding library is available. It is compiling the (usually posix) C library in Windows the real issue. Anyway, on Windows Vista, cmd.exe: GHCi, version 6.10.4: http://www.haskell.org/ghc/ :? for help Prelude :m System.Directory Prelude System.Directory doesDirectoryExist C:\\ True Salvatore ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ANN: darcs 2.3.0
Great! Just a little note: MSYS isn't required to install Darcs with cabal on Windows, just to develop or run tests. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type Coercion
2008/5/28 PR Stanley [EMAIL PROTECTED]: Hi (16 :: Float) is a perfectly legitimate statement although I'm surprised that it's allowed in a type strong language such as Haskell. It's a bit like casting in good old C. What's going on here? Don't worry: it's not a cast. Numeric constants like 16 in Haskell have polymorphic types: Prelude :t 16 16 :: (Num t) = t Prelude :t 16.6 16.6 :: (Fractional t) = t Writing 16 :: Float you are simply making the type explicit, and you can do it only in the context of the typeclass. Prelude :t (16 :: Integer) (16 :: Integer) :: Integer This works because Integer is a type of the typeclass Num, but: Prelude :t (16.5 :: Integer) interactive:1:1: No instance for (Fractional Integer) arising from the literal `16.5' at interactive:1:1-4 Possible fix: add an instance declaration for (Fractional Integer) This doesn't work. So everything is done at compile time, no casting (i.e. believe me compiler, this it a Float) involved. Notice that during binding the numeric constants' type is always made explicit (if you want to know more, look for section 4.3.4 in the Haskell Report): Prelude let a = 3 Prelude :t a a :: Integer Prelude let b = 3.3 Prelude :t b b :: Double Prelude b :: Float interactive:1:0: Couldn't match expected type `Float' against inferred type `Double' In the expression: b :: Float In the definition of `it': it = b :: Float Salvatore ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] relational data representation in memory using haskell?
2008/5/22 Marc Weber [EMAIL PROTECTED]: I'd like to illustrate two different ideas using a small example: (A) data CD = CD { title :: String, tracks :: [ Track ] } data Track = Track { track :: String, cd :: CD } data PDB = PDB { cds :: Set CD, tracks :: Set Track } because it's not using foreign ids but kind of pointers I'll call this the pointer method This doesn't look like a relational structure at all in Haskell. Let's take the CD and Track relations. In a relational database you have something like: CD (1, 'Querying about you') Track (1, 'Inserting some love', 1) Track (2, 'Updating my feelings', 1) Track (3, 'Deleting my hopes', 1) In an imperative language you can do something similar in memory using objects (you can in haskell to with IORefs and so on, but let's stay on data). You get something like: 0x000 CD('Querying about you') 0x004 Track('Inserting some love, 0x004) ... In Haskell when you say: data Track = Track { track :: String, cd :: CD } You are not storing in Track a reference, a pointer or something similar to a CD, you are storing a *value* (low level you probably have a pointer, but you have not pointer semantics). As you noticed, you cannot update the CD title without changing each Track. That's a way to store information, and a good way too, but it's not a relational structure by any extent. If you want to use this structure for your relational data you need two things: 1) Something that will convert from a value-based representation of data to something relational (aka ORM in the OO world... a FRM? VRM?). 2) A relational storage (internal or external). If you want to use normal Haskell ADT, are you sure that a relational storage is what you want? Keeping that in memory doesn't give you some advantages of relational databases (e.g. uniform representation), and the impedance between the functional and the relational world is not easy to manage. Maybe I misunderstood what you are trying to accomplish, and you only want to do a generic data structure with fast lookups on the content of the items? Or do you really need relational semantics? Salvatore ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] relational data representation in memory using haskell?
Consider let x = Cd ... forkIO $ ( do something with x } -- (1) print x -- (2) How can ghc know when running line (2) that (1) hasen't changed the record? I see two solutions: a) give the forked process a copy (Then my design will collapse) but this is expensive to copy data without knowing you ned to b) use pointers and replace x ony on updating. Thus if (1) changes the title a new struct wil be created poiting to the old list but a new title String. line (2) doesn't have to care at all. GHC knows that because in Haskell isn't possible to update x. x is not a variable, it's a binding. To put it simply: with IORefs (and STRefs, MVars, ...) you have references to values that you can change (inside their respective monads), much like variables, but data declarations are values, not references to values (even if GHC stores them as pointers you cannot treat them as such), so you cannot update it. So, in your example, you have more or less a relation (CD) where all the columns are part of primary key (and so they are not mutable). Salvatore ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] relational data representation in memory using haskell?
2008/5/22 Marc Weber [EMAIL PROTECTED]: So in haskell it would look like this: let updatedCd = 0x22 CD (0x6 My song) (0x20 ( 0x23 : ...) updatedTrack = 0x23 Track ( 0x21 updated track title ) 0x22 in (0x27) DB (0x24 (updatedCd:otherCds)) (0x25 (updatedTrack:otherTracks)) Mmmm I don't think that this is a good way to go. Let me do a counter-example: data A = A String data B = B String [A] data C = C String [B] data D = D String [C] Suppose to have some As, Bs, Cs, Ds in your database. Now you want to update the String of A. As you cannot update stuff in Haskell mantaining the same pointer, you've got a new A. So you must find all Bs that had this A in their list, and update that. Unfortunately lists are not mutable too, so you are creating a new list; so you need to create new containing Bs too. But then you must change Cs... and so on. A little change like changing the String in A requires updating the whole DB. Salvatore ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] MD5 performance optimizations
2008/5/21 Andrew Coppin [EMAIL PROTECTED]: Woo! Salvatore kindly sent me a Darcs patch, and applying it does indeed make it run faster. Yay! Hi Andrew, I'm glad that -fvia-c works for you: maybe it's a Mac OS X specific bug? Anyway, did you compile with -fvia-c -optc-O3? I expect register-intensive code like this to be at least 20% faster with gcc. Salvatore ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] MD5 performance optimizations, and GHC -via-C producing segfaulting binary
2008/5/17 Andrew Coppin [EMAIL PROTECTED]: Hi folks. OK, try this: darcs get http://darcs.orphi.me.uk/MyMD5 cd MyMD5 ghc -O2 --make md5sum md5sum some large filename I've got some time to take a look at the code. It's very nice, readable and declarative, but obviously not optimized for raw speed. There're a few things to do to have a speed-up of 2x, without going low-level. 1) There's a lazyness leak in Pad.hs. The sum in: else make_block_bs bs0 : work (n + block_size_bytes) bs1 is not strict. With a very large file (e.g. 100 mb) it means stack overflow. [roxas:~/Desktop/test2/MyMD5] kirby% ghc -O2 --make md5sum.hs [roxas:~/Desktop/test2/MyMD5] kirby% time ./md5sum ../../jboss-4.2.2.GA.zip Stack space overflow: current size 8388608 bytes. Use `+RTS -Ksize' to increase it. To solve it just add a bang (!) before the n parameter: work !n bs = You've got to add {-# LANGUAGE BangPatterns #-} at the top of the file too. There're solutions that don't imply BangPatterns, and use only seq, but I like bang patterns! Now it works: [roxas:~/Desktop/test2/MyMD5] kirby% time ./md5sum ../../jboss-4.2.2.GA.zip E6542028D538BAEC180A96A5D1E6EC3A 11.958u 0.210s 0:12.19 99.7%0+0k 0+2io 0pf+0w 2) make_block_bs is sub-optimal, and very critical to performance. I decided to use Data.Binary for it (it's also more readable, and you get rid of the unsafeWrite): import Data.Binary import Data.Binary.Get import Control.Monad // ... instance Binary Block where put _ = undefined get = do xs - replicateM 16 getWord32le return $ Block $ listArray (0, 15) xs make_block_bs :: B.ByteString - Block make_block_bs = decode Now we are getting faster: [roxas:~/Desktop/test2/MyMD5] kirby% time ./md5sum ../../jboss-4.2.2.GA.zip E6542028D538BAEC180A96A5D1E6EC3A 8.063u 0.174s 0:08.23 100.0%0+0k 0+0io 0pf+0w 3) You are doing a lot of access to fields of a strict data type (State). You can at least ask the compiler to help you a bit with -funbox-strict-fields. Now we have: [roxas:~/Desktop/test2/MyMD5] kirby% time ./md5sum ../../jboss-4.2.2.GA.zip E6542028D538BAEC180A96A5D1E6EC3A 6.780u 0.133s 0:06.91 100.0%0+0k 0+1io 0pf+0w We have got a good, nearly 2x, speed-up with very few optimizations, and we run in a very small constant amount of memory. Probably compiling with -fvia-C could help even more, but strangely: [roxas:~/Desktop/test2/MyMD5] kirby% ghc -fvia-C -funbox-strict-fields -O2 --make md5sum.hs [roxas:~/Desktop/test2/MyMD5] kirby% time ./md5sum ../../jboss-4.2.2.GA.zip Segmentation fault Is this supposed to happen? There're no unsafe functions or imports used in the program. Maybe a bug in GHC? Salvatore ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] MD5 performance optimizations, and GHC -via-C producing segfaulting binary
2008/5/20 Don Stewart [EMAIL PROTECTED]: Probably compiling with -fvia-C could help even more, but strangely: [roxas:~/Desktop/test2/MyMD5] kirby% ghc -fvia-C -funbox-strict-fields -O2 --make md5sum.hs [roxas:~/Desktop/test2/MyMD5] kirby% time ./md5sum ../../jboss-4.2.2.GA.zip Segmentation fault Is this supposed to happen? There're no unsafe functions or imports used in the program. Maybe a bug in GHC? That could be a gcc bug, in fact. Can you provide the final source? Does changing the gcc optimisation level help? (i.e. -fvia-C -optc-O2 ) I tried with and without gcc optimizations, but it always segfaults. It happened to me even before my optimizations. I've got GHC 6.8.2 on Mac OS X 10.5.2, GCC 4.0.1. -fvia-C works well for other libraries and applications, so I don't think it's a problem of my specific setting. Salvatore MyMD5.tar.gz Description: GNU Zip compressed data ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Performance: MD5
2008/5/18 Andrew Coppin [EMAIL PROTECTED]: unsafeRead/Write Found in Data.Array.Base, apparently. (I managed to find an example in the Gtk2hs fastdraw demo.) Oddly, this seems to make virtually no performance difference. I find this highly surprising. But then, I perform 16 write to the array, and 64 reads from the ByteString, so maybe that's where I should be worrying about bounds checks... Hi Andrew, just a profiling suggestion: did you try to use the SCC cost-centre annotations for profiling? If you want to know precisely what takes 60% of time, you can try: bn = {-# SCC IntegerConversion #-} 4 * fromIntegral wn b0 = {-# SCC ByteStringIndexing #-} B.index bi (bn+0) b1 = {-# SCC ByteStringIndexing #-} B.index bi (bn+1) b2 = {-# SCC ByteStringIndexing #-} B.index bi (bn+2) b3 = {-# SCC ByteStringIndexing #-} B.index bi (bn+3) w = foldl' (\w b - shiftL w 8 .|. fromIntegral b) 0 [b3,b2,b1,b0] in {-# SCC ArrayWriting #-} unsafeWrite temp wn w In profiling the time of all expressions with the same SCC name will be summed. You can get more information about SCC here: http://www.haskell.org/ghc/docs/latest/html/users_guide/profiling.html#cost-centres Obviously, even ultra-optimizing this function to be 60 times faster (assuming that this is possible) will only make your program go about 2 time faster. One advice: I've seen various md5sum implementations in C, all using about the same algorithms and data structures, and they performed even with 10x time differences between them; md5summing fast is not a really simple problem. If I were you I would drop the comparison with ultra-optimized C and concentrate on does my high-level-good-looking-super-readable implementation perform acceptably?. What acceptably means is left as an exercise to the reader. Salvatore ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Consensus about databases / serialization
·regarding Haskell and databases, the page http://haskell.org/haskellwiki/Libraries_and_tools/Database_interfaces describes a few, but which are the ones that are stable and practical? Any user experiences? During my experiments I found Takusen (http://darcs.haskell.org/takusen/) and HDBC (http://software.complete.org/hdbc) very useful, even if I liked Takusen interface more. ·regarding Haskell and serialization, I don't think that implementing Read/Show is a good way for real serialization, so what other options exist? I could suggest Data.Binary (http://code.haskell.org/binary/), that is very well performing and supported. There are ways to generate instances of Binary automatically. I like the Derive approach most (http://www.cs.york.ac.uk/fp/darcs/derive/derive.htm), as it uses Template Haskell and does not require separate pre-processing. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] GHC doesn't work
2007/10/3, Andrew Coppin [EMAIL PROTECTED]: The entry point OpenThread could not be found in KERNEL32.dll. Are you using NT 4? Probably GHC 6.6.1 dropped support for it (or maybe the binary you downloaded was compiled without the support for it), as this error message means more or less your OS is too old to run this. Salvatore ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] problems installing Takusen-0.6
2007/7/29, Rahul Kapoor [EMAIL PROTECTED]: I am having problems installing Takusen-0.6 (ghc 6.6.1 on FreeBSD) The configure and build works fine. running ./setup install fails with: Installing: /usr/local/lib/Takusen-0.6/ghc-6.6.1 /usr/local/bin Takusen-0.6... setup: Error: Could not find module: Database.Oracle.Enumerator with any suffix: [hi] Hi Rahul, just edit the file takusen.cabal and comment (with --) all the lines that begin with Database.Oracle or Database.PostgreSQL. Salvatore ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Handling custom types in Takusen
2007/7/27, Bayley, Alistair [EMAIL PROTECTED]: Also, in Sqlite 3.4, they introduced new functions for incremental reading / writing of Blobs. I could use them in the future. Seems reasonable. I recall Oleg saying something privately a while ago about an API for large objects. He may have some ideas for this. A good idea could be to do the marshalling / unmarshalling of Blob as CStringLen. It can then be used to construct PackedStrings and ByteStrings in O(1), or doing some custom computations with it. A CStringLen, even if contains Ptr CChar, can easily be converted to any pointer type. Another idea could be using custom bind function for blobs, but the first solution is surely easier. Salvatore ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Handling custom types in Takusen
2007/7/27, Bayley, Alistair [EMAIL PROTECTED]: It was my intention to do it the other way around: marshall blob to Ptr (), and then you can cast this to a Ptr CChar. Obviously you'd need to retain the size information, so a blob basically becomes a (Ptr (), Int) pair, just like a CStringLen... At least this way you've got a type which says explicitly this thing is a blob, and then if you know better, i.e. it's really a CString, you can cast it. You're right, I'll work in this direction. Eventually I will add also the CStringLen marshalling, as it is a pretty common case (BS, FPS, PS) and it could be handy. Salvatore ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Handling custom types in Takusen
2007/7/27, Bayley, Alistair [EMAIL PROTECTED]: BTW, do you really need to marshall PackedStrings to blobs? The Sqlite library uses CStrings, and I assume that CString to PackedString marshaling is fairly efficient, so that would seem to be a better choice. (I have no experience of PackedStrings, so there might be good reasons to prefer blobs, and I'd like to know what they are.) The main reason is that I'm working on a Sqlite back-end for Darcs, that will be used to store file contents. I think to choose Takusen as back-end library mainly because it has the blob functions of Sqlite already mapped. In Darcs PackedStrings are used to store file contents in memory. I don't think that it would be very efficient to store files of megabytes in a text column (there could be encoding problems too). Also, in Sqlite 3.4, they introduced new functions for incremental reading / writing of Blobs. I could use them in the future. Thank you a lot for helping! I'll surely send you the patches, even if the PackedString support will be a little Darcs-specific (I don't think that requiring it for compiling Takusen is a good idea). Salvatore Insalaco ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Speedy parsing
2007/7/20, Tillmann Rendel [EMAIL PROTECTED]: Re, Joseph (IT) wrote: At this point I'm out of ideas, so I was hoping someone could identify something stupid I've done (I'm still novice of FP in general, let alone for high performance) or direct me to a guide,website,paper,library, or some other form of help. I think that your problem is simply an excess of lazyness :). foldr is too lazy: you pass huge structures to fold, that you evaluate anyway. Try to import Data.List and use foldl' (not foldl), that is strict. Being left fold, you probably need to rework a bit your functions (I tried to simply flip them, but the result of the program wereflipped too), but the time (and memory) difference is unbelievabl (foldl' is constant in memory allocation). Salvatore ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] GHC 6.6.1: Where is Graphics.SOE ?
I think that it's simply a buildfile error, that requires X11 even if you are on windows. The problem is that the building process requires running a configure script, so it requires a cygwin environment under windows. If you need HGL only for educational purposes, I strongly suggest you to download and use Hugs (it has HGL precompiled). If you need HGL for more advanced purposes, the first step is installing a cygwin environment and remove X11-any and all the lines containing X11 from the HGL.cabal file. Salvatore ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] can't build hIDE
src/Hide/Plugin/LoaderMidLevel.hs:126:26: Not in scope: `moduleFS' hIDE uses low-level GHC APIs to do some of its tricks. Unfortunately, GHC APIs change faster than hIDE, so the last version of hIDE is not compatible with GHC 6.6. As far as I know, in GHC 6.6 moduleFS has been renamed moduleNameFS. You can try to replace moduleFS with moduleNameFS on line 126 in src/Hide/Plugin/LoaderMidLevel.hs, and try to recompile. Tell me if you manage to compile it with this fix, hIDE authors could be interested. Salvatore ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe