Send Beginners mailing list submissions to
        [email protected]

To subscribe or unsubscribe via the World Wide Web, visit
        http://www.haskell.org/mailman/listinfo/beginners
or, via email, send a message with subject or body 'help' to
        [email protected]

You can reach the person managing the list at
        [email protected]

When replying, please edit your Subject line so it is more specific
than "Re: Contents of Beginners digest..."


Today's Topics:

   1.  how to read file with locking (Joey Hess)
   2. Re:  how to read file with locking (Jimmy Wylie)
   3. Re:  how to read file with locking (Isaac Dupree)
   4.  Re: how to read file with locking (Ertugrul Soeylemez)
   5.  reproducing HashTable benchmark (Tom Doris)
   6. Re:  reproducing HashTable benchmark (Daniel Fischer)


----------------------------------------------------------------------

Message: 1
Date: Sat, 9 Oct 2010 18:49:12 -0400
From: Joey Hess <[email protected]>
Subject: [Haskell-beginners] how to read file with locking
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset="us-ascii"

The function below always returns "", rather than the file's contents.
_Real World Haskell_ touches on how laziness can make this problimatic,
without really giving a solution, other than throwing in a putStr to
force evaluation, which can't be done here. How can I make  hGetContents
strict, to ensure the file contents are really read before it gets closed?

readFile' file = do
        f <- openFile file ReadMode
        -- locking will go here
        s <- hGetContents f
        hClose f
        return s

Also, I noticed that opening a file and locking it involves a
very verbose seeming dance. (It's 2 lines of code in most other languages.)
Does this indicate that few people bother with file locking in Haskell
and so it still has these rough edges, or that there's a better way to do
it that I have not found yet?

openLocked file = do
        handle <- openFile file ReadMode
        lockfd <- handleToFd handle -- closes handle
        waitToSetLock lockfd (ReadLock, AbsoluteSeek, 0, 0)
        handle' <- fdToHandle lockfd
        return handle'

-- 
see shy jo
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 828 bytes
Desc: Digital signature
Url : 
http://www.haskell.org/pipermail/beginners/attachments/20101009/5eebe19e/attachment-0001.bin

------------------------------

Message: 2
Date: Sat, 9 Oct 2010 20:40:11 -0500
From: Jimmy Wylie <[email protected]>
Subject: Re: [Haskell-beginners] how to read file with locking
To: <[email protected]>
Message-ID: <[email protected]>
Content-Type: text/plain; charset="iso-8859-1"

  On 10/9/10 5:49 PM, Joey Hess wrote:
> The function below always returns "", rather than the file's contents.
> _Real World Haskell_ touches on how laziness can make this problimatic,
> without really giving a solution, other than throwing in a putStr to
> force evaluation, which can't be done here. How can I make  hGetContents
> strict, to ensure the file contents are really read before it gets closed?
>
> readFile' file = do
>          f<- openFile file ReadMode
>       -- locking will go here
>          s<- hGetContents f
>          hClose f
>          return s
>
Haskell won't actually read the file unless you need the contents of the 
file.  In order to ensure that the file contents are read before it gets 
close, you need to actually perform an operation that will force 
evaluation of the file. Haskell will read the file then to perform 
whatever operation you specify.
     for example
          sendFile file = do
               f<- openFile file ReadMode
               s <- hGetContents f
               sendToNetwork s --made up function
               hClose f

In your example, you're getting "" because the handle is closed, so 
Haskell doesn't have anything to read.
You say you can't use putStr in this scenario, but if you're reading the 
file you must be doing something with the contents. Wait to close the 
handle until after that operation takes place.

> Also, I noticed that opening a file and locking it involves a
> very verbose seeming dance. (It's 2 lines of code in most other languages.)
> Does this indicate that few people bother with file locking in Haskell
> and so it still has these rough edges, or that there's a better way to do
> it that I have not found yet?
>
> openLocked file = do
>          handle<- openFile file ReadMode
>          lockfd<- handleToFd handle -- closes handle
>          waitToSetLock lockfd (ReadLock, AbsoluteSeek, 0, 0)
>          handle'<- fdToHandle lockfd
>          return handle'
>
You should go to haskell.org/hoogle, and search openFile, or check out 
the Haskell98 report, but I'm under the impression that ghc locks the 
file for you when you open the file.:
 From haskell98 report:


        21.2.3 File locking

Implementations should enforce as far as possible, at least locally to 
the Haskell process, multiple-reader single-writer locking on files. 
That is, /there may either be many handles on the same file which manage 
input, or just one handle on the file which manages output/. If any open 
or semi-closed handle is managing a file for output, no new handle can 
be allocated for that file. If any open or semi-closed handle is 
managing a file for input, new handles can only be allocated if they do 
not manage output. Whether two files are the same is 
implementation-dependent, but they should normally be the same if they 
have the same absolute path name and neither has been renamed, for example.


        21.3.1 Opening Files

...

/Error reporting/: the openFile computation may fail with 
isAlreadyInUseError if the file is already open and cannot be reopened; 
isDoesNotExistError if the file does not exist; orisPermissionError if 
the user does not have permission to open the file



Hope this helps,
Jimmy Wylie


-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
http://www.haskell.org/pipermail/beginners/attachments/20101009/d3bd5364/attachment-0001.html

------------------------------

Message: 3
Date: Sat, 09 Oct 2010 21:52:35 -0400
From: Isaac Dupree <[email protected]>
Subject: Re: [Haskell-beginners] how to read file with locking
To: Joey Hess <[email protected]>
Cc: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed

On 10/09/10 18:49, Joey Hess wrote:
> The function below always returns "", rather than the file's contents.
> _Real World Haskell_ touches on how laziness can make this problimatic,
> without really giving a solution, other than throwing in a putStr to
> force evaluation, which can't be done here. How can I make  hGetContents
> strict, to ensure the file contents are really read before it gets closed?

There are various hacks to do it (including ones with no external 
side-effects that just use "case" / "seq" / etc. quite thoroughly)... 
But realistically you should use a library that doesn't add laziness, if 
laziness is not what you want. For example, "strict" on Hackage
http://hackage.haskell.org/package/strict
http://hackage.haskell.org/packages/archive/strict/0.3.2/doc/html/System-IO-Strict.html

-Isaac


------------------------------

Message: 4
Date: Sun, 10 Oct 2010 06:39:11 +0200
From: Ertugrul Soeylemez <[email protected]>
Subject: [Haskell-beginners] Re: how to read file with locking
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=US-ASCII

Joey Hess <[email protected]> wrote:

> The function below always returns "", rather than the file's contents.
> _Real World Haskell_ touches on how laziness can make this
> problimatic, without really giving a solution, other than throwing in
> a putStr to force evaluation, which can't be done here. How can I make
> hGetContents strict, to ensure the file contents are really read
> before it gets closed?

In general you don't want to read a file as a String non-lazily.  That
uses a lot of memory, because String is just a type alias for [Char],
which means a linked list of Char values.

To read an entire file eagerly the proper way is in most cases using
Data.ByteString or Data.ByteString.Char8, which have a strict interface.
A ByteString from those modules is always either non-evaluated or
completely evaluated, and it is a real byte array instead of a linked
list.  Both modules feature hGetContents:

  import qualified Data.ByteString.Char8 as B

  readFileLocked :: FilePath -> IO B.ByteString
  readFileLocked fn =
    withFile fn ReadMode $ \h -> do
      lockFile h  -- for a suitable function lockFile
      B.hGetContents h

It is, BTW, always preferable to use withFile over openFile, if you can.
This makes your code cleaner and also exception-safe.


Greets,
Ertugrul


-- 
nightmare = unsafePerformIO (getWrongWife >>= sex)
http://ertes.de/




------------------------------

Message: 5
Date: Sun, 10 Oct 2010 12:01:59 +0100
From: Tom Doris <[email protected]>
Subject: [Haskell-beginners] reproducing HashTable benchmark
To: Haskell Beginners <[email protected]>
Message-ID:
        <[email protected]>
Content-Type: text/plain; charset="iso-8859-1"

I've been investigating the performance of some word frequency counting code
I wrote, and I came across this stackoverflow thread
http://stackoverflow.com/questions/3058529/curious-about-the-hashtable-problemwhere
Dons shows simple benchmarks for HashTable and IntMap, but I can't
reproduce the "after the fix" performance of the HashTable code, I am very
confused as to what version of ghc actually has the fix.

In the post Don writes "With GHC 6.10.2, before the fix, inserting 10M
ints:" and then "With GHC 6.13, after the fix:", is this a typo, shouldn't
it read 6.10.3? Since there is no 6.13 version of ghc yet? If it should be
6.10.3, and I'm running v 6.12.1, why does the HashTable code in Don's post
take 22 seconds to run on my machine (compiled ghc --make -O2) and the
IntMap version takes only 5.8s? How can one find out what release the fix
for ticket #650 was released into? I've tried the release notes but I can't
seem to spot it, and google doesn't either. The ticket has "Milestone:
6.12.2" but that is struck-through, though the comments would suggest this
made it into r 6.12.2, I can't spot anything in the release notes for that
version either.

Can someone help clarify which version the fix will be/is in and how one
should figure this out in general for other issues?

Thanks
Tom
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
http://www.haskell.org/pipermail/beginners/attachments/20101010/7db556b4/attachment-0001.html

------------------------------

Message: 6
Date: Sun, 10 Oct 2010 14:10:55 +0200
From: Daniel Fischer <[email protected]>
Subject: Re: [Haskell-beginners] reproducing HashTable benchmark
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain;  charset="utf-8"

On Sunday 10 October 2010 13:01:59, Tom Doris wrote:
> I've been investigating the performance of some word frequency counting
> code I wrote, and I came across this stackoverflow thread
> http://stackoverflow.com/questions/3058529/curious-about-the-hashtable-p
>roblemwhere Dons shows simple benchmarks for HashTable and IntMap, but I
> can't reproduce the "after the fix" performance of the HashTable code, I
> am very confused as to what version of ghc actually has the fix.
>
> In the post Don writes "With GHC 6.10.2, before the fix, inserting 10M
> ints:" and then "With GHC 6.13, after the fix:", is this a typo,
> shouldn't it read 6.10.3? Since there is no 6.13 version of ghc yet?

And there never will be. GHC's versioning scheme for releases is

series.even-branch-number.patchlevel

Odd numbers in second place indicate the development branch (aka HEAD).

So 6.13 was the development branch after 6.12 was released. Originally, a 
6.14 release was planned, but there have been so significant changes that 
the next release (due in a few weeks, probably end of October) will be the 
first of the 7 series (and HEAD is now 7.1, no longer 6.13).

> If it should be 6.10.3, and I'm running v 6.12.1, why does the HashTable
> code in Don's post take 22 seconds to run on my machine (compiled ghc
> --make -O2) and the IntMap version takes only 5.8s? How can one find out
> what release the fix for ticket #650 was released into? I've tried the
> release notes but I can't seem to spot it, and google doesn't either.
> The ticket has "Milestone: 6.12.2" but that is struck-through, though
> the comments would suggest this made it into r 6.12.2, I can't spot
> anything in the release notes for that version either.

Not sure what goes in the release notes, nor whether the fix was in 6.12.2.
But the patch was merged nine months ago, it should be in 6.12.2 (but if 
you upgrade within the 6.12 series, choose 6.12.3, there were some bugs in 
6.12.2 iirc).
However, if it's not pressing, consider waiting for the release of GHC 7.

>
> Can someone help clarify which version the fix will be/is in and how one
> should figure this out in general for other issues?

In general, ask or test. But if you found a ticket for the issue, if it's 
closed with a merge, any release later than a few eeeks after the merge 
should contain the fix (unless it's explicitly stated that the patch will 
not go to the stable branch).

>
> Thanks
> Tom



------------------------------

_______________________________________________
Beginners mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/beginners


End of Beginners Digest, Vol 28, Issue 17
*****************************************

Reply via email to