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.

2009-09-30 Thread Salvatore Insalaco
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

2009-07-24 Thread Salvatore Insalaco
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-05-28 Thread Salvatore Insalaco
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-05-22 Thread Salvatore Insalaco
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?

2008-05-22 Thread Salvatore Insalaco
 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-05-22 Thread Salvatore Insalaco
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-05-21 Thread Salvatore Insalaco
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-05-20 Thread Salvatore Insalaco
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-05-20 Thread Salvatore Insalaco
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-05-19 Thread Salvatore Insalaco
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

2008-01-02 Thread Salvatore Insalaco
 ·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-04 Thread Salvatore Insalaco
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-07-29 Thread Salvatore Insalaco
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-07-27 Thread Salvatore Insalaco
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-07-27 Thread Salvatore Insalaco
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-07-27 Thread Salvatore Insalaco
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-07-20 Thread Salvatore Insalaco

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 ?

2007-07-18 Thread Salvatore Insalaco

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

2007-07-16 Thread Salvatore Insalaco


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