Re: [Haskell-cafe] Can't figure out source of race condition when using System.Process

2008-11-02 Thread David Roundy
On Sun, Nov 02, 2008 at 09:15:25PM +0100, Marc Weber wrote:
 On Mon, Nov 03, 2008 at 01:02:12AM +1100, Rafal Kolanski wrote:
   Rafal Kolanski.
  -- Pass text to md5sum and drop the final   - when returning
  hashMD5 text = do
  (inp,out,err,pid) - runInteractiveProcess md5sum [] Nothing Nothing
  forkIO $ do 
  hPutStrLn inp text
  hClose inp
  exit - waitForProcess pid
  case exit of ExitFailure _ - error md5sum fail 
   _ - return ()
  [...]
 
 Why do you use forkIO here? It's not necessary. The process will run in
 background on its own. ?

It looks to me like this code requires a forkIO, not in the writing to inp,
but rather in the reading of out and err.  Otherwise, those buffers may
fill up and your process will hang...
-- 
David Roundy
http://www.darcs.net
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: [darcs-users] Poll: Do you need to be able to build darcs from source on GHC 6.6?

2008-10-31 Thread David Roundy
On Thu, Oct 30, 2008 at 01:30:51PM -0700, Jason Dagit wrote:
 On Thu, Oct 30, 2008 at 1:22 PM, Juliusz Chroboczek
 [EMAIL PROTECTED] wrote:
  Also, note that Lenny has 6.8, and it is scheduled to become stable Real
  Soon Now.
 
  That's irrelevant.  Lenny going stable will not cause my servers to
  automatically get upgraded.
 
  FWIW, the experimental server is scheduled to switch to lenny in the summer
  of 2009.  There is no ETA for the production servers, which tend to be
  managed more conservatively still.
 
 But surely if you have such conservative upgrade practices you also
 only run stable releases of darcs right?  All the existing stable
 releases build on ghc6.6.
 
 I was not sufficiently clear in my original question.  My question
 really only applies to people who build from the darcs.net
 respository.  HEAD as some people might call it.

No, darcs is buggier than the average code, and it's reasonable to
want those bugs fixed, even on stable servers.

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: [darcs-users] Poll: Do you need to be able to build darcs from source on GHC 6.6?

2008-10-31 Thread David Roundy
On Thu, Oct 30, 2008 at 03:08:29PM -0700, Don Stewart wrote:
 dagit:
  On Thu, Oct 30, 2008 at 1:20 PM, Juliusz Chroboczek
  [EMAIL PROTECTED] wrote:
   I wanted to know if anyone who is using distros with 6.6 need to be
   able to build current releases of darcs from source.
  
   If there turns out to be a significant issue with Darcs 1, I need to be
   able to build a recent version of Darcs in my Debian stable chroot.
  
  I see.  If you're using the darcs 1 binary I would encourage you to
  upgrade.  If  you meant darcs 1 repository format then I would
  encourage you to consider darcs 1 hashed repository format.  You don't
  even have to upgrade the public facing repo.  Just 'darcs get --hashed
  ...'.
  
   The alternative is to build a static version of Darcs that I can install 
   on
   my stable (soon to be oldstable) servers.  Last time I checked, building
   static Darcs didn't work.
  
  Interesting.  Yes, building darcs statically is something we should
  probably do on the build bots.
 
 Statically linked darcs should be trivial with the cabal version.

The bug is in debian's libcurl.

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [darcs-users] [Haskell-cafe] Poll: Do you need to be able to build darcs from source on GHC 6.6?

2008-10-30 Thread David Roundy
On Thu, Oct 30, 2008 at 12:16:17PM +1100, Trent W. Buck wrote:
 David Roundy [EMAIL PROTECTED] writes:
  And as far as bundled versions, it's the desire to *remove* a bundled
  version that's apparently at issue.  I'm not sure why this is
  considered desirable, but apparently some folks feel strongly about
  this.
 
 Could someone please summarize what code is currently bundled with darcs
 that isn't darcs?  I had the impression that most of it was in house
 code that had/has not been formalized into a separate libraries yet
 (e.g. an FFI for zlib, byte strings before they were librarified).

Yes, that's what I was referring to.  The bytestring library is a
descendant of the FastPackedString module that is still in darcs.  Recently
Ganesh added the ability for darcs to use bytestring instead if its own
code, and dons has submitted code to remove FastPackedString in favor of
bytestring.

 To me, that's different from a bundled (convenience) copy, which is
 where you basically download libfoo's tarball, unpack it in your source
 tree, and then do darcs rec -lam 'Install copy of libfoo 5.1'.

Yes, I agree.  But continuing to keep our own code has the same sorts of
benefits that bundling other libraries has (without the legal hassle).
-- 
David Roundy
http://www.darcs.net
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Poll: Do you need to be able to build darcs from source on GHC 6.6?

2008-10-29 Thread David Roundy
On Wed, Oct 29, 2008 at 11:17:35AM -, Mitchell, Neil wrote:
 Duncan,
 
 I believe the major darcs issue is the changed GADT implementation
 between 6.6, so that neither 6.6 or 6.8 is a superset/subset of the
 other - leading to a situation where they have to use a common subset of
 both.

No, the 6.6 gadts are nicer than the 6.8 gadts, but the common subset
is pretty large.  Duncan has the issue right: it's the desire to
reduce the number of dependencies that's at issue.  And as far as
bundled versions, it's the desire to *remove* a bundled version that's
apparently at issue.  I'm not sure why this is considered desirable,
but apparently some folks feel strongly about this.

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: [darcs-users] Poll: Do you need to be able to build darcs from source on GHC 6.6?

2008-10-28 Thread David Roundy
Yes, it's important for me to be able to use the latest darcs on my
debian stable computers.

David

On Mon, Oct 27, 2008 at 10:24 PM, Jason Dagit [EMAIL PROTECTED] wrote:
 Hello,

 I would like to find out if any darcs users who build from the source
 are still using ghc 6.6?

 If you are such a user, please let me know.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Why 'round' does not just round numbers ?

2008-10-28 Thread David Roundy
On Tue, Oct 28, 2008 at 04:07:12PM +, Bart Massey wrote:
 I'm just saying that the name round is unfortunate, since
 there's no single universally accepted mathematical
 definition for it. For this reason many programming
 languages either don't provide it or provide a different
 version.  The names roundHalfUp and roundHalfEven are
 much better: they each correspond to a well-known
 mathematical function that is codified in an IEEE standards
 document.
 
 If it were up to me, I'd deprecate round in Haskell' and
 make the documentation point to these other rounding
 functions.
 
 Our solution in Nickle (http://nickle.org), BTW, was to
 provide floating point with user-settable mantissa precision
 and a default precision of 256 bits.  For all practical
 purposes we know of, this makes worrying about the edge
 cases for rounding pointless.  Kahan has a nice paper on
 this that I can't find right now.

Isn't it quite common to have numbers like 0.5 as input? (as an
example of a number that's exactly representable in any binary
floating point format, but whose rounded value depends on rounding
convention.

I don't feel strongly on the question, but was somewhat surprised to
find that round is present, for the reasons you mention.  floor (x+0.5)
is not a bad way to round... no one will mistakenly thing that it'll
do something smart with half-integers.

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] [Somewhat OT] Speed

2008-10-28 Thread David Roundy
On Tue, Oct 28, 2008 at 08:55:59PM +0100, Henning Thielemann wrote:
 For example, is integer arithmetic faster or slower than
 floating-point?

 In principle integer arithmetic is simpler and faster. But your
 processor may do it in the same time.

Indeed.  Usually there are more integer arithmetic units, so more
integer arithmetic can be done in parallel.

 Is addition faster or slower than multiplication?

 Multiplication can be done almost as fast as addition. This is so, 
 because a sum of n numbers can be computed much faster than n individual  
 additions.

 How much slower are the trigonometric functions?

 division, square root are similar in complexity. exp, log, arctan can be  
 implemented with a school division like algorithm (CORDIC) and are 
 similar in performance.

Last I looked (which was quite a while back, but considerably more
recent than the 68k or Z80...), floating point division was the
surprise slow operation (close to the cost of a transcendental), with
square root being 5-10 times faster.  Generally, floating point
multiplies and adds have a throughput of 1 or 2 per clock cycle, with
most modern processors having a fused mutliply-add.

It does pay to reduce the number of divides and floating point
operations... but probably not if you're writing in Haskell.  :)

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: [darcs-users] Poll: Do you need to be able to build darcs from source on GHC 6.6?

2008-10-28 Thread David Roundy
On Wed, Oct 29, 2008 at 12:11:22PM +1100, Trent W. Buck wrote:
  Thus I think the version/upgrade matrix is handy so we can
  plan/schedule when it is safe to drop support.
 
 In an ideal world, we just make sure it builds with the latest tools,
 and let the users of stable distros worry about telling us if it
 breaks against whatever versions they care about.

No, in the idea world we'd try to be supportive of our contributors and
maintainers by not requiring that they install the latest tools.
-- 
David Roundy
http://www.darcs.net
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Repair to floating point enumerations?

2008-10-16 Thread David Roundy
On Thu, Oct 16, 2008 at 05:36:35PM +0200, Henning Thielemann wrote:
 On Wed, 15 Oct 2008, David Roundy wrote:
 On Wed, Oct 15, 2008 at 11:25:57PM +0200, Henning Thielemann wrote:
 David Roundy schrieb:

 Why not look for a heuristic that gets the common cases right, rather
 than going with an elegant wrong solution? After all, these
 enumerations are most often used by people who neither care nor know
 how they're implemented, but who most likely would prefer if haskell
 worked as well as matlab, python, etc.

  Although MatLab has a lot of bad heuristics, they fortunately didn't
 try to be too clever with respect to rounding errors. Floating point
 enumerations have the same problems in MatLab as in all other languages.

 I presume you say this because you haven't tried qusing matlab?

 I had to use MatLab in the past and remembered problems with rounding
 errors. What you show indicates that they try to be more clever, though.
 But they can't make floating point numbers precise rationals.

Of course not.  It doesn't mean that we shouldn't try to make the
common cases work.

 I suspect that all algorithms that try to solve problems of floating
 point numbers will do something unexpected in certain circumstances. So,
 I think it is better they do it in a way that can be predicted easily. I
 feel much safer with enumeration of integers which are converted to
 floating point numbers than using a heuristics for floating point
 numbers.

I agree that it's nice to have functions whose behavior can be
predicted easily.  This isn't always possible with floating point
numbers due to roundoff error.  The proposed change to the Prelude
removes this easy-predicting behavior.  The Prelude was written such
that it was easy to predict what the result would be unless the stop
value is a half-integer number of steps.  This change makes behavior
hard to predict when the stop value is an integer number of steps.  I
assert that an integer number of steps is a more common situation than
a half-integer number of steps, and therefore the Haskell 98 Prelude's
behavior was better.  It isn't be best solution, but it's better than
the proposed alternative.

And with simple syntax, I think simple behavior is best--which means
it should not be dependent on details of roundoff error.

Another alternative would be to say

import Data.Ratio ( (%) )

xxx m n p = map (scale . fromRational . (%num)) [0..num]
  where num = round ((p-m)/(n-m))
scale f = m*(1-f) + p*f

This gives up even approximating the property that each element of the
output differs by (m-n) (which was never true in any of the proposed
implementations, and is impossible in any case).  And in exchange, we
always get a sequence with the requested beginning and ending values.

It has the downside that

(map fromInteger [0,2..9]) :: [Float]

gives a different result from [0,2..9] :: [Float].

But we gain the new feature that

(map fromInteger [1,2..1]) :: [Float]

gives the same result as

[1,2..1] :: [Float]

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Repair to floating point enumerations?

2008-10-15 Thread David Roundy
On Wed, Oct 15, 2008 at 11:25:57PM +0200, Henning Thielemann wrote:
 David Roundy schrieb:
 
  Why not look for a heuristic that gets the common cases right, rather
  than going with an elegant wrong solution? After all, these
  enumerations are most often used by people who neither care nor know
  how they're implemented, but who most likely would prefer if haskell
  worked as well as matlab, python, etc.
 
  Although MatLab has a lot of bad heuristics, they fortunately didn't
 try to be too clever with respect to rounding errors. Floating point
 enumerations have the same problems in MatLab as in all other languages.

I presume you say this because you haven't tried qusing matlab?  I
don't know what their algorithm is, but matlab gives:

 sprintf('%.20f\n', (0:0.1:0.3), 0.1*3, 0.1+0.1+0.1, 0.3)

ans =

0.
0.1555
0.19998335
0.29998890
0.30004441
0.30004441
0.29998890

from which you can clearly see that matlab does have special handling
for its [0,0.1..0.3] syntax.  For what it's worth, octave has the same
behavior:

octave:1 sprintf('%.20f\n', (0:0.1:0.3), 0.1*3, 0.1+0.1+0.1, 0.3)
ans = 0.
0.1555
0.20001110
0.29998890
0.30004441
0.30004441
0.29998890

I don't know what they're doing, but obviously they're doing something
clever to make this common case work.  They presumably use different
algorithms, since octave gives a different answer for the 0.2 than
matlab does.  Matlab's value here is actually less that 0.1 and it's
also less than 2*0.1, which is a bit odd.  Both agree that the final
element in the sequence is 0.3.

The point being that other languages *do* put care into how they
define their sequences, and I see no reason why Haskell should be
sloppier.

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Linking and unsafePerformIO

2008-10-14 Thread David Roundy
On Tue, Oct 14, 2008 at 04:39:38PM +0100, Claus Reinke wrote:
 Where do the semantics of haskell say this? How does it interact with
 fixing bugs (which means changing mathematical and universal constant
 functions--since all functions are constants)?

 What semantics of haskell?-) But if there was one, it might not talk
 about separate compilation (it should, though), or packages. And if
 you consider cross-package inlining, separate package updates, or
 dynamic linking, etc, you might want to flag all variable constants as  
 {-# NOINLINE c #-}, and perhaps even switch of any CSE-style
 optimizations. The usual bag of tricks for unsafePerformIO constants.

But in this case you'd also have to use the same flags for any
functions you might want to edit later.  It's always the job of the
compiler and/or build system to ensure that the compile is consistent.
But claiming that it's wrong to edit your source code is downright
silly, even if it is true that the compiler could then be more
aggresive in its optimizations...

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Linking and unsafePerformIO

2008-10-14 Thread David Roundy
On Tue, Oct 14, 2008 at 05:20:35PM +0100, Jules Bean wrote:
 David Roundy wrote:
 On Tue, Oct 14, 2008 at 04:05:23PM +0100, Jules Bean wrote:
 Constants are mathematical and universal, like pi. That is what the
 semantics of haskell say.

 Where do the semantics of haskell say this? 

 You should better ask 'which semantics?'.

 The semantics in which a value of type Int - Int is denoted by a
 mathematical function from Int to Int. In that semantics a value of
 type Int denotes a specific Int.  And that denotation is, of
 course, entirely independent of compiler or OS or package or dynamic
 loading or any concern like that.

 This is, to my mind the often assumed but never written down
 semantics of haskell. It's certainly the semantics *I* want haskell
 to have.

  How does it interact with fixing bugs (which means changing
  mathematical and universal constant functions--since all functions
  are constants)?

 That's fine. Changing a program changes it denotation.

 Running a program on a different interpreter or compiler had better
 not change its denotation, otherwise it [the denotation] is not much
 use as a basis for reasoning.

But you're saying above that we can't change programs, right? You
probably won't be surprised to hear that different compilers are
different programs.  And different packages are also different
programs.  Are you the only one who's allowed to fix bugs?

I personally feel that it's a valuable feature that we're allowed to
implement distinct libraries with a shared API, which is a feature
that you claim violates the semantics you want haskell to have.

I would say that putting constants that are known at compile time into
the IO monad is an abuse of the IO monad, since those constants have
nothing to do with IO, and are in fact *constants* which cannot vary
at run time.

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Linking and unsafePerformIO

2008-10-14 Thread David Roundy
On Tue, Oct 14, 2008 at 04:05:23PM +0100, Jules Bean wrote:
 David Roundy wrote:
 (Sure this is a weird situation, but I do like to think about worst
 cases.)
 In practice that is fine, with current RTSes and so on.

 In principle it's not fine. A 'constant' should be constant over all  
 time, not just constant over a particular library version or 
 sub-version or a particular program invocation or OS or

 No, constants don't have to constant over all time.  e.g. it's perfectly
 fine for compilers to implement System.Info, whose sole purpose to provide
 constants that are different in different library versions and OSs.

 http://haskell.org/ghc/docs/latest/html/libraries/base/System-Info.html#v:os

 I entirely disagree.

 That API is broken. All those things should be in the IO monad.

 I might have code which migrates at runtime between different
 OSes. Of course i can't, and even if I did, it would probably return
 something different like 'virtual haskell migration pseudo-OS', but
 that's not the point.

 Constants are mathematical and universal, like pi. That is what the
 semantics of haskell say.

Where do the semantics of haskell say this? How does it interact with
fixing bugs (which means changing mathematical and universal constant
functions--since all functions are constants)?

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Linking and unsafePerformIO

2008-10-14 Thread David Roundy
On Tue, Oct 14, 2008 at 02:05:02PM +0100, Jules Bean wrote:
 Mauricio wrote:
 If I have a Haskell wrapper (with unsafe...)  over a function that's
 never going to return different values and is always side-effect free,
 but can change depending on compile time options of its library; my
 program is running, and then the version of my library is updated by my
 distribution smart instalation system, which does update versions of
 libraries in use; is it possible that I get a wrong behavior of my
 program?

If you're talking aout an FFI function, the best option (in my opinion)
would be to not import it in the IO monad, if possible.  Which you couldn't
do if it does something like allocate a C string... but in many cases this
would be the cleanest approach.

 I do not understand enough about package management to understand how
 running programs or libraries are updated, and less about how linking
 works between Haskelll and libraries on other languages, so I don't know
 if my program is guaranteed to stay with a single version of a library
 for each run.
 
 (Sure this is a weird situation, but I do like to think about worst
 cases.)
 
 In practice that is fine, with current RTSes and so on.
 
 In principle it's not fine. A 'constant' should be constant over all 
 time, not just constant over a particular library version or sub-version 
 or a particular program invocation or OS or

No, constants don't have to constant over all time.  e.g. it's perfectly
fine for compilers to implement System.Info, whose sole purpose to provide
constants that are different in different library versions and OSs.

http://haskell.org/ghc/docs/latest/html/libraries/base/System-Info.html#v:os

 Who knows, maybe some future haskell runtime will be able to perform the 
 trickery you describe and will cause this to break ;)

No, that sort of trickery breaks referential transparency, and itself is
unsafe.  It is in fact safe to assume that the RTS will never break
referential transparency.

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] System.Process

2008-09-30 Thread David Roundy
On Tue, Sep 30, 2008 at 10:14:38AM +0200, Ketil Malde wrote:
 Svein Ove Aas [EMAIL PROTECTED] writes:
  All programs want argument arrays, not un-split lines, and if you
  don't have the shell split it you'll have to do it yourself. words
  works fine.
 
 ...as long as the words don't contain quotes, or wildcard/globbing
 characters, or $, ! and probably other things I can't think of right
 now?

Actually, it's no problem having any of those characters in your
arguments, it's just that they'll be passed literally (which may or
may not be what your user wants--sometimes it's really convenient to
avoid multiple layers of escapes).  The one constraint that using
words makes is that it doesn't allow you to specify arguments that
contain a space.

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] System.Process

2008-09-30 Thread David Roundy
On Tue, Sep 30, 2008 at 06:33:52PM +0200, Ketil Malde wrote:
 David Roundy [EMAIL PROTECTED] writes:
  Actually, it's no problem having any of those characters in your
  arguments,
 
 My point is that using 'words' on the argument sting to 'runProcess' and
 expecting the same result as 'runCommand' implies making those assumptions::

My point was that which of these is correct entirely depends on what
your input is.  It's often a huge (and security-bug-prone) chore to
escape all those shell characters, and so in many cases it's much
nicer to execute an external program direcly without invoking a
shell.

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: [Haskell] ICFP programming contest results

2008-09-24 Thread David Roundy
On Wed, Sep 24, 2008 at 1:06 AM, Malcolm Wallace
[EMAIL PROTECTED] wrote:
 The ICFP programming contest results presentation:
 http://video.google.com/videoplay?docid=-4697764813432201693

 Feel free to pass on this link to any other appropriate forum.

Yikes.  Haskell did pretty terribly! Anyone have an idea why, given
our success in previous contests?

David (speaking as someone who was traveling that weekend and didn't
have time to compete)
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] readFile and closing a file

2008-09-18 Thread David Roundy
On Thu, Sep 18, 2008 at 05:38:51PM +0200, Henning Thielemann wrote:
 On Wed, 17 Sep 2008, Mitchell, Neil wrote:
 I tend to use openFile, hGetContents, hClose - your initial readFile
 like call should be openFile/hGetContents, which gives you a lazy
 stream, and on a parse error call hClose.

 Yes, this seems to be the right way. This weakness should be mentioned in
 the docs of readFile. In production code, you cannot rely on a garbage
 collector to close the file, because you might want to open a file for
 writing after you have processed it with readFile, and there is warranty
 that the file is already closed then.

Ah, so you must be concerned about windows systems? Yes, on windows
systems it's definitely best to never to lazy IO.  On non-windows file
systems, unless you're planning on opening thousands of files, relying
on the garbage collector is fine.

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] readFile and closing a file

2008-09-17 Thread David Roundy
On Wed, Sep 17, 2008 at 01:31:26PM +0200, Henning Thielemann wrote:
 Say I acquire a text by readFile, feed it to a lazy parser and the parser 
 stops reading because of a parse error. After the parser error I won't  
 fetch more characters from the text file, but readFile does not get to  
 know that and cannot close the file. Actually, when encountering a parser 
 error I could read the remaining characters from the file in order to let 
 readFile close the file eventually, but this sounds rather inefficient.  
 So, what is the right way to go, or do I have to stay away from readFile  
 (and maybe unsafeInterleaveIO at all)?

Eventually the garbage collector should close the file, I believe.

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] about openTempFile

2008-09-17 Thread David Roundy
On Wed, Sep 17, 2008 at 02:10:56PM +0100, Dougal Stanton wrote:
 On Wed, Sep 17, 2008 at 1:17 PM, Manlio Perillo
 [EMAIL PROTECTED] wrote:
  The Python tempfile module, as an example, implements a wrapper around
  mkstemp function that does exactly this, and the code is portable; on
  Windows it uses O_TEMPORARY_FILE flag, on POSIX systems the file is
  unlink-ed as soon as it is created (but note that the code is not signal
  safe - well, many functions in the Python standard library are not signal
  safe).
 
 Something like:
 
  withTempFile :: String - ((FilePath, Handle) - IO b) - IO b
  withTempFile name action = do
  tmpdir - getTemporaryDirectory
  bracket
  (openTempFile tmpdir name)
  (\(fp,h) - hClose h  removeFile fp)
  action
 
 I don't know if this has the safety requirements you mean?

You need to be sure to use the bracket from Control.Exception, not the
one from System.IO or IO (which won't work).  And you also need
special work to make the code safe from signals.  But basically, this
is the right idea.

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] about openTempFile

2008-09-17 Thread David Roundy
On Wed, Sep 17, 2008 at 04:51:07PM +0100, Mitchell, Neil wrote:
   But since GHC does not implement such a function, I was curious to 
   know why it don't even implement a function that make sure the 
   temporary file is removed.
   
  
  Because it is two lines to write, so no one has yet proposed 
  it for the base library. 
 
 Map is 2 lines, but we have that as a library (1 line in Hugs).
 Otherwise is a whole one lexeme long, but we still provide a library
 function.
 
 This one is tricky and has lots of edge cases! If its useful, it should
 be in the libraries.

In particular, the code Don quoted is incorrect depending on which
import statements are used.  If we assume that the default is the
bracket available in Haskell 98, then it is definitely incorrect.

It also doesn't behave properly in the presence of signals or keyboard
interrupts (i.e. posix or windows systems).  Of course, a larger
change in the standard libraries is needed in order to solve this
particular problem, so I'd want to agree on a solution for that
problem first.  Which is perhaps a better reason why it's not yet in
the standard libraries: it's perhaps not a good idea to put a function
with such serious issues into the standard libraries.

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] about openTempFile

2008-09-17 Thread David Roundy
On Wed, Sep 17, 2008 at 10:11:28PM +0200, Manlio Perillo wrote:
 David Roundy ha scritto:
 [...]
 In particular, the code Don quoted is incorrect depending on which
 import statements are used.  If we assume that the default is the
 bracket available in Haskell 98, then it is definitely incorrect.

 It also doesn't behave properly in the presence of signals or keyboard
 interrupts (i.e. posix or windows systems).  

 Maybe a withSignalsMasked function, at least on Posix systems (it is not  
 defined in System.Posix.Signals)?

Darcs does something like this, and I obviously think it should be
moved into the standard libraries.  In my opinion signals ought to
throw asynchronous exceptions by default, then we'd have unified
handling of exceptional cases.

 I have no idea how signals works under Windows.

Windows doesn't have signals per se, but does have something similar
for keyboard interrupts, which in darcs we also convert into an
asynchronous exception.  I'm not clear as to how well it works.  Under
cygwin shells, ctrl-C does something other than send a windows
keyboard interrupt, so darcs doesn't work so well in that
environment.

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Can you do everything without shared-memory concurrency?

2008-09-10 Thread David Roundy
2008/9/9 Jed Brown [EMAIL PROTECTED]:
 On Tue 2008-09-09 12:30, Bruce Eckel wrote:
 So this is the kind of problem I keep running into. There will seem to be
 consensus that you can do everything with isolated processes message passing
 (and note here that I include Actors in this scenario even if their mechanism
 is more complex). And then someone will pipe up and say well, of course, you
 have to have threads and the argument is usually for efficiency.

 Some pipe up and say ``you can't do global shared memory because it's
 inefficient''.  Ensuring cache coherency with many processors operating
 on shared memory is a nightmare and inevitably leads to poor
 performance.  Perhaps some optimizations could be done if the programs
 were guaranteed to have no mutable state, but that's not realistic.
 Almost all high performance machines (think top500) are distributed
 memory with very few cores per node.  Parallel programs are normally
 written using MPI for communication and they can achieve nearly linear
 scaling to 10^5 processors BlueGene/L for scientific problems with
 strong global coupling.

I should point out, however, that in my experience MPI programming
involves deadlocks and synchronization handling that are at least as
nasty as any I've run into doing shared-memory threading.  This isn't
an issue, of course, as long as you're letting lapack do all the
message passing, but once you've got to deal with message passing
between nodes, you've got bugs possible that are strikingly similar to
the sorts of nasty bugs present in shared memory threaded code using
locks.

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Can you do everything without shared-memory concurrency?

2008-09-10 Thread David Roundy
On Wed, Sep 10, 2008 at 03:30:50PM +0200, Jed Brown wrote:
 On Wed 2008-09-10 09:05, David Roundy wrote:
  2008/9/9 Jed Brown [EMAIL PROTECTED]:
   On Tue 2008-09-09 12:30, Bruce Eckel wrote:
   So this is the kind of problem I keep running into. There will seem to be
   consensus that you can do everything with isolated processes message 
   passing
   (and note here that I include Actors in this scenario even if their 
   mechanism
   is more complex). And then someone will pipe up and say well, of 
   course, you
   have to have threads and the argument is usually for efficiency.
  
   Some pipe up and say ``you can't do global shared memory because it's
   inefficient''.  Ensuring cache coherency with many processors operating
   on shared memory is a nightmare and inevitably leads to poor
   performance.  Perhaps some optimizations could be done if the programs
   were guaranteed to have no mutable state, but that's not realistic.
   Almost all high performance machines (think top500) are distributed
   memory with very few cores per node.  Parallel programs are normally
   written using MPI for communication and they can achieve nearly linear
   scaling to 10^5 processors BlueGene/L for scientific problems with
   strong global coupling.
 
  I should point out, however, that in my experience MPI programming
  involves deadlocks and synchronization handling that are at least as
  nasty as any I've run into doing shared-memory threading.

 Absolutely, avoiding deadlock is the first priority (before error
 handling).  If you use the non-blocking interface, you have to be very
 conscious of whether a buffer is being used or the call has completed.
 Regardless, the API requires the programmer to maintain a very clear
 distinction between locally owned and remote memory.

Even with the blocking interface, you had subtle bugs that I found
pretty tricky to deal with.  e.g. the reduce functions in lam3 (or was
it lam4) at one point didn't actually manage to result in the same
values on all nodes (with differences caused by roundoff error), which
led to rare deadlocks, when it so happened that two nodes disagreed as
to when a loop was completed.  Perhaps someone made the mistake of
assuming that addition was associative, or maybe it was something
triggered by the non-IEEE floating point we were using.  But in any
case, it was pretty nasty.  And it was precisely the kind of bug that
won't show up except when you're doing something like MPI where you
are pretty much forced to assume that the same (pure!) computation has
the same effect on each node.

  This isn't an issue, of course, as long as you're letting lapack do
  all the message passing, but once you've got to deal with message
  passing between nodes, you've got bugs possible that are strikingly
  similar to the sorts of nasty bugs present in shared memory threaded
  code using locks.

 Lapack per-se does not do message passing.  I assume you mean whatever
 parallel library you are working with, for instance, PETSc.  Having the
 right abstractions goes a long way.

Right, I meant to say scalapack.  If you've got nice simple
abstractions (which isn't always possible), it doesn't matter if
you're using message passing or shared-memory threading.

 I'm happy to trade the issues with shared mutable state for distributed
 synchronization issues, but that is likely due to it's suitability for
 the problems I'm interested in.  If the data model maps cleanly to
 distributed memory, I think it is easier than coarse-grained shared
 parallelism.  (OpenMP is fine-grained; there is little or no shared
 mutable state and it is very easy.)

Indeed, data-parallel programming is nice and it's easy, but I'm not
sure that it maps well to most problems.  We're fortunate that it does
map well to most scientific problems, but as normal programmers are
thinking about parallelizing their code, I don't think data-parallel
is the paradigm that we need to lead them towards.

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Consequences of implementing a library in Haskell for C consumption?

2008-09-05 Thread David Roundy
On Thu, Sep 04, 2008 at 08:04:25PM -0500, Austin Seipp wrote:
 Excerpts from Justin Bailey's message of Thu Sep 04 17:00:58 -0500 2008:

  Looking at the package, I think would be pretty painful though. It
  seems I'd have to build the AST by hand,

 The AST Language.C defines for C is actually fairly regular once you
 wrap your head around it - I got it to generate working programs that
 I could compile in approximately an hour after looking through nothing
 but the documentation, essentially.

 The AST is very 'raw' though: I found that defining some simple
 functions for things like just creating a global variable, creating
 declarations and the like cut down on overall AST size tremendously
 (although hints of the AST types/constructors were still around, naturally.)

 Here's the example I put on HPaste a few days ago:

 http://hpaste.org/10059#a1

 You'll notice that the actual shim you're looking at - with the help
 of the defined functions - is actually fairly small, and those
 functions help out with those *a lot.* That was the first thing I
 wrote with it though, so the functions could probably be further
 generalized and abstracted.

Nice.

 On that note (although a little OT,) does anybody think it would be
 nice to have a higher level library designed specifically around
 emitting C that uses Language.C? A lot of repetetive stuff can be cut
 down considerably, I think.

That sounds great to me.  I'd love to see something like this with
some handy classes, so that I could write my haskell code using Int
and/or Integer rather than CInt.

e.g. change

mkConst (ConInt i)   = CConst $ CIntConst   (cInteger i) undef
mkConst (ConChar c)  = CConst $ CCharConst  (cChar c) undef
mkConst (ConFloat f) = CConst $ CFloatConst (readCFloat f) undef
mkConst (ConStr s)   = CConst $ CStrConst   (cString s) undef

to

class CConst i where
  mkConst i :: ???
instance CConst Int
instance CConst Double

etc.


David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Top Level -

2008-09-02 Thread David Roundy
On Tue, Sep 02, 2008 at 10:10:31AM +0100, Sittampalam, Ganesh wrote:
   Contrived example follows:
  
   module Module1 (mod1) where
   import Module2
  
   glob1 :: IORef Int
   glob1 - mod2 = newIORef
  
   mod1 :: IO Int
   mod1 = readIORef glob1
  
   module Module2 (mod2) where
 
   import Module1
 
   glob2 :: IORef Int
   glob2 - mod1 = newIORef
  
   mod2 :: IO Int
   mod2 = readIORef glob2
 
  This is illegal because you're only allowed to use ACIO
  in top level - bindings and readIORef isn't (and clearly
  could not be) ACIO.
 
 (made a couple of changes to quoted example; added import
 statements and explicit export lists)
 
 Even though I never call writeIORef on glob1 or glob2, and
 can change the example as above so we don't export them, so
 it's impossible to ever do so?
 
 As an alternative, consider
 
 module Module1 (mod1) where
 import Module2
 
 glob1 :: Int
 glob1 - return $! mod2
 
 mod1 :: Int
 mod1 = glob1
  
 module Module2 (mod2) where
 
 import Module1
 
 glob2 :: Int
 glob2 - return $! mod1
  
 mod2 :: Int
 mod2 = glob2
 
 Even more artificial, of course.
 
 Arguably both of these cases are not ACIO simply because
 of the non-termination effects, but it's not obvious to
 me how you tell just by looking at either one's code together
 with the declared API of the other. Is anything strict
 automatically forbidden by ACIO?

Isn't this just a pure infinite loop? Why is it a problem that ACIO
allows you the flexibility that's present in any pure code?

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: [Haskell] Top Level -

2008-08-28 Thread David Roundy
On Thu, Aug 28, 2008 at 01:17:29PM -0400, Dan Doel wrote:
 On Thursday 28 August 2008 12:26:27 pm Adrian Hey wrote:
  As I've pointed out several times already you can find simple examples
  in the standard haskell libs. So far nobody has accepted my challenge to
  re-implement any of these competantly (I.E. avoiding the use of global
  variables).
 
  Why don't you try it with Data.Unique and find out :-)
 
 Here's a first pass:
 
 -- snip --
 
 {-# LANGUAGE Rank2Types, GeneralizedNewtypeDeriving #-}
 
 module Unique where

If you want this to actually provide any guarantees, of course, you'll
have to provide an export list.

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Cleaning up the Debian act (report from the trenches)

2008-08-27 Thread David Roundy
On Wed, Aug 27, 2008 at 1:58 AM, Jason Dagit [EMAIL PROTECTED] wrote:
 2) Compile GHC yourself. You can even compile and install GHC (and most
 Haskell software) on a dedicated user account. In this way you avoid
 messing up you Debian installation if something goes wrong.

 I find with Debian this is the way to go.  Install your system and use
 Debian's packages for everything, and then install your own copy of
 anything for which you care what version you're running.

 Not everyone will like this option, but I find it's a decent balance
 between using what Debian provides and getting the satisfaction of
 using the versions of things I care about.

I've always used the version of ghc that comes with debian.  Part of
creating decent software is making sure that it compiles with a stable
non-bleeding-edge compiler that is readily available to users.  But
that's probably because  I'm lazy, and would rather write software
that just works than play with the latest bells and whistles.

I have had to compile ghc myself on a few occasions to help  the ghc
folks  track down compiler bugs (i.e. to check behavior under a
different compiler), but for normal use, I would say the sane thing is
to stick with the debian version of ghc.

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Haskell Propeganda

2008-08-26 Thread David Roundy
On Sat, Aug 23, 2008 at 6:15 PM, Daniel Fischer
[EMAIL PROTECTED] wrote:
 Am Samstag, 23. August 2008 23:17 schrieb Thomas Davie:

 I'd be interested to see your other examples -- because that error is
 not happening in Haskell!  You can't argue that Haskell doesn't give
 you no segfaults, because you can embed a C segfault within Haskell.

 Use ST(U)Arrays, and use unsafeWrite because you do the indexchecking
 yourself. Then be stupid and confuse two bounds so that you actually write
 beyond the array bounds.
 I've had that happen _once_.
 But if you explicitly say you want it unsafe, you're prepared for it :)

Which illustrates the point that it's not type safety that protects us
from segfaults, so much as bounds checking, and that's got a
non-trivial runtime cost.  At least, most segfaults that *I've* caused
(in C or C++) have been from overwriting the bounds of arrays, and
that's precisely the problem that Haskell does *not* solve using its
type system.  There have attempts to do so, but I've not heard of
instances where they have been used in real programs.

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] X Haskell Bindings

2008-08-18 Thread David Roundy
On 8/16/08, Antoine Latter [EMAIL PROTECTED] wrote:
  The following is a summary of my plan so far.  I'm interested in
  hearing any suggestions or concerns about what a Haskell library for
  writing X clients should look like.  This is not a release
  announcement, and I can't make any promises about when this will be
  delivered.

  Code is available in darcs:
  --  darcs get http://community.haskell.org/~aslatter/code/xhb

  Some of the  advantages XCB claims over xlib are:
   + smaller API
   + latency hiding when communicating with the X server
   + direct access to the X protocol
   + improved threading support
   + easier to extend

  What I plan for the X Haskell Bindings (XHB) are as follows:

It seems to me that you could make this a bit more haskelly...

   + All requests to the server are non-blocking (under most circumstances)

   + Requests which produce a reply from the server return a token or 
 receipt

Why not abstract this token or receipt into a function?

i.e. why not change...

   -- | List all of the extensions supported by the server
   listExtensions :: Connection - IO (Receipt (ListExtensionsReply))

   -- | Query a receipt for a response
   getReply :: Receipt a - IO (Either XError a)

to

listExtensions :: Connection - IO (IO ListExtensionsReply)

and then you don't need to use a getReply, or a Receipt data type.
This should be equally general, if (as I imagine) the only thing you
can do with a Receipt is to getReply it.  And to me it seems like a
friendly way of describing what this function does.

  Each X extension defines its own set of errors and events
  (potentially).  Should all of these be lumped together into one giant
  sum-type for errors and one for events?

Or maybe just a couple of existential types together with dynamic?
(i.e. like xmonad's SomeMessage)

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: A Monad for on-demand file generation?

2008-07-03 Thread David Roundy
On Thu, Jul 03, 2008 at 07:09:58PM +0100, ChrisK wrote:
 Joachim Breitner wrote:
  * The 5th line does not have this effect. Because this gets desugared
 to (), the special implementation of () means that the next line
 still sees the same dependency state as the before the call to liftIO.
 
 You are violating the monad laws.  (f  k) and (f = \_ - k)
 should do the same thing.  You might write a version of liftIO that
 has the effect you want, however.

I don't mind a little anarchy in the monad laws...  :)

  * A change to inFile3 causes outFile1 to be re-written, although from
 looking at the code, _we_ know that this is not necessary, but the ODIO
 monad can not tell. The programmer should have swapped the lines.
 
 Let me reverse engineer your algorithm (aside from the screwy ):
 
 Every readFile that is encountered in processing ODIO is added to a
 list of source files.  The reading deferred to be lazy with
 unsafePerformIO.
 
 When a writeFile is encountered it is assumed to depend on all
 previously read files.  If this output file already exists and is
 newer than all the source files, then writing it is skipped (and
 perhaps also the lazy reads are skipped).  Otherwise, the writing is
 strict.
 
 
 
 I would say this is an unusual module.  I rather prefer Makefile semantics,
 which could be improved in some ways by using a DSL in Haskell instead.
 
 The syntactic form of a file-oriented Makefile declaration is
 
 output : input1 input2
   shell script
   more shell script

I must say that I prefer the automatic computation of dependencies as
outlined by Joachim.  A bit more is needed, of course, to enable true
Makefile-like dependency handling, since you'd want to ensure that the
dependencies themselves are up-to-date, but the automatic computation
of dependencies would be a real boon.  Makefiles are extremely prone
to errors in which dependencies are left out, and those bugs are only
caught on rare occasions when the build is performed in an unusual
order, or when a rarely-touched source file is edited.

Of course, to create a make replacement, you'd also have to be able
to call external programs and track which files they use, which is a
hard problem, particularly as which files they use may depend on the
contents of the files that they use.  One could, however, lift calls
to well-behaved external programs (e.g. those like ghc or gcc that can
output their dependencies) into this sort of monad.

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] A Monad for on-demand file generation?

2008-07-01 Thread David Roundy
On Tue, Jul 01, 2008 at 10:22:35AM +, Joachim Breitner wrote:
 Hi,
 
 Am Dienstag, den 01.07.2008, 11:53 +0200 schrieb Ketil Malde:
  Joachim Breitner [EMAIL PROTECTED] writes:
  
   1) unsafeInterleaveIO seems like a big hammer to use for this problem,
   and there are a lot of gotchas involved that you may not have fully
   thought out.  But you do meet the main criteria (file being read is
   assumed to be constant for a single run of the program).
  
   Any other gotcha? 
  
  The one that springs to mind is that you might run out of file
  handles. At least on Linux, that's a precious resource.
 
 but at least then, (unsafeInterleaveIO readFile) is actually better than
 (readFile), because if I consume the files in sequence and complete,
 they will be opened and closed in sequence with the first one, but be
 opened all at once with the second. At least it won’t be worse, because
 the file will not be closed later, and possibly opened later.

Indeed, the best option (in my opinion) would be

unsafeInterleaveIO readFileStrict

(where you might need to write readFileStrict).  In darcs, we use lazy IO a
lot, but never lazily read a file, precisely due to the open file handle
issue.  This works pretty well, and your scenario is precisely the one in
which unsafeInterleaveIO shines.

David


signature.asc
Description: Digital signature
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] history of tuples vs pairs

2008-06-25 Thread David Roundy
On Wed, Jun 25, 2008 at 02:24:57PM -0400, Brent Yorgey wrote:
 On Wed, Jun 25, 2008 at 07:50:08PM +0200, Niels Aan de Brugh wrote:
  On Wed, 2008-06-25 at 16:50 +0200, Conal Elliott wrote:
   I have a foggy memory that early ML had only binary pairing, nesting
   for n-tuples.  Can anyone confirm this memory.  If so, does anyone
   remember the rationale for going to n-tuples?  Performance, perhaps?
  
  ???What is the difference between a list build up of Cons and a tuple
  made out of pairs? I think the latter wouldn't really add anything new.
 
 The difference is that all the elements of a list must be the same
 type, whereas nested tuples could have elements of any type.  For
 example,
 
   (True, (6, 'c')) :: (Bool, (Int, Char))
 
 and there is no corresponding three-element list.  However, you're
 right in noting the similarity between lists and nested tuples -- in
 fact, this is exactly how lists are implemented in lisp (which is
 where we get the tern 'cons').

The other difference is that nested tuples have the number of elements
specified in the type, while lists do not.
-- 
David Roundy
Department of Physics
Oregon State University
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: C buffer suggestions??

2008-06-23 Thread David Roundy
See the Data.ByteString.Internal docs:

http://www.haskell.org/ghc/docs/latest/html/libraries/bytestring/Data-ByteString-Internal.html#v%3AtoForeignPtr

Of course, you'd better not write to the contents of that pointer, or
bad things could happen...

David

On Mon, Jun 23, 2008 at 08:18:23PM -0500, Galchin, Vasili wrote:
 e.g. on Word8 .
 
  let aiocb = AIOCB{
aioFd=fd,
aioLioOpcode=0,
aioReqPrio=0,
aioOffset=0,
aioBuf=??,   Ptr Word8
aioBytes=128,
aioSigevent=event}
 
 ???
 
 Kind regards, Vasili
 
 On Mon, Jun 23, 2008 at 8:13 PM, Galchin, Vasili [EMAIL PROTECTED]
 wrote:
 
  ok .
 
  1) how do I marshall from ByteString to char * (poke)??
 
  2) how do I write
 
   let x =??? :: Word8
 
  3) how do I write
 
   let y = ??? ::ByteString
 
  Kind regards, Vasili
 
 
 
  On Mon, Jun 23, 2008 at 6:13 PM, Adam Langley [EMAIL PROTECTED]
  wrote:
 
  On Mon, Jun 23, 2008 at 2:27 PM, Don Stewart [EMAIL PROTECTED] wrote:
   So heap allocated and collected, but not moved.
 
  My bad. In that case, you might want to work with ByteStrings all the
  way since it might make building the visible interface (which probably
  should use ByteStrings) easier.
 
 
  AGL
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] blas bindings, why are they so much slower the C?

2008-06-18 Thread David Roundy
On Wed, Jun 18, 2008 at 09:16:24AM -0700, Anatoly Yakovenko wrote:
  #include cblas.h
  #include stdlib.h
 
  int main() {
int size = 1024;
int ii = 0;
double* v1 = malloc(sizeof(double) * (size));
double* v2 = malloc(sizeof(double) * (size));
for(ii = 0; ii  size*size; ++ii) {
   double _dd = cblas_ddot(0, v1, size, v2, size);
}
free(v1);
free(v2);
  }
 
  Your C compiler sees that you're not using the result of cblas_ddot,
  so it doesn't even bother to call it. That loop never gets run. All
  your program does at runtime is call malloc and free twice, which is
  very fast :-)
 
 C doesn't work like that :).  functions always get called.  but i did
 find a problem with my C code, i am incorrectly calling the dot
 production function:

See a recent article in lwn on pure and const functions to see how gcc
is able to perform dead code elimination and CSE, provided its given
annotations on the relevant functions.  I'd certainly hope that your
blas library is properly annotated!

 #include cblas.h
 #include stdlib.h
 #include stdio.h
 #include string.h
 
 int main() {
int size = 1024;
int ii = 0;
double dd = 0.0;
double* v1 = malloc(sizeof(double) * (size));
double* v2 = malloc(sizeof(double) * (size));
for(ii = 0; ii  size; ++ii) {
   v1[ii] = 0.1;
   v2[ii] = 0.1;
}
for(ii = 0; ii  size*size; ++ii) {
   dd += cblas_ddot(size, v1, 0, v2, 0);
}
free(v1);
free(v2);
printf(%f\n, dd);
return 0;
 }
 
 time ./testdot
 10737418.240187
 
 real0m2.200s
 user0m2.190s
 sys 0m0.010s
 
 So C is about twice as fast.  I can live with that.

I suspect that it is your initialization that is the difference.  For
one thing, you've initialized the arrays to different values, and in
your C code you've fused what are two separate loops in your Haskell
code.  So you've not only given the C compiler an easier loop to run
(since you're initializing the array to a constant rather than to a
sequence of numbers), but you've also manually optimized that
initialization.  In fact, this fusion could be precisely the factor of
two.  Why not see what happens in Haskell if you create just one
vector and dot it with itself? (of course, that'll also make the blas
call faster, so you'll need to be careful in your interpretation of
your results.)

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] blas bindings, why are they so much slower the C?

2008-06-18 Thread David Roundy
On Wed, Jun 18, 2008 at 06:03:42PM +0100, Jules Bean wrote:
 Anatoly Yakovenko wrote:
 #include cblas.h
 #include stdlib.h
 
 int main() {
   int size = 1024;
   int ii = 0;
   double* v1 = malloc(sizeof(double) * (size));
   double* v2 = malloc(sizeof(double) * (size));
   for(ii = 0; ii  size*size; ++ii) {
  double _dd = cblas_ddot(0, v1, size, v2, size);
   }
   free(v1);
   free(v2);
 }
 Your C compiler sees that you're not using the result of cblas_ddot,
 so it doesn't even bother to call it. That loop never gets run. All
 your program does at runtime is call malloc and free twice, which is
 very fast :-)
 
 C doesn't work like that :). 
 
 C compilers can do what they like ;)
 
 GCC in particular is pretty good at removing dead code, including entire 
 loops. However it shouldn't eliminate the call to cblas_ddot unless it 
 thinks cblas_ddot has no side effects at all, which would be surprising 
 unless it's inlined somehow.

Or unless it's been annotated as pure, which it should be.

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Design suggestion for Data.Binary.Defer

2008-06-17 Thread David Roundy
On Tue, Jun 17, 2008 at 07:55:51AM +0100, Neil Mitchell wrote:
 Hi,

Hello!

 David:
  Is there any reason not to just write all lazy fields of variable size
   in a deferred manner?
 
 I completely hadn't though of this! You will loose a bit of time, for
 example reading fields which were previously not deferred will require
 a file seek, but the effort/thought/efficiency trade-off is good. I
 think I will go with this.

Actually, you ought to be able to pretty easily remove this tradeoff
by introducing a strict read function as a new method in your class.
So anyone who wants to strictly read lazy data can use that function
instead of the lazy one.  The writing of data is unaffected... or
rather, it *is* affected, but only in the sense that writing deferred
data cannot be as lazy as the writing of undeferred data.  e.g. when
writing a deferred list, you can't output the first word until you've
already read through the entire list in order to find out how long it
is.  That could actually be quite a problem for code that relies on
laziness to handle massive amounts of data.  :( Lazy reading seems to
require strict writing, while lazy writing requires strict reading!

So perhaps you want a pair of read functions, one strict, one lazy,
and a pair of write functions.  That doesn't provide any sort of
fine-grained control, but at least allows streaming in either
direction.  You could use the same data format for either strictly or
lazily pickled data as long as you have a reserved value for the
length-to-be-skipped, so the lazy reader could tell if it reaches data
that whose length it doesn't know.

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Suggestion for implementation of vector library

2008-06-17 Thread David Roundy
On Tue, Jun 17, 2008 at 08:24:58AM -0700, John Meacham wrote:
 You can also create helper functions like
 
 v3 = Vector3
 
 so you can do (v3 1 2 3 + v3 4 5 6)

Or just use

data Vector3 = V3 !Float !Float !Float

and you've got compact pattern matching as well as constructing.

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: 答复 : [Haskell-cafe] How to do this in FP way?

2008-06-17 Thread David Roundy
On Tue, Jun 17, 2008 at 08:56:31AM -0700, Don Stewart wrote:
 dons:
  magicloud.magiclouds:
   OK. Here it is.
   I want to make a monitor tool for linux. It runs for a long time, and give
   out a certain process's io stat per second. The way I get io stat is to 
   read
   from /proc/pid/io. But the data in this file is a total, I need to read it
   first, then next second, read it again, and shows the difference, and go 
   on.
   So, what is your idea?
  
  Easy,
  
  import Control.Concurrent
  import Control.Monad
  
  main = go 0
  where
  go st = forever $ do
 n - read `fmap` readFile /proc/pid/io
 print (n - st) -- display difference
 threadDelay (10^6)
 
 Oops, not 'forever' :)
 
   go st = do
 ...
 go n


or

doEverySecond :: (a - IO a) - a - IO ()
doEverySecond job n = do n' - job n
 threadDelay (10^6)
 doEverySecond job n'

showChange :: Int - IO Int
showChange n = do n' - read `fmap` readFile /proc/pid/io
  print (n' - n) -- display difference
  return n'

main = doEverySecond showChange 0 -- note: prints bogus value first time

This demonstrates how you can abstract the ideas in Don's solution
just a bit, so that you could reuse these functions for somewhat
different purposes.  For such a simple function you'd probably be
better with Don's solution, but if your monitor tool is starting to
look more complicated than this, perhaps you're better off breaking
it into different functions.

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] How to do this in FP way?

2008-06-16 Thread David Roundy
2008/6/15 Magicloud Magiclouds [EMAIL PROTECTED]:
 Hello,
 I am getting familiar with FP now, and I have a program design kind of
 question.
 Say I have something like this in C:
 static int old;
 int diff (int now) { /* this would be called once a second */
   int ret = now - old;
   old = now;
   return ret;
 }
 Because there is no variable in Haskell. So how to do this in a FP
 way?

A better question would be to think about what you are trying to
accomplish, and then ask how to achieve that through functional
programming.

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Design suggestion for Data.Binary.Defer

2008-06-16 Thread David Roundy
On Mon, Jun 16, 2008 at 9:43 AM, Neil Mitchell [EMAIL PROTECTED] wrote:
 == The Question ==

 Is there a simple way of tagging fields in a constructor as deferred,
 just once for reading and writing, and ideally outside the instance
 definition and not requiring additional code to unwrap? I can't think
 of any, but there may be something I have missed.

Is there any reason not to just write all lazy fields of variable size
in a deferred manner? That would seem like the best option to me, but
maybe that's just because I don't see any downside besides the
requirement that one use some space to write the size.  But that seems
like it would almost always be a trivial issue, as any small data
element will have a fixed size (so that the deferred/non-deferred
distinction doesn't exist).

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] 1/0

2008-06-16 Thread David Roundy
On Mon, Jun 16, 2008 at 4:07 PM, Evan Laforge [EMAIL PROTECTED] wrote:
 So, I know this has been discussed before, but:

 1/0
 Infinity
 0/0
 NaN

 ... so I see from the archives that Infinity is mandated by ieee754
 even though my intuition says both should be NaN.

There is a good reason for 1/0 being infinity, as it allows correct
programs to give correct answers even in the presence of underflow and
overflow.

 Every other language throws an exception, even C will crash the
 program, so I'm guessing it's telling the processor / OS to turn these
 into signals, while GHC is turning that off.  Or something.  But then
 what about this note in Control.Exception:

That's just not true.  It depends on how your system (compiler?) is
configured, but the default on most systems that I've used is to
return NaNs.

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] 1/0

2008-06-16 Thread David Roundy
On Mon, Jun 16, 2008 at 4:18 PM, David Roundy [EMAIL PROTECTED] wrote:
 On Mon, Jun 16, 2008 at 4:07 PM, Evan Laforge [EMAIL PROTECTED] wrote:
 Every other language throws an exception, even C will crash the
 program, so I'm guessing it's telling the processor / OS to turn these
 into signals, while GHC is turning that off.  Or something.  But then
 what about this note in Control.Exception:

 That's just not true.  It depends on how your system (compiler?) is
 configured, but the default on most systems that I've used is to
 return NaNs.

Sorry, I just read my post, and realized I quoted too much.  I was
responding to the first sentence about other languages, thinking of
octave, C and C++.

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] 1/0

2008-06-16 Thread David Roundy
On Mon, Jun 16, 2008 at 04:50:05PM -0700, John Meacham wrote:
 On Mon, Jun 16, 2008 at 04:41:23PM -0700, Evan Laforge wrote:
  But what about that NaN-Integer conversion thing?
 
 I think that may be a bug or at least a misfeature. The standard is
 somewhat vauge on a lot of issues dealing with floating point since
 it is such a tricky subject and depends a lot on the environment. The
 various rounding funcitons are particularly ugly IMHO. I added varients
 of them that preserved the floating point type and properly implemented
 IEEE behavior for jhc.

I think the Data.Binary guys think it's a feature, since they rely in
this behavior (well, they rely on the equivalently-foolish behavior of
toRational).  I think it's a bug.

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] 1/0

2008-06-16 Thread David Roundy
On Mon, Jun 16, 2008 at 05:08:36PM -0700, Don Stewart wrote:
 droundy:
  On Mon, Jun 16, 2008 at 04:50:05PM -0700, John Meacham wrote:
   On Mon, Jun 16, 2008 at 04:41:23PM -0700, Evan Laforge wrote:
But what about that NaN-Integer conversion thing?
   
   I think that may be a bug or at least a misfeature. The standard is
   somewhat vauge on a lot of issues dealing with floating point since
   it is such a tricky subject and depends a lot on the environment. The
   various rounding funcitons are particularly ugly IMHO. I added varients
   of them that preserved the floating point type and properly implemented
   IEEE behavior for jhc.
  
  I think the Data.Binary guys think it's a feature, since they rely in
  this behavior (well, they rely on the equivalently-foolish behavior of
  toRational).  I think it's a bug.
 
 You mean:
 
 instance Binary Double where
 put d = put (decodeFloat d)
 get   = liftM2 encodeFloat get get
 
 ?
 
 if you've a portable Double decoding that works in GHC and Hugs, I'm
 accepting patches.

I really don't understand why being portable is such an issue.  Is it
really better to behave wrong on every platform rather than behaving
wrong on a very small minority of platforms?

Anyhow, I've not hacked on binary, because I've not used it, and have
trouble seeing when I would use it.  So maybe I shouldn't have brought
the subject up, except that this use of decodeFloat/encodeFloat is a
particularly egregious misuse of floating point numbers.  decodeFloat
really ought to be a partial function, and this should be a crashing
bug, if the standard libraries were better-written.

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] 1/0

2008-06-16 Thread David Roundy
On Mon, Jun 16, 2008 at 05:39:39PM -0700, Don Stewart wrote:
  decodeFloat really ought to be a partial function, and this should
  be a crashing bug, if the standard libraries were better-written.
 
 It's a bug in the H98 report then:
 
 Section 6.4.6:
 
 The function decodeFloat applied to a real floating-point number returns
 the significand expressed as an Integer and an appropriately scaled
 exponent (an Int). If decodeFloat x yields (m,n), then x is equal in value
 to mb^n, where b is the floating-point radix, and furthermore, either m
 and n are both zero or else b^d-1=mb^d, where d is the value of
 floatDigits x.  encodeFloat performs the inverse of this transformation.
 

Yes, it is a bug in the report, that it doesn't fully specify the
behavior this function when given a NaN or infinity.  There's also a
bug in the standard libraries, which is that they don't conform to the
report.

let x = 0/0
let (m,n) = decodeFloat x
Prelude (m,n)
(-6755399441055744,972)
Prelude let x = 0/0
Prelude x
NaN
Prelude let d = floatDigits x
Prelude let (m,n) = decodeFloat x
Prelude let x' = (fromInteger m :: Double)*2^n
Prelude x'
-Infinity
Prelude 2^d-1=m
False
Prelude m2^d
True

So for the ghc decodeFloat, when operating on a NaN, the
specifications of decodeFloat are almost completely unsatisfied.  On
the plus side, at least it's true that mb^d, so that's one out of
three.  I suppose the problem is that quickcheck was developed only
after the standard was written...

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] elem of infinite set of tuple

2008-05-16 Thread David Roundy
On Fri, May 16, 2008 at 04:42:31AM -0700, leledumbo wrote:
 
 I don't know how Haskell should behave on this. Consider this function:
 elemOf (x,y) = (x,y) `elem` [ (a,b) | a - [0..], b - [0..] ]
 
 If I try to query elemOf (1,1), the program keeps searching and searching
 but it never makes it. But if I query elemOf (0,1) (or anything as long as
 the first element is 0), it can find it easily. I wonder how it's handled.
 
 From my point of view, instead of starting from (1,0), the program starts
 from (0,0), which will never finish since the limit of the second element is
 infinite.

Didn't you just answer your own question?
-- 
David Roundy
Department of Physics
Oregon State University
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Fun with Darcs

2008-05-14 Thread David Roundy
On Wed, May 14, 2008 at 08:37:53PM +0100, Andrew Coppin wrote:
 Andrew Coppin wrote:
 Henning Thielemann wrote:
 
 As said, the IDE Leksah can display code exactly like this ...
 
 
 I noticed the first time. Clearly this is another toy I'm going to 
 have to try out sometime...
 
 ...and then he discovers that Darcs isn't working any more. :-(
 
 I've recently reinstalled Windows, so I decided to go download the 
 latest Darcs and set that up. Now it's complaining that I don't have 
 curl or wget. (Never used to do that before.) The WindowsConfiguration 
 file doesn't mention anything about it. [And the link back to the Darcs 
 wiki is 404 by the way. darcs.net rather than wiki.darcs.net. Nice 
 touch...] Presumably this change is new in Darcs 2. I don't recall 
 seeing anything about it when I read the announcement, and I'm now 
 searching the wiki and I still don't see anything about it.
 
 Presumably I just need to discover a Windows binary for wget and put it 
 in my search path somewhere? Would be nice if this were documented... 
 Darcs used to just work by itself without any additional tools.

It's just that the guy who built the windows binary didn't have libcurl
installed.  Since there don't seem to be many windows developers, we have
to live with those few people willing to compile darcs on windows...

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Interesting critique of Haskell

2008-05-09 Thread David Roundy
On Fri, May 09, 2008 at 11:35:32AM -0400, Brent Yorgey wrote:
 On Fri, May 9, 2008 at 10:02 AM, Andrew Coppin [EMAIL PROTECTED]
 wrote:
  While I'm here - I'm aware of how you control importing [or not] from the
  Prelude. Is there a way that I can, for example, import all the stuff like
  the basic types, classes, etc., but *not* all the list-related stuff? Or is
  the Prelude not that modular?
 
 Not only is the Prelude not that modular, there's not really any mechanism
 to make it so.  There's no way to partition an export list in such a way
 that whole chunks of it can be imported/not imported at a go.  Would that be
 a nice feature?  I don't know, possibly.

Ordinary functions are easily split off from the Prelude.  The only tricky
bit is classes and class instances, and that's a Hard Problem, as far as I
can tell.  And, of course, only is quite an understatement here.
-- 
David Roundy
Department of Physics
Oregon State University
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Interesting critique of Haskell

2008-05-09 Thread David Roundy
On Fri, May 09, 2008 at 05:19:05PM +0100, Andrew Coppin wrote:
 Brent Yorgey wrote:
 
 On Fri, May 9, 2008 at 10:02 AM, Andrew Coppin 
 [EMAIL PROTECTED] mailto:[EMAIL PROTECTED] wrote:
 
 While I'm here - I'm aware of how you control importing [or not]
 from the Prelude. Is there a way that I can, for example, import
 all the stuff like the basic types, classes, etc., but *not* all
 the list-related stuff? Or is the Prelude not that modular?
 
 
 Not only is the Prelude not that modular, there's not really any 
 mechanism to make it so.  There's no way to partition an export list 
 in such a way that whole chunks of it can be imported/not imported at 
 a go.  Would that be a nice feature?  I don't know, possibly.
 
 Well, if the Prelude was split into several seperate modules, you could 
 import just the modules you wanted. That sounds pretty easy to me. [I 
 mean, apart from the minor detail that no current implementation works 
 this way...]
 
 By default, if you don't ask for anything, your module automatically 
 imports Prelude. What if we made Prelude a module that just imports 
 and re-exports several other modules - Prelude.Types, Prelude.Classes, 
 Prelude.List (or rather, a subset of Data.List). Then if a module 
 imports Prelude, or anything under Prelude, it turns off the automatic 
 import, similar to the current system.
 
 Of course, I guess all this isn't likely to happen any time soon... I'm 
 just throwing ideas out there.

It's pretty easy (albeit tedious) to do this for yourself (except that you
wouldn't automatically turn off the import of Prelude, and you'd still
suffer from the instances disease).

module Prelude.Types ( Int, Double, Char, String ) where

import Prelude

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] MonadPlus

2008-05-09 Thread David Roundy
On Fri, May 09, 2008 at 08:39:38PM +0100, Andrew Coppin wrote:
 OK, so I feel I understand monads fine. I regularly use Maybe, [] and 
 IO, and I've even constructed a few monads of my own. But here's a 
 question: what is the purpose of the MonadPlus class?
 
 Clearly it defines a binary operation over monadic values and an 
 identity element for that operation. But... what is this supposed to 
 *do*? (For example, () has an almost identical signature to mplus. But 
 presumably they don't both do the same thing...) What functionallity is 
 this supposed to give you?

MonadPlus is a crude way of achieving the catching of exceptional cases,
and you should think of mplus as being equivalent to (catch . const).  The
trouble is that MonadPlus doesn't provide any mechanism for finding out
what went wrong, so I've only ever found it useful when using the Maybe
monad (which itself has no way of identifying what went wrong).

 [In a somewhat unrelated question... I saw some code the other day that 
 used Either as if it were a monad. And yet, I don't see an instance 
 given in the standard libraries - even though there should be one. I can 
 see Functor (Either a), but not Monad (Either a) or even Monad (Either 
 String)...]

I am pretty certain that there is a monad instance for Either, but also
don't know where it's defined.
-- 
David Roundy
Department of Physics
Oregon State University
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] GHC predictability

2008-05-09 Thread David Roundy
On Fri, May 09, 2008 at 02:24:12PM -0700, Don Stewart wrote:
 jeff.polakow:
  Hello,
  
  One frequent criticism of Haskell (and by extension GHC) is that it has
  unpredictable performance and memory consumption. I personally do not find
  this to be the case. I suspect that most programmer confusion is rooted in
  shaky knowledge of lazy evaluation; and I have been able to fix, with
  relative ease, the various performance problems I've run into. However I
  am not doing any sort of performance critical computing (I care about
  minutes or seconds, but not about milliseconds).
  
  I would like to know what others think about this. Is GHC predictable? Is
  a thorough knowledge of lazy evaluation good enough to write efficient
  (whatever that means to you) code? Or is intimate knowledge of GHC's
  innards necessary?
  
  thanks,
Jeff
  
  PS I am conflating Haskell and GHC because I use GHC (with its extensions)
  and it produces (to my knowledge) the fastest code.
 
 This has been my experience to. I'm not even sure where
 unpredicatiblity would even come in, other than though not
 understanding the demand patterns of the code.

I think the unpredictability comes in due to the difficulty of predicting
resource useage in the presence of lazy data (and particularly lazy IO).
It's not really that hard to predict the behavior of code that you write,
but it can certainly be hard to predict the effect of changes that you make
to someone else's code.  It's an effect of the possibility of constructing
and consuming large data objects without ever holding them in memory.  It's
beautiful, and it's wonderful, but it's also really easy for someone to add
a second consumer of the same object, and send performance through the
floor.

Of course, one can avoid this particular pattern, but then you lose some of
the very nice abstractions that laziness gives us.
-- 
David Roundy
Department of Physics
Oregon State University
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] runInteractiveProcess and hGetLine on Windows

2008-05-07 Thread David Roundy
On Wed, May 07, 2008 at 04:42:45PM +0200, Harri Kiiskinen wrote:
 Prelude System.Process System.IO (inp,outp,err,ph) -
   runInteractiveProcess kpsewhich [testfile.txt] Nothing
   Nothing
...
 Prelude System.Process System.IO hGetLine outp
 
 which gives me:
 
 ./testfile.txt\r
 
 as opposed to ./testfile.txt which I get on my Linux box.
 
 Is the \r supposed to be at the end? I thought it is part of the line
 separator in Windows, and as such, should not be part of the line
 retrieved? Same thing happens when compiled with ghc.

This is the correct behavior (although it's debatable whether kpsewhich
should be outputting in text mode).  In order to get windows-style line
handling, a file handle needs to be opened in text mode, which is certainly
not the correct behavior for runInteractiveProcess, which has no knowledge
about the particular behavior of the program it's running.

\r\n as newline should die a rapid death... windows is hard enough
without maintaining this sort of stupidity.
-- 
David Roundy
Department of Physics
Oregon State University
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] runInteractiveProcess and hGetLine on Windows

2008-05-07 Thread David Roundy
On Wed, May 07, 2008 at 08:33:23AM -0700, Bryan O'Sullivan wrote:
 David Roundy wrote:
  This is the correct behavior (although it's debatable whether kpsewhich
  should be outputting in text mode).
 
 I think it would be more accurate to say that runInteractiveProcess has
 an inadequate API, since you can't indicate whether the interaction with
 the other process should happen in text or binary mode.

I don't see any reason to support text mode.  It's easy to filter by hand
if you absolutely have to deal with ugly applications on ugly platforms.
-- 
David Roundy
Department of Physics
Oregon State University
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] runInteractiveProcess and hGetLine on Windows

2008-05-07 Thread David Roundy
On Wed, May 07, 2008 at 07:48:45PM +0400, Bulat Ziganshin wrote:
 Hello David,

Hi Bulat!

 Wednesday, May 7, 2008, 7:46:11 PM, you wrote:
  I don't see any reason to support text mode.  It's easy to filter by hand
  if you absolutely have to deal with ugly applications on ugly platforms.
 
 you mean unix, of course? ;)

Maybe I should have said if you don't care what the actual output of the
programs you run is? Then it would have been clear that I was talking
about Windows...

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] runInteractiveProcess and hGetLine on Windows

2008-05-07 Thread David Roundy
On Wed, May 7, 2008 at 9:12 AM, Donn Cave [EMAIL PROTECTED] wrote:
  Doesn't hGetLine imply text mode?  What does Line mean, otherwise?

On normal operating systems, line means until you reach a '\n'
character.  In fact, that's also what it means when reading in text
mode, it's just that when in text mode on DOS-descended systems, the
character sequence \r\n is converted to \n by the operating
system.

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] runInteractiveProcess and hGetLine on Windows

2008-05-07 Thread David Roundy
On Wed, May 07, 2008 at 09:24:46PM +0100, Duncan Coutts wrote:
 On Wed, 2008-05-07 at 08:46 -0700, David Roundy wrote:
  On Wed, May 07, 2008 at 08:33:23AM -0700, Bryan O'Sullivan wrote:
   David Roundy wrote:
This is the correct behavior (although it's debatable whether kpsewhich
should be outputting in text mode).
   
   I think it would be more accurate to say that runInteractiveProcess has
   an inadequate API, since you can't indicate whether the interaction with
   the other process should happen in text or binary mode.
  
  I don't see any reason to support text mode.  It's easy to filter by hand
  if you absolutely have to deal with ugly applications on ugly platforms.
 
 If it was only Windows' silly line ending convention I'd be tempted to
 agree but we probably want to distinguish text and binary handles
 anyway. You get Chars out of a text handle (with some string
 ed/decoding) and bytes out of a binary handle. In that case, default
 line ending convention is just another thing to throw in with the text
 encoding conversion.

But that's a feature that was only added in a very recent ghc, right?  I
consider it an ugly hack to work around the fact that we have no system for
dealing with file encodings.  I'd rather consider text mode handles to be
an ugly workaround for an ugly system, and have a clean solution for
unicode (e.g. one that allows for the reading of files that are not in the
locale encoding).  I certainly wouldn't want to be forced to live with DOS
line endings just to generate unicode output.  Fortunately, darcs doesn't
do unicode (or need to) or text mode, so I personally am pretty safe from
this feature.

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] approximating pi

2008-04-28 Thread David Roundy
On Mon, Apr 28, 2008 at 09:47:44AM +0200, [EMAIL PROTECTED] wrote:
 Benjamin L. Russell: 
 
 Assuming the square had 100 pixels per side, on the average, approximately 
 how many random pixels should be plotted in the square before obtaining a 
 reasonably good estimate of pi?
 
 Nothing to do with Haskell... 
 
 What do you mean by reasonable? This Monte-Carlo procedure is very
 inefficient anyway. The relative error falls as 1/sqrt(N) where N is the
 number of samples, so, several hundred thousands of samples may give you
 just three significant digits.
 And, at any rate, this has nothing to do with pixels, what, introduce
 one more source of errors through the truncation of real randoms? 

Indeed, Monte-Carlo is generally very inefficient, but it does have the
advantage of often allowing one to write very simple code that is thus
easily shown to be correct, and (as long as the random number generator is
good!!!) to get rigorously-correct error bars, which is something that more
efficient methods often struggle on.  For simple tasks like computing pi or
integrating smooth functions, this doesn't matter much, but it's quite a
big deal when considering methods such as Quantum Monte Carlo (although,
alas the fermion problem means that for most QMC calculations one *doesn't*
get a rigorous error bar on the calculation... it's just better than almost
any other method, and for bosons you *can* get a rigorous error bar).
-- 
David Roundy
Department of Physics
Oregon State University
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Laziness and Either

2008-04-23 Thread David Roundy
On Wed, Apr 23, 2008 at 01:12:16PM +0200, apfelmus wrote:
 I think that using  [Maybe a]  for this purpose is too fine-grained, I 
 would use a custom list type
 
   data River a = a : (River a) | Done | Error
 
 (I didn't want to call it  Stream  because that name is too overloaded 
 already and  PartialList  is too long :) The three constructors 
 correspond to the three cases you mention. In particular, Error takes 
 the role of the last  Nothing .

That sounds like a good idea.  But I'd call it Creek, because a river is
present year-round, while a creek sometimes dries up in the summer.  :) And
I'd also vote for adding a String (or more generic parameter) to the Error
type, so you can give some sort of reporting when something goes wrong.
String is appealing, because then you could make Creek a monad, and fail
could generate a nice Error message (assuming fail = Error).

Of course, you could take the silly metaphor even further

data Creek a = a : (Creek a) | Ocean | Drought String

:)
-- 
David Roundy
Department of Physics
Oregon State University
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: [Haskell] Matrix multiplication

2008-04-23 Thread David Roundy
On Wed, Apr 23, 2008 at 05:24:20PM +0100, Sebastian Sylvan wrote:
 On Wed, Apr 23, 2008 at 5:01 PM, Tillmann Vogt [EMAIL PROTECTED]
 wrote:
 
  Hi,
 
  I am currently experimenting with parallelizing C-programs. I have
  therefore written a matrix vector multiplication example that needs 13
  seconds to run (5 seconds with OpenMP). Because I like Haskell I did the
  same in this language, but it takes about 134 seconds. Why is it so slow?
  Does someone have an idea?
 
 Yes, in the C version you use unboxed arrays, in the Haskell version you use
 a linked list of linked lists. Naturally the latter will take up more space,
 require more work to index, and will thrash the cache quite a bit.

In fact, I'm impressed that Haskell can come within a factor of 10, given
that it's using such a challenging data type! (I wonder if this may be due
to inefficiencies in the C code, although I haven't looked at it.)
-- 
David Roundy
Department of Physics
Oregon State University
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: [darcs-devel] announcing franchise 0.0

2008-04-23 Thread David Roundy
On Wed, Apr 23, 2008 at 06:43:42PM +0200, Marc Weber wrote:
 On Fri, Apr 18, 2008 at 08:37:06AM -0700, David Roundy wrote:
  I'm pleased to announce the existence (not release, properly) of
  franchise, a new configuration/build system for Haskell programs and
  packages.
 
 Hi David!
 I like this idea.. ( I had it myself in another context : Generating nix
 expressions and figuring out dependencies automatically..)
 
 Is Franchise only meant to compile executables?
 Or is there some support for libraries as well?
 You need to feed in at least a list of exposed modules I guess

It does libraries also.  It has to, since franchise itself is a library.
Yes, you feed the list of exposed modules.  You can look at franchise's
Setup.hs for an example.  It only exposes one module, but you can see that
that module is given as a list.
-- 
David Roundy
Department of Physics
Oregon State University
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Stronger STM primitives needed? Or am I just doing it wrong?

2008-04-23 Thread David Roundy
On Wed, Apr 23, 2008 at 12:12:15PM -0700, Ryan Ingram wrote:
 On 4/23/08, Jan-Willem Maessen [EMAIL PROTECTED] wrote:
  I've been trying to decide whether either of these is implementable in terms
  of `orElse`, in such a way that we immediately check the predicate upon
  retry before doing anything else.   I can't quite make up my mind whether
  this is possible or not.
 
 I do not think it is possible; consider this case:
 
 broken = atomically $ do
v - expensive_computation :: STM (TVar Int)
retryUntil v ( 50)
 
 Given that you don't know which tvar to use until the end of the
 expensive computation, I don't see how you can lift orElse to the
 make that tvar be the first thing checked when the transaction is
 rerun.

I'm confused as to how your retryUntil gains you anything.  If any of the
TVars used in the expensive_computation change while waiting for a retry,
then the expensive_computation will need to be done again.  If none of them
change, then we can skip the expensive_computation.  How does retryUntil
help us with this?

i.e. how does your broken function using retryUntil differ from the
following?

broken = atomically $ do
 v - expensive_computation :: STM (TVar Int)
 vv - readTVar v
 unless (vv  50) retry
-- 
David Roundy
Department of Physics
Oregon State University
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Cabalizing darcs

2008-04-23 Thread David Roundy
On Wed, Apr 23, 2008 at 02:55:49PM -0400, Gwern Branwen wrote:
 So recently I spent a bit of time working on a cabalization of Darcs. It
 works well for me, and is reasonably easy to apply (attached are three
 files; do a 'darcs get --lazy http://darcs.net' with Darcs-2 to get the
 latest, and copy the files into it, the usual autoconf, and it should
 then work as normal; if this doesn't work for you, I'd appreciate
 knowing).

It certainly doesn't work for me.
-- 
David Roundy
Department of Physics
Oregon State University


signature.asc
Description: Digital signature
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Stronger STM primitives needed? Or am I just doing it wrong?

2008-04-23 Thread David Roundy
On Wed, Apr 23, 2008 at 01:46:53PM -0700, Ryan Ingram wrote:
 On 4/23/08, David Roundy [EMAIL PROTECTED] wrote:
  I'm confused as to how your retryUntil gains you anything.  If any of the
  TVars used in the expensive_computation change while waiting for a retry,
  then the expensive_computation will need to be done again.  If none of them
  change, then we can skip the expensive_computation.
 
 Does the STM runtime do this?
 
  i.e. how does your broken function using retryUntil differ from the
  following?
 
  broken = atomically $ do
  v - expensive_computation :: STM (TVar Int)
  vv - readTVar v
  unless (vv  50) retry
 
 If the STM runtime does the optimization you suggest, it's not
 different at all.

I doubt it does this, but my point is that you aren't suggesting a new
primitive, you're suggesting an improved runtime.  Once you've got your
improved runtime, this optimization is trivial, as far as I can tell.  And
without an improved runtime, your function is equivalent to this one.

 But consider this computation:
 
  -- non-primitive retryUntil:
  retryUntil v p = do
 x - readVar v
 unless (p x) retry
 
  broken2 = atomically $ do
 (v1, v2) - expensive_computation :: STM (TVar Int, TVar Int)
 retryUntil v1 ( 50)
 x - expensive_computation2 :: STM Int
 retryUntil v2 ( x)
 
 If v1 succeeds and v2 fails, then v1 changes to some other value  50,
 I am sure that the STM runtime as it stands now will re-run
 expensive_computation2.

I suppose it depends on how you rewrite the runtime.  Rather than your very
limited retryUntil + caching of results computed in the STM, why not make
this caching explicit, and allow users to write their own more complicated
variants of retryUntil? e.g.

retryUntil2 :: TVar a - TVar b - (a - b - Bool) - IO ()

A simple primitive to do this (in combination with a totally rewritten STM
runtime) would be

subatomically :: ReadOnlySTM a - STM ()

which would run a STM computation that is guaranteed to have no
side-effects (i.e. can't write to TVars) and ignore its results (and let
the runtime know that the results have been ignored).  Then your
extra-fancy retryUntil could simply be.

retryUntil v p = subatomically $
 do x - readVarRO v
unless (p x) retryRO

The only thing that is special about your retryUntil is that it does not
allow the modification of TVars.

On the other hand, I suspect the whole issue is silly.  Is it ever actually
wise to do an expensive calculation in the STM monad? That seems like it's
guaranteed to be a performance nightmare.
-- 
David Roundy
Department of Physics
Oregon State University
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: [Haskell] How to define tail function for Even/Odd GADT lists?

2008-04-23 Thread David Roundy
2008/4/23 Martijn Schrage [EMAIL PROTECTED]:
  It depends a bit on what you want to use these lists for, but the following
 encoding works for your examples and doesn't need the type class.

 data E
  data O

  type Even = (E,O)
  type Odd  = (O,E)

That's a nice little trick!  I like how you achieve type signatures
relating two distinct types just by sticking them in a tuple.  :)

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: [Haskell] How to define tail function for Even/Odd GADT lists?

2008-04-23 Thread David Roundy
I presume the point was to allow the writing of functions that accept
either list type, such as

sort :: List a evenorodd - List a evenorodd

or similar.

David

On Wed, Apr 23, 2008 at 7:55 PM, Iavor DiIatchki
[EMAIL PROTECTED] wrote:
 Hello,
  I am not sure of the use case here but you could also do the following:

  data EvenList a = Nil
 | ConsE a (OddList a)

  data OddList a  = ConsO a (EvenList a)

  This does not use any type system extensions.

  -Iavor



  On Wed, Apr 23, 2008 at 4:46 PM, David Roundy [EMAIL PROTECTED] wrote:
   2008/4/23 Martijn Schrage [EMAIL PROTECTED]:
  
 It depends a bit on what you want to use these lists for, but the 
 following
 encoding works for your examples and doesn't need the type class.

 data E
  data O

  type Even = (E,O)
  type Odd  = (O,E)
  
That's a nice little trick!  I like how you achieve type signatures
relating two distinct types just by sticking them in a tuple.  :)
  
David
___
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


Re: [Haskell-cafe] Glome.hs-0.3 and other things

2008-04-21 Thread David Roundy
On Mon, Apr 21, 2008 at 11:54 AM, Andrew Coppin
[EMAIL PROTECTED] wrote:
  I suppose the idea is that Haskell is supposed to help you work at a higher
 level of abstraction, so you can concentrate on building better *algorithms*
 which require less work in the first place. Surely using an algorithm in a
 suitably superior complexity class could more than make up for the
 performance loss from lack of cache coherence. But people who work in C and
 C++ know how to build efficient algorithms too, so... hmm, we seem to be in
 trouble here.

I don't think things are so glum.  There are certainly things we can
do to control where data is located (e.g. using unboxed arrays and
keeping track of strictness, and strict data types combined with
-funboxstrictidontrecalltheexactpragma).  In truth, C++ programs also
tend to have severe issues with memory use.  Garbage collection is
horrible on the cache, but it's also done relatively infrequently (at
least, full GCs are).

Writing seriously fast Haskell code is indeed challenging, but it's a
fun challenge.  And writing bug-free code is also a fun challenge, and
one at which we have a huge advantage over most other languages.  And
in Haskell we less are forced to choose between a horribly ugly
implementation and a horribly inefficient implementation.

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] announcing franchise 0.0

2008-04-18 Thread David Roundy
I'm pleased to announce the existence (not release, properly) of
franchise, a new configuration/build system for Haskell programs and
packages.

Franchise
=

Franchise is a configuration and build system for Haskell projects.  The
configure system employed in franchise is designed to be easily forward and
backward compatible, meaning that you shouldn't need to change your
Setup.hs file in order to compile with a new version of ghc, and if you
*do* need to make a change in your Setup.hs file, it shouldn't force users
who have an older version of franchise and/or ghc to upgrade either their
compiler or their copy of franchise.  The latter goal is really only going
to be realized if and when a stable version of franchise is released... as
it is currently is something of a pre-alpha state (but useable, for
instance, for compiling darcs).

One goal of franchise is to not require developers to provide redundant
information.  For instance, you've already listed all the modules you use,
and ghc already knows which modules are present in which packages, so
there's in general no need for you to list the packages that you require,
much less their versions.  This enhances both forwards and backwards
compatibility, and just plain makes your life easier.  If a particular
module is provided by more than one package, you may need to disambiguate,
but that's not the common case.

Perhaps also worth mentioning is that franchise supports parallel builds
similar to make -j.  Currently the number of simultaneous builds is fixed
at four.  Franchise does not, however, compute an optimized parallel build
order, with the result that on the darcs repository a franchise build is a
few percent slower than make -j4.

Franchise is currently ghc-specific and won't run on Windows, but patches
to extend either of these limitations would be welcome.  It also currently
won't work when any flags contain space characters (e.g. with
--prefix=/home/user/My stuff), but the fix for lack of space support is
the same as the fix for Windows support, so far as I can tell.

The package name franchise stands for Fun, relaxing and calming Haskell
into Saturday evening.  It is also something of an antonym of cabal,
since franchise means the right to vote.  Which also fits in with the
concept of allowing the code to decide on its own dependencies.  Franchise
is made up of some pretty ugly code, with a small amount of pretty
beautiful code.  But it was all code that was fun and relaxing to write.

It you want to have argumentative, stressful conversations, please don't do
so on the subject of fun, relaxing and calming code.

Note: franchise is almost entirely undocumented.  It does only export a
couple of dozen functions, but still might be hard to learn to use.  This
is because writing documentation is not as fun, relaxing or calming as
writing Haskell.  Also, franchise is not yet at the stage where it's likely
to be useful to you without any features added, unless you've got a very
simple project, in which case you should be able to pretty easily copy and
modify an existing franchise Setup.hs file.

To get franchise, run

darcs get http://darcs.net/repos/franchise

(note that this will require darcs 2.0.0)

To build and install franchise, simply execute

runghc Setup.hs install --user --prefix=$HOME

if you don't want to actually install it, just run

runghc Setup.hs build

I think that's all (and obviously, in no particular order).  I hope you
enjoy franchise, or if you don't enjoy franchise, I hope you don't tell me
about it.

David Roundy

P.S. A franchise build file for darcs is included below.  This is a
work-in-progress.  It doesn't build the documentation, doesn't allow the
user to configure on the command-line which packages they want to use
(e.g. bytestring/curl/libwww) and doesn't build the Workaround.hs module
which codes replacements for missing or broken library functions.  But it
*is* able to build darcs, and if these features are added, it will be able
to replace darcs' configure and build system without loss of features or
compatibility.

#!/usr/bin/runhaskell
import Distribution.Franchise

configure = do findPackagesFor src/darcs.lhs
   addEnv GHC_FLAGS -DPACKAGE_VERSION=\2.0.0\
   addEnv GHC_FLAGS -O2 -Wall -Werror
   addEnv CFLAGS -DPACKAGE_VERSION=\2.0.0\
   -- look for libz
   checkLib z zlib.h gzopen(\temp\,\w\)
   -- look for libwww
   do systemOut libwww-config [--cflags] = addEnv CFLAGS
  systemOut libwww-config [--libs] = addEnv LDFLAGS
  addEnv GHC_FLAGS -DHAVE_LIBWWW
  putStrLn Found libwww
 `catch` \_ - putStrLn Libwww isn't present!
   -- look for libcurl
   do systemOut curl-config [--cflags] = addEnv GHC_FLAGS
  systemOut curl-config [--cflags] = addEnv CFLAGS
  systemOut curl-config [--libs] = addEnv LDFLAGS

Re: [Haskell-cafe] announce: Glome.hs-0.3 (Haskell raytracer)

2008-04-18 Thread David Roundy
On Sat, Apr 19, 2008 at 12:19:19AM +0400, Bulat Ziganshin wrote:
 Saturday, April 19, 2008, 12:10:23 AM, you wrote:
  The other problem I had with concurrency is that I was getting about a
  50% speedup instead of the 99% or so that I'd expect on two cores.  I 
 
 2 cores doesn't guarantee 2x speedup. some programs are limited by
 memory access speed and you still have just one memory :)

In fact, this is relatively easily tested (albeit crudely):  just run two
copies of your single-threaded program at the same time.  If they take
longer than when run one at a time, you can guess that you're
memory-limited, and you won't get such good performance from threading your
code.  But this is only a crude hint, since memory performance is strongly
dependent on cache behavior, and running one threaded job may either do
better or worse than two single-threaded jobs.  If you've got two separate CPUs
with two separate caches, the simultaneous single-threaded jobs should beat the
threaded job (meaning take less than twice as long), since each job should
have full access to one cache.  If you've got two cores sharing a single
cache, the behavior may be the opposite:  the threaded job uses less total
memory than the two single-threaded jobs, so more of the data may stay in
cache.

For reference, on a friend's dual quad-core Intel system (i.e. 8 cores
total), if he runs 8 simultaneous (identical) memory-intensive job he only
gets about five times the throughput of a job, meaning that each core is
running at something like 60% of it's CPU capacity due to memory
contention.  It's possible that your system is comparably limited, although
I'd be suprised, somehow it seems unlikely that your ray tracer is
stressing the cache all that much.
-- 
David Roundy
Department of Physics
Oregon State University
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] announce: Glome.hs-0.3 (Haskell raytracer)

2008-04-18 Thread David Roundy
On Fri, Apr 18, 2008 at 02:09:28PM -0700, Jim Snow wrote:
 On a particular scene with one instance of the single-threaded renderer
 running, it takes about 19 seconds to render an image.  With two
 instances running, they each take about 23 seconds.  This is on an
 Athlon-64 3800+ dual core, with 512kB of L2 cache per core.  So, it
 seems my memory really is slowing things down noticeably.

This doesn't mean there's no hope, it just means that you'll need to be
extra-clever if you're to get a speedup that is close to optimal.  The key
to overcoming memory bandwidth issues is to think about cache use and
figure out how to improve it.  For instance, O(N^3) matrix multiplication
can be done in close to O(N^2) time provided it's memory-limited, by
blocking memory accesses so that you access less memory at once.

In the case of ray-tracing I've little idea where or how you could improve
memory access patterns, but this is what you should be thinking about (if
you want to optimize this code).  Of course, improving overall scaling is
best (e.g. avoiding using lists if you need random access).  Next I'd ask
if there are more efficent or compact data structures that you could be
using.  If your program uses less memory, a greater fraction of that memory
will fit into cache.  Switching to stricter data structures and turning on
-funbox-strict-fields (or whatever it's called) may help localize your
memory access.  Even better if you could manage to use unboxed arrays, so
that your memory accesses really would be localized (assuming that you
actually do have localize memory-access patterns).

Of course, also ask yourself how much memory your program is using in
total.  If it's not much more than 512kB, for instance, we may have
misdiagnosed your problem.
-- 
David Roundy
Department of Physics
Oregon State University
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Shouldn't this loop indefinitely = take (last [0..]) [0..]

2008-04-07 Thread David Roundy
On Sun, Apr 06, 2008 at 07:12:24AM -0700, John Meacham wrote:
 On Fri, Apr 04, 2008 at 04:46:22PM +0100, Neil Mitchell wrote:
  Where length xs = 1 and ys = 1000. This takes 1000 steps to tell the
  Int's aren't equal, since we don't have proper lazy naturals. If we
  did, it would take 2 steps.
  
  Read this: http://citeseer.ist.psu.edu/45669.html - it argues the
  point I am trying to make, but much better.
 
 I implemented this efficient lazy natural class once upon a time. it
 even has things like lazy multiplication:

I wonder about the efficiency of this implementation.  It seems that for
most uses the result is that the size of a Nat n is O(n), which means that
in practice you probably can't use it for large numbers.

e.g. it seems like

last [1..n :: Nat]

should use O(n) space, where

last [1..n :: Integer]

should take O(1) space.  And I can't help but imagine that there must be
scenarios where the memory use goes from O(N) to O(N^2), which seems pretty
drastic.  I imagine this is an inherent cost in the use of lazy numbers?
Which is probably why they're not a reasonable default, since poor space
use is often far more devastating then simple inefficiency.  And of course
it is also not always more efficient than strict numbers.
-- 
David Roundy
Department of Physics
Oregon State University
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Shouldn't this loop indefinitely = take (last [0..]) [0..]

2008-04-07 Thread David Roundy
On Mon, Apr 07, 2008 at 04:52:51AM -0700, John Meacham wrote:
 On Mon, Apr 07, 2008 at 04:45:31AM -0700, David Roundy wrote:
  I wonder about the efficiency of this implementation.  It seems that for
  most uses the result is that the size of a Nat n is O(n), which means that
  in practice you probably can't use it for large numbers.
  
  e.g. it seems like
  
  last [1..n :: Nat]
  
  should use O(n) space, where
  
  last [1..n :: Integer]
  
  should take O(1) space.  And I can't help but imagine that there must be
  scenarios where the memory use goes from O(N) to O(N^2), which seems pretty
  drastic.  I imagine this is an inherent cost in the use of lazy numbers?
  Which is probably why they're not a reasonable default, since poor space
  use is often far more devastating then simple inefficiency.  And of course
  it is also not always more efficient than strict numbers.
 
 Oh, yes. I certainly wouldn't recommend them as some sort of default,
 they were sort of a fun project and might come in handy some day.
 
 By efficient, I meant more efficient than the standard lazy number
 formulation of
 
 data Num = Succ Num | Zero 
 
 not more efficient than strict types, which it very much is not. :)

Ah, that makes sense.  And yes, they're definitely more efficient than
that.  :) The trouble (I suppose) is that for the common case in which lazy
naturals are called for, which is situations where you compute
(1+1+1+1...+1+0), you can't be more space-efficient than the standard lazy
numbers without losing some of the laziness.  Or at least, I can't see how
you could do so.
-- 
David Roundy
Department of Physics
Oregon State University
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] announcing the darcs 2.0.0 release

2008-04-07 Thread David Roundy
Hello darcs users,

I am pleased to announce the release of darcs 2.0.0! It's been a long time
coming, and hopefully you will be pleased with the result.  Notable new
features include (in no particular order):

 * New ssh-connnection mode that dramatically improves connection times
   when darcs 2.0.0 is present on the server as well as the client.

 * New hashed format that improves darcs' robustness with regard to
   network or filesystem errors, and also allows for efficient (and safe)
   caching of patch data, greatly improving access times to a repository
   that you have had previous contact with--which is the common case of
   pulling, pushing or sending.  This format allows patches to move back
   and forth with darcs1-format repositories, and is the recommended format
   (with an old-format mirror) if you do not wish to require darcs 2.0.0,
   but want to benefit from most of its improvements.

 * New darcs-2 format, which features improved conflict handling, and
   also has all the benefits of the hashed format.  Because this format
   features new and different semantics, it is not possible to interact
   with darcs 1.x, and care must be taken in switching to this format.  It
   is the recommended format for new projects (although we haven't made it
   the default).

 * The --partial get is now replaced with a --lazy get when using hashed
   formats, and in fact if you forget to provide one of these flags on the
   command line, you can acheive a lazy get simply by hitting control-C
   after darcs prints a message suggesting you do this.  Lazy repositories
   are identical to full repositories so long as you have a working network
   connection and the original repository is accessible, with patches
   downloaded as they are needed.  When the original repository is no
   longer accessible, a lazy repository will behave like the old --partial
   repositories.

 * We have added support for pipelined http downloading via either libwww or
   a very recent version of libcurl.  Neither of these is yet the default,
   but it is recommended that you try one of them if possible, as they
   greatly improve download times.

 * There is now a configurable global cache, which can help reduce network
   traffic if you have multiple local copies of the same--or
   similar--remote repositories.

 * I'm sure there are other new features, but this is all that comes to
   mind at the moment.


BUGS

There are numerous issues with the --darcs-2 repository semantics (see a
discussion at http://wiki.darcs.net/DarcsWiki/DarcsTwo).  In general, I
believe the status is that anything you could do with darcs 1.x you can do
with the darcs-2 semantics, but the high-level code hasn't been updated to
take into account the new possibilities opened up by the new semantics.  In
particular, patch dependencies are much more complex.  Alas, there has not
been enough time (or sufficient contributors) to make the code take these
complexities into account, and if you're clever you can reveal bugs.  You
have been warned.

Darcs 2.0.0 contains some performance regressions when running with large
repositories.  It is possible that these regressions will be sufficient to
prevent its effective use in some projects.  If this describes your
project--and the only way to know is to try it--then I recommend
considering either switching to a different revision control system, or
helping us to improve darcs.  The former is certainly the easier path.  If
I knew how to easily make darcs dramatically faster, I would have done so.

FUTURE DIRECTIONS FOR DARCS

The existing model for darcs maintenance has been the use of two branches,
a darcs-stable branch for well-tested changes, and a darcs-unstable branch
for more experimental work.  Each branch has a separate maintainer, so most
patches will be reviewed by two maintainers before making it into a darcs
release.  This is quite a nice system.

Unfortunately, it is also a rather labor-intensive process, and due to a
lack of contributors, we've moving to a more streamlined process.  Starting
with the darcs 2.0.0 release, there will be just one central branch of
darcs and only one maintainer: for now this is me, David Roundy.  Moreover,
I will be attempting to act as a much lower-profile maintainer than we've
had previously.  I will not be reading bug reports, reading the darcs-users
email list or even the darcs-devel mailing list.  I will only be reviewing
patches that are contributed.  I will not write up long user-friendly
release announcements like this for future darcs releases.  I will only be
reviewing and applying contributed patches.

What does this mean?

It means that if darcs is to continue to improve, we need new
contributors.  If bug reports are to be read, responded to and bugs are to
be fixed, we need new contributors.  If darcs is to be made more efficient,
we need new contributors.

The new URL for the darcs repository is simply http://darcs.net.

(Yes, this is a lame ending

Re: [Haskell-cafe] announcing the darcs 2.0.0 release

2008-04-07 Thread David Roundy
On Mon, Apr 07, 2008 at 10:28:12PM +0400, Bulat Ziganshin wrote:
 Monday, April 7, 2008, 9:22:25 PM, you wrote:
   * I'm sure there are other new features, but this is all that comes to
 mind at the moment.
 
 there was some issues with efficiency of darcs 1.x. am i correctly
 understood that these issues was not addressed by new release?

Some efficiency issues have dramatically improved.  Others have gotten
worse.  I don't know how better to summarize the situation than that.

 its hard to understand why darcs 2.0 is better than 1.x from your
 announcement. afair from gsoc project your primary goal was to improve
 patches flexibility?

Yes, it's much better at dealing with conflicts, if you use the darcs-2
format.  And it's less buggy than 1.0.9 is, which directly relates to one
slowdown that I'm aware of.  Try it and you can see whether you like it
more.  There's also the factor that darcs 1.0.x isn't going to see another
release.  If you don't want to switch to eventually darcs 2.0, then I would
strongly recommend that you switch to some other revision constrol system.
-- 
David Roundy
Department of Physics
Oregon State University
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Shouldn't this loop indefinitely = take (last [0..]) [0..]

2008-04-04 Thread David Roundy
On Fri, Apr 04, 2008 at 12:34:54PM +0100, Neil Mitchell wrote:
   length, take, drop and index working on machine-sized Ints by default
   are really a bit of a wart, aren't they?
 
 Yes. Also, having strict Int's by default is a bit ugly, in an
 otherwise lazy-by-default language. It's a place where Haskell decided
 to remove mathematical elegance for pragmatic speed...
 
 (Not that it isn't a worthwhile trade off, but it is still loosing
 something to gain something else)

Personally, I like Ints.
-- 
David Roundy
Department of Physics
Oregon State University
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Role based access control via monads or arrows or... something

2008-04-03 Thread David Roundy
On Thu, Apr 03, 2008 at 12:45:49AM +, Luke Palmer wrote:
 2008/4/2 porrifolius [EMAIL PROTECTED]:
(7) ideally required permissions would appear (and accumulate) in
   type signatures via inference so application code knows which are
   required and type checker can reject static/dynamic role constraint
   violations
 
 If you mean what I think you mean by dynamic, that these are runtime
 permissions, then you're not going to get the type checker to check
 them... of course.  What did you mean by dynamic?

With GADTs you can certainly get pretty easy compile-time type checking of
dynamic constraints.  The catch is that GADTs aren't properly integrated
with type classes, and this sort of permissions problem may not be
expressible without class constraints, in which case the system may require
olegish code complexity.

At the simplest (and stupidest) level, one could define

data CanReadA
data CanReadB
-- etc

data HavePermission perms where
   HaveAPerm :: HavePermission CanReadA
   HaveBPerm :: HavePermission CanReadB

and if you then restricted access to the constructors of HavePermission,
you could write code like

data RestrictedData permrequired a = Data a
-- constructor obviously not exported, or you'd lose any safety

readRestrictedData :: HavePermission perm - RestrictedData perm a - a

and now if you export readRestrictedData only, then only folks with the
proper permissions could access the data (and this could be done at
runtime).

But this is far from an elegant or satisfactory (or complete) solution.
-- 
David Roundy
Department of Physics
Oregon State University
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Role based access control via monads or arrows or... something

2008-04-03 Thread David Roundy
On Thu, Apr 03, 2008 at 05:31:16PM +0200, apfelmus wrote:
 David Roundy wrote:
 Luke Palmer wrote:
 porrifolius wrote:
   (7) ideally required permissions would appear (and accumulate) in
  type signatures via inference so application code knows which are
  required and type checker can reject static/dynamic role constraint
  violations
 
 If you mean what I think you mean by dynamic, that these are runtime
 permissions, then you're not going to get the type checker to check
 them... of course.  What did you mean by dynamic?
 
 
 At the simplest (and stupidest) level, one could define
 
 data CanReadA
 data CanReadB
 -- etc
 
 data HavePermission perms where
HaveAPerm :: HavePermission CanReadA
HaveBPerm :: HavePermission CanReadB
 
 and if you then restricted access to the constructors of HavePermission,
 you could write code like
 
 data RestrictedData permrequired a = Data a
 -- constructor obviously not exported, or you'd lose any safety
 
 readRestrictedData :: HavePermission perm - RestrictedData perm a - a
 
 and now if you export readRestrictedData only, then only folks with the
 proper permissions could access the data (and this could be done at
 runtime).
 
 At runtime, are you sure? I mean, if I want to use it like in
 
   foo = ... readRestrictedData permission secret ...
 
 I must know that the type of my  permission  matches the the type of 
 secret , either by knowing them in advance or by propagating this as 
 type variable into the type of foo. In any case, I may only write  foo 
 if I know statically that  permission  is going to match the  secret . 
 No runtime involved?

 In other words, I fail to see how this GADT example is different from a 
 normal phantom type (modulo different naming)

The difference is that I can inspect at runtime what permissions I have.  I
see that I didn't demonstrate this.  You can introduce a function

checkPerms :: HavePermission p - HavePermission p' - EqCheck
checkPerms HaveAPerm HaveAPerm = IsEq
checkPerms HaveBPerm HaveBPerm = IsEq
checkPerms _ _ = NotEq

data EqCheck a b where
  IsEq :: EqCheck a a
  NotEq :: EqCheck a b

which allows you to compare permissions at runtime and make use of them.
-- 
David Roundy
Department of Physics
Oregon State University
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] announce: Glome.hs raytracer

2008-03-26 Thread David Roundy
On Thu, Mar 27, 2008 at 01:09:47AM +0300, Bulat Ziganshin wrote:
  -Collecting rendering stats is not easy without global variables.  It
  occurs to me that it would be neat if there were some sort of write-only
  global variables that can be incremented by pure code but can only be 
  read from within monadic code; that would be sufficient to ensure that
  the pure code wasn't affected by the values.
 
 the code is called *pure* exactly because it has no side-effects and
 compiler may select either to call some function two times or reuse
 already computed result. actually, you can make sideeffects with
 unsafePerformIO, but there is no guarantees of how many times such
 code will be executed. try this:
 
 plus a b = unsafePerformIO (modifyIORef counter (+1)) `seq` a+b

This is exactly what he wants to do.  The point of putting traces into the
code is precisely to figure out how many times it is called.  The only
trouble is that unsafePerformIO (I believe) can inhibit optimizations,
since there are certain transformations that ghc won't do to
unsafePerformIO code.
-- 
David Roundy
Department of Physics
Oregon State University
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] announce: Glome.hs raytracer

2008-03-26 Thread David Roundy
On Wed, Mar 26, 2008 at 05:07:10PM -0700, Don Stewart wrote:
 droundy:
  On Thu, Mar 27, 2008 at 01:09:47AM +0300, Bulat Ziganshin wrote:
-Collecting rendering stats is not easy without global variables.  It
occurs to me that it would be neat if there were some sort of write-only
global variables that can be incremented by pure code but can only be 
read from within monadic code; that would be sufficient to ensure that
the pure code wasn't affected by the values.
   
   the code is called *pure* exactly because it has no side-effects and
   compiler may select either to call some function two times or reuse
   already computed result. actually, you can make sideeffects with
   unsafePerformIO, but there is no guarantees of how many times such
   code will be executed. try this:
   
   plus a b = unsafePerformIO (modifyIORef counter (+1)) `seq` a+b
  
  This is exactly what he wants to do.  The point of putting traces into the
  code is precisely to figure out how many times it is called.  The only
  trouble is that unsafePerformIO (I believe) can inhibit optimizations,
  since there are certain transformations that ghc won't do to
  unsafePerformIO code.
 
 could we just use -fhpc or profiling here. HPC at least will tell you
 how many times top level things are called, and print pretty graphs
 about it.

It depends what the point is.  I've found traces to be very helpful at
times when debugging (for instance, to get values as well as counts).
Also, I imagine that manual tracing is likely to be far less invasive (if
you do it somewhat discretely) than profiling or using hpc.
-- 
David Roundy
Department of Physics
Oregon State University
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] floating point operations and representation

2008-03-17 Thread David Roundy
On Wed, Mar 12, 2008 at 9:27 PM, Don Stewart [EMAIL PROTECTED] wrote:
  You could consider binding directly to the C functions, if needed,

 {-# OPTIONS -fffi -#include math.h #-}

 import Foreign.C.Types

 foreign import ccall unsafe math.h log10
 c_log10 :: CDouble - CDouble

 log10 :: Double - Double
 log10 x = realToFrac (c_log10 (realToFrac x))

Actually, you could almost certainly just use

foreign import ccall unsafe math.h log10 log10 :: Double - Double

since in ghc CDouble and Double are identical.

It's a bit sloppier, but shouldn't cause any trouble.  And I've no
idea how realToFrac is implemented, but would worry about it behaving
oddly... for instance when given NaNs.

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Small displeasure with associated type synonyms

2008-03-07 Thread David Roundy
On Fri, Mar 07, 2008 at 08:07:57AM +0100, Tom Schrijvers wrote:
 Am I correct in thinking this would have worked if it were an
 associated type instead of an associated type synonym?
 
 ie,
 
 class C a where
data T a
val :: T a
 
 Yes, you are. Associate data type constructors (as well as ordinary 
 algebraic data constructors) are injective. So we have:

Yay, that's what I though! (but was hesitant to suggest anything, since
I've never actually used associated anything...)  It's nice to hear that I
do understand some of this stuff.  :)
-- 
David Roundy
Department of Physics
Oregon State University
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: The Proliferation of List-Like Types

2008-02-20 Thread David Roundy
On Wed, Feb 20, 2008 at 11:18:51PM +0100, Ben Franksen wrote:
 John Goerzen wrote:
 
  On 2008-02-20, Jules Bean [EMAIL PROTECTED] wrote:
  Not directly, no.
 
  The point about Foldable, Functor, and Monad, is that they enforce the
  connection between container and contents. If the contents is of type
  a, the container is of type f a for a fixed type constructor 'f'.
  This works for [], Seq, and so on, but fails for ByteString.
  
  Right.  In a pure abstract sense, we humans know there is a
  relationship between container and contents: a ByteString always
  contains a Word8 (or a Char8 if we choose the alternative
  implementation).
  
  But that is not expressed in the type of ByteString.
 
 Hm, making a function out of a constant is easy on the value level, just use
 (const x) instead of (x). So, what about wrapping ByteString in a GADT,
 like this
 
   data ByteString' a where
 BS' :: Word8 - ByteString' Word8
 
 ? I probably overlooked something important here...

The problem is that while this would change the kind of ByteString to the
same as the kind expected by Functor, you still couldn't define a proper
Functor instance, since only ByteString' Word8 can ever actually be
created.  i.e. how could you implement

fmapBS :: (a - b) - ByteString' a - ByteString' b
-- 
David Roundy
Department of Physics
Oregon State University
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: threads + IORefs = Segmentation fault?

2008-02-08 Thread David Roundy
On Fri, Feb 08, 2008 at 10:46:25AM +, Simon Marlow wrote:
 (I'm a bit behind with haskell-cafe, sorry for not seeing this sooner...)

No problem!

 Yes, that should all be fine, because the IORef is only modified from one 
 thread, and read from the other(s).   If you were modifying the IORef from 
 more than one thread you would need to use atomicallyModifyIORef, or MVars.

If I did modify the IORef from more than one thread (e.g. if a bug were
introduced), would this cause any trouble other than occasional missed
updates or reads of wrong data?
-- 
David Roundy
Department of Physics
Oregon State University
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: [darcs-devel] announcing darcs 2.0.0pre3

2008-01-31 Thread David Roundy
On Thu, Jan 31, 2008 at 09:47:06AM -0600, John Goerzen wrote:
 On 2008-01-22, David Roundy [EMAIL PROTECTED] wrote:
  We are happy to announce the third prerelease version of darcs 2! Darcs 2

 I'm very happy to see this, and will be trying it out today!

Great! I do recommend that you try the darcs version, as we've had a number
of improvements since the last prerelease.

 I have one concern though, and it's a big one.  On your DarcsTwo page,
 it says:
 
   Darcs get is now much faster, and always operates in a lazy
   fashion, meaning that patches are downloaded only when they are
   needed. . . if the source repository disappears, or you lose network
   connectivity, some operations may fail. I do not believe these
   dangers will prove particularly problematic, but we may need to
   fine-tune the user interface to make it more clear what is going on.
 
 To me, that's a showstopper.  This was really one of the huge
 advantages of Darcs over, say, svn.  I can darcs get a repo from a
 server to the laptop, and hack on it doing anything, with full
 history, with no need for net connectivity.  Losing this feature would
 be a huge problem for me and many others.
 
 The other benefits include having a complete local copy of a project's
 history in case that project's repo ever goes away.  Also, I'm
 concerned that if I do a darcs get from one local repo to another, and
 remove the original one, that my other repo will no longer be complete.

This is a definite danger, and I've considered making local gets always
complete, just because there's much less benefit for partial local gets
(except perhaps when hard links between the repos aren't possible).  But
I'm hesitant to add special-case code just yet, as the best solution is to
figure out a set of behavior that is readily-understood by users, and for
that purpose, consistent behavior is good.

 I hope that this means it's just a default, that there is still some
 way to pull down everything that could possibly be needed?  But from
 the way the wiki page is sounded, it doesn't sound that way.

Running darcs check, darcs changes -s or darcs changes foobar for
instance would ensure that you've got a complete repository.
-- 
David Roundy
Department of Physics
Oregon State University
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: [darcs-devel] announcing darcs 2.0.0pre3

2008-01-31 Thread David Roundy
On Thu, Jan 31, 2008 at 11:51:10AM -0700, zooko wrote:
 I would suggest that strict get should be the default and lazy is a  
 command-line option.

Okay.  I'm convinced, and am pushing a patch to do this.
-- 
David Roundy
Department of Physics
Oregon State University
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: [darcs-devel] announcing darcs 2.0.0pre3

2008-01-25 Thread David Roundy
On Wed, Jan 23, 2008 at 03:26:51PM +, Simon Marlow wrote:
 There are still times when I see nothing happening, for example in the 
 unpull test on the GHC repo (see previous messages), the last progress 
 message I get is
 
 Reading patches in /64playpen/simonmar/ghc-darcs2 17040
 
 and it sits there for 7-8 seconds before completing.  Does this maybe shed 
 any light on why this unpull is 2 times slower than darcs1?

I've finally got an idea what's causing this.  Actually, there are three
operations in which the hashed repositories don't scale quite as well as
the old format--all of which are pretty fast, so it's only visible on
huge repositories like yours.

The first two scale with the number of files and directories in the
repository, and both are essentially garbage collecting of the pristine
cache.

One goes through the _darcs/pristine.hashed/ directory and compares each
file there with a list of files that should be there, deleting those that
aren't present.  This is currently O(N^2) in the number of files and
directories in the repository, because we use a list to do this set
comparison.  Using Data.Set should make this O(NlogN) which probably is
more than enough to make this negligible.  It's already pretty fast, even
on the ghc repo, so this may not even be noticeable.

The second is similar to the first.  It's when we go through the global
cache to remove any unused files.  Here we use the link count, and remove
any that have a link count of 1.  This means running stat on each file to
get the link count, so this is only O(N) where N is the total number of
distinct files and directories (i.e. having different hashes) present in
*all* repositories that you use.  It scales better than the previous one,
but if stat is slow on the cache, or if you've got very many different
large repositories, it could be slow.

The third (and possibly largest) issue is the writing of the inventory
files.  This is (thankfully) independent of the number or size of files in
the repository, and only depends on the number of patches and tags.  It's
roughly O(N+M) where N is the number of patches and tags (with a different
prefactor on the two, but who cares?), and M is the number of new or
modified patches.  This isn't *bad* scaling, but when you've got 17k
patches, O(N) adds up.  This is most likely the primary culprit, but is
tricky to fix, since as far as I can imagine, we'd need to change the
PatchSet data type (currently just a nested RL list) to cache the hash
values, and change all functions manipulating them to invalidate the cache
when they make changes.  :(

I've added progress reporting to all three of these (and it seems like it's
working).  All three could be sped up in some way (the second, perhaps just
by avoiding writing pristine files to the global cache, or failing to
clean them up).  But I'd rather hear from you where the pain is before
going ahead, since I've got more work right now than I can handle.

Also, if you want (way!) more information when tracking down timings, the
progress reporting now interacts with the --debug flag to generate enough
data to kill a horse.  You could also add the --timings flag, which will
add some timestamps (alas, with only 1s resolution) that might be helpful.
-- 
David Roundy
Department of Physics
Oregon State University
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [darcs-devel] [Haskell-cafe] Re: announcing darcs 2.0.0pre3

2008-01-24 Thread David Roundy
On Jan 23, 2008 5:47 PM, zooko [EMAIL PROTECTED] wrote:
  In principle it is good to provide a cryptographically secure hash, as
  this allows users to sign their repositories by signing a single file,
  which seems like it's potentially quite a useful feature.

 Can you be more specific about this -- who can sign a repository?
 How is such a signature checked?  What guarantee can you rely on if
 the check passes?

All data in the hashed format is hashed.  Darcs doesn't implement any
checking of signatures, but you could (relatively) easily do so by
hand.  Just sign _darcs/hashed_inventory, and if the signature is
valid and the repository is consistent (which darcs automatically
checks for any portion of the repository that it accesses), then the
repository hasn't been tampered with (since it was signed, anyhow).

As far as what the guarantee is, all contents of the repository
(except _darcs/prefs/ and of course the working directory) are
accessed by hashes stored in that one file.

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] announcing darcs 2.0.0pre3

2008-01-23 Thread David Roundy
On Wed, Jan 23, 2008 at 09:59:29AM +0300, Bulat Ziganshin wrote:
 Hello David,
 
 Tuesday, January 22, 2008, 11:43:44 PM, you wrote:
 
  The third prerelease features (apart from numerous bug and performance
  regression fixes) a completely rewritten rollback command and new
  progress-reporting functionality. If darcs takes more than a couple of
  seconds for a given operation and provides you with no feedback as to what
  it's up to, let us know, so we can fine-tune the progress-reporting output!
 
 btw, in my program, progress is output be separate thread each 0.1
 second. operating threads just update global var with current state.
 of course when operating thread need to interact with user, it just
 sts another global var to False which prevents progress indicator
 thread from showing anything

This is precisely what we do in darcs.  :)
-- 
David Roundy
Department of Physics
Oregon State University
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: [darcs-devel] announcing darcs 2.0.0pre3

2008-01-23 Thread David Roundy
On Wed, Jan 23, 2008 at 03:26:51PM +, Simon Marlow wrote:
 David Roundy wrote:
  We are happy to announce the third prerelease version of darcs 2! Darcs 2
  features numerous improvements, and it seems that we have fixed most of the
  regressions, so we're looking for help, from users willing to try this
  release out. Read below, to see how you can benefit from this new release,
  and how you can help us to make the final darcs 2 release the best ever!
  
  The third prerelease features (apart from numerous bug and performance
  regression fixes) a completely rewritten rollback command and new
  progress-reporting functionality. If darcs takes more than a couple of
  seconds for a given operation and provides you with no feedback as to what
  it's up to, let us know, so we can fine-tune the progress-reporting output!
 
 The progress reporting is fantastic!  It's worth upgrading to darcs2 just 
 for that :-)

Thanks! I've enjoyed it myself, actually...

 ... Although the progress reporting doesn't appear to work quite as well
 on darcs-1 repositories as it does on darcs-2 repositories - is that
 expected?

No, it's not really expected, but the progress reporting is rather hastily
thrown together, so it's not surprising, either.  Basically I first
converted the existing progress-reporting code (which reported getting
patches with darcs get, and applying them in a few other instances), and
then started throwing in progress annotations in other spots until my
couple of test commands and the ones I normally use seemed to be pretty
snappy (I'm not sure what the right word for a lack of delays in
progress-reporting).

 There are still times when I see nothing happening, for example in the 
 unpull test on the GHC repo (see previous messages), the last progress 
 message I get is
 
 Reading patches in /64playpen/simonmar/ghc-darcs2 17040
 
 and it sits there for 7-8 seconds before completing.  Does this maybe shed 
 any light on why this unpull is 2 times slower than darcs1?

Hmmm.  I'll take a look.  This is basically equivalent to something like

darcs obliterate --last 400 -a

I believe? The ghc repo definitely stresses different parts of darcs,
because of its large size (which means you often have the privilege of
reporting poor behavior).
-- 
David Roundy
Department of Physics
Oregon State University
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: [darcs-devel] announcing darcs 2.0.0pre3

2008-01-23 Thread David Roundy
On Wed, Jan 23, 2008 at 03:26:51PM +, Simon Marlow wrote:
 There are still times when I see nothing happening, for example in the 
 unpull test on the GHC repo (see previous messages), the last progress 
 message I get is
 
 Reading patches in /64playpen/simonmar/ghc-darcs2 17040
 
 and it sits there for 7-8 seconds before completing.  Does this maybe shed 
 any light on why this unpull is 2 times slower than darcs1?

I'm not entirely certain what's triggering this, but I have identified that
removing a couple of sha1 checks cuts 1s out of 15s for me.  This makes me
wonder whether it's worth looking into a faster sha1 implementation.
-- 
David Roundy
Department of Physics
Oregon State University
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: [darcs-devel] announcing darcs 2.0.0pre3

2008-01-23 Thread David Roundy
On Wed, Jan 23, 2008 at 10:09:05PM +0100, Peter Verswyvelen wrote:
 Maybe a dedicated SIMD version of SHA1?
 
 http://arctic.org/~dean/crypto/sha1.html

From what that page says, it looks like thta sha1 is not recommended for
actual use (although they don't test with gcc 4.x).  I've come across the
gnulib sha1 routine, which is adequately-licensed, and is fast enough to
give us a 10% speedup in my obliterate test (beyond which we probably hit
diminishing returns--we're probably no longer spending much time in sha1 at
all).
-- 
David Roundy
Department of Physics
Oregon State University
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [darcs-devel] [Haskell-cafe] Re: announcing darcs 2.0.0pre3

2008-01-23 Thread David Roundy
On Wed, Jan 23, 2008 at 02:55:06PM -0700, zooko wrote:
 I have to ask: why does darcs use SHA-1?
 
 On the one hand, SHA-1 is cryptographically fragile and is deprecated  
 for use in applications that require collision-resistance and pre- 
 image resistance.  SHA-2 is the current standard for those  
 applications (SHA-2 is about twice as expensive in CPU [1]), and  
 SHA-3 is under development.
 
 On the other hand, why does darcs need a cryptographically secure  
 hash function at all?  Wouldn't MD5 or a sufficiently wide CRC, such  
 as the one used in ZFS [2], do just as well?  They would certainly be  
 a lot faster to compute.
 
 Is there some behavior on the part of some malicious actor that darcs  
 tries to prevent, such that the collision-resistance (such as it is)  
 of SHA-1 is necessary to prevent it?

It's mostly historical, but also supported by the assumption that Linus
thought about it when *he* decided to use sha1 for the same purpose.  In
principle it is good to provide a cryptographically secure hash, as this
allows users to sign their repositories by signing a single file, which
seems like it's potentially quite a useful feature.  On the other hand,
using sha2, which is twice as expensive (and twice as large, right) would
perhaps be too costly.  I don't know.  SHA-2 would cost more in disk space
and network bandwidth, as well as in CPU time.

Is SHA-1 optimal? I don't know.  Is it reasonable? I suspect so.
-- 
David Roundy
Department of Physics
Oregon State University
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] threads + IORefs = Segmentation fault?

2008-01-21 Thread David Roundy
On Sat, Jan 19, 2008 at 08:36:55PM +0100, Alfonso Acosta wrote:
 On Jan 19, 2008 2:36 PM, David Roundy [EMAIL PROTECTED] wrote:
  Using ghc 6.6, but I've since isolated the bug as being unrelated to the
  IORefs and threading, it was in an FFI binding that somehow never died
  until I was testing this new code.
 
 In case the you are creating a binding of haskell code. Did you make
 sure that the runtime constructor and destructor (hs_* functions) are
 properly called? The could be the source of the segfault.

No, there are no bindings to haskell code involved.  Perhaps it's even a
segfault in libwww itself.
-- 
David Roundy
Department of Physics
Oregon State University
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] threads + IORefs = Segmentation fault?

2008-01-19 Thread David Roundy
Using ghc 6.6, but I've since isolated the bug as being unrelated to the
IORefs and threading, it was in an FFI binding that somehow never died
until I was testing this new code.

David

On Sat, Jan 19, 2008 at 01:27:47PM +0100, Peter Verswyvelen wrote:
 Hi David,
 
 Which version of GHC are you using?
 
 I tried to recompile some GHC 6.6.1 progs using GHC 6.8.2 and I also got
 segfaults. I haven't figured out yet if this is because my changes to
 make it work with GHC 6.8.2 are incorrect, or if this is an issue with
 6.8.2.
 
 Cheers,
 Peter
 
 
 On Fri, 2008-01-18 at 18:22 -0500, David Roundy wrote:
  Hi all,
  
  I'm working on some new progress-reporting code for darcs, and am getting
  segmentation faults!  :( The code uses threads + an IORef global variable
  to do this (with lots of unsafePerformIO).  So my question for the gurus
  who know more about this than I do:  is this safe? I thought it would be,
  because only one thread ever modifies the IORef, and the others only read
  it.  I don't really care if they read a correct value, as long as they
  don't segfault.
  
  The code (to summarize) looks like:
  
  {-# NOINLINE _progressData #-}
  _progressData :: IORef (Map String ProgressData)
  _progressData = unsafePerformIO $ newIORef empty
  
  updateProgressData :: String - (ProgressData - ProgressData) - IO ()
  updateProgressData k f = when (progressMode) $ modifyIORef _progressData 
  (adjust f k)
  
  setProgressData :: String - ProgressData - IO ()
  setProgressData k p = when (progressMode) $ modifyIORef _progressData 
  (insert k p)
  
  getProgressData :: String - IO (Maybe ProgressData)
  getProgressData k = if progressMode then lookup k `fmap` readIORef 
  _progressData
  else return Nothing
  
  The key function is
  
  beginTedious :: String - IO ()
  beginTedious k = do tid - forkIO $ handleProgress k
  debugMessage $ Beginning  ++ k
  setProgressData k $ ProgressData { sofar = 0,
 latest = Nothing,
 total = Nothing,
 handler = Just tid }
  
  which is called before an action that may be so tedious for our users that
  they need their day brightened by messages such as Applying patch
  137/1436.  The handleProgress function alternates between threadDelay and
  reading the progress data to see whether any progress has been made and
  printing messages.  Meanwhile the main thread calls functions that update
  _progressData.
  
  Anyhow, the point is that I'm getting segfaults, even after recompiling
  everything from scratch! Is this in fact that unsafe? Do I really need to
  switch to MVars, even though no locking is required?
 
 ___
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-cafe

-- 
David Roundy
Department of Physics
Oregon State University
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] threads + IORefs = Segmentation fault?

2008-01-18 Thread David Roundy
Hi all,

I'm working on some new progress-reporting code for darcs, and am getting
segmentation faults!  :( The code uses threads + an IORef global variable
to do this (with lots of unsafePerformIO).  So my question for the gurus
who know more about this than I do:  is this safe? I thought it would be,
because only one thread ever modifies the IORef, and the others only read
it.  I don't really care if they read a correct value, as long as they
don't segfault.

The code (to summarize) looks like:

{-# NOINLINE _progressData #-}
_progressData :: IORef (Map String ProgressData)
_progressData = unsafePerformIO $ newIORef empty

updateProgressData :: String - (ProgressData - ProgressData) - IO ()
updateProgressData k f = when (progressMode) $ modifyIORef _progressData 
(adjust f k)

setProgressData :: String - ProgressData - IO ()
setProgressData k p = when (progressMode) $ modifyIORef _progressData (insert k 
p)

getProgressData :: String - IO (Maybe ProgressData)
getProgressData k = if progressMode then lookup k `fmap` readIORef _progressData
else return Nothing

The key function is

beginTedious :: String - IO ()
beginTedious k = do tid - forkIO $ handleProgress k
debugMessage $ Beginning  ++ k
setProgressData k $ ProgressData { sofar = 0,
   latest = Nothing,
   total = Nothing,
   handler = Just tid }

which is called before an action that may be so tedious for our users that
they need their day brightened by messages such as Applying patch
137/1436.  The handleProgress function alternates between threadDelay and
reading the progress data to see whether any progress has been made and
printing messages.  Meanwhile the main thread calls functions that update
_progressData.

Anyhow, the point is that I'm getting segfaults, even after recompiling
everything from scratch! Is this in fact that unsafe? Do I really need to
switch to MVars, even though no locking is required?
-- 
David Roundy
Department of Physics
Oregon State University
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: [darcs-devel] announcing darcs 2.0.0pre2

2008-01-16 Thread David Roundy
On Thu, Jan 03, 2008 at 11:11:40AM +, Simon Marlow wrote:
  Anyhow, could you retry this test with the above change in methodology,
  and let me know if (a) the pull is still slow the first time and (b) if
  it's much faster the second time (after the reverse unpull/pull)?
 
 I think I've done it in both directions now, and it got faster, but still 
 much slower than darcs1:
 
 $ time darcs2 unpull --from-tag 2007-09-25 -a
 Finished unpulling.
 58.68s real   50.64s user   6.36s system   97% darcs2 unpull --from-tag 
 2007-09-25 -a
 $ time darcs2 pull -a ../ghc-darcs2
 Pulling from ../ghc-darcs2...
 Finished pulling and applying.
 53.28s real   44.62s user   7.10s system   97% darcs2 pull -a ../ghc-darcs2
 
 This is still an order of magnitude slower than darcs1 for the same 
 operation.  (these times are now on the local filesystem, BTW)

I've recently found the problem leading to this slowdown (I believe) and
get about an order-of-magnitude improvement in the speed of a pull of 400
patches in the ghc repository.  It turned out to be an issue that scaled
with the size (width) of the repository, not with the number of patches
(which had been the obvious suspect), which was causing trouble when
applying to the pristine cache.

At this point, darcs-2 outperforms darcs-1 on most tests that I've tried,
so it'd be a good time to find some more performance problems, if you
can... and I don't doubt that there are more out there.
-- 
David Roundy
Department of Physics
Oregon State University
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: 0/0 1 == False

2008-01-14 Thread David Roundy
On Fri, Jan 11, 2008 at 07:10:20PM -0800, Jonathan Cast wrote:
 On 11 Jan 2008, at 10:12 AM, Achim Schneider wrote:
 
 David Roundy [EMAIL PROTECTED] wrote:
 
 Prelude let x=1e-300/1e300
 Prelude x
 0.0
 Prelude x/x
 NaN
 
 The true answer here is that x/x == 1.0 (not 0 or +Infinity), but
 there's no way for the computer to know this, so it's NaN.
 
 Didn't catch this the first time around, but: only to a physicist.

I don't understand what you're saying below.  Do you mean that the
true answer is not 1.0, or that it's not reasonable for the computer to
call it NaN?  Since 1.0 is the answer you get for high-precision
computations, it's hard to see how you can argue that it's a wrong answer.

 (I mean no disrespect to the author of darcs, but nevertheless the  
 point stands).  Back in the real world, 0 / 0 may be defined  
 arbitrarily, or left undefined.  (Defining it breaks the wonderful  
 property that, if lim (xn) = x, lim (yn) = y, and x/y = z, then lim  
 (xn / yn) = z.  This is considered a Bad Thing by real  
 mathematicians).  In fact, in integration theory 0 * inf = 0 for  
 certain 'multiplications', which gives the lie to 0 / 0.
-- 
David Roundy
Department of Physics
Oregon State University
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: 0/0 1 == False

2008-01-11 Thread David Roundy
On Fri, Jan 11, 2008 at 02:54:20PM +0100, Achim Schneider wrote:
 +-0 / +-0 is always NaN 'cos you can't tell which one is bigger and
 thus can't decide between positive and negative Infinity, and it
 isn't both, either.
 
 But then there's +0/0 and -0/0, which would be +Infinity and
 -Infinity, and +0  0  -0. AFAIK there are no floats with three zero
 values, though. 

No, +0/0 might be 0 or finite instead of +Infinity, so it's a NaN.

e.g. consider

Prelude let x=1e-300/1e300
Prelude x
0.0
Prelude x/x
NaN

The true answer here is that x/x == 1.0 (not 0 or +Infinity), but there's
no way for the computer to know this, so it's NaN.
-- 
David Roundy
Department of Physics
Oregon State University
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Why purely in haskell?

2008-01-10 Thread David Roundy
On Jan 9, 2008 5:42 PM, Henning Thielemann
[EMAIL PROTECTED] wrote:
  I just want to point out that unsafePerformIO is at the core of the
  (safe) bytestring library.  As SPJ et al pointed out, this is crucial
  functionality, and is only unsafe if unsafely used.

 Indeed, there are hacks and they are some times necessary. The good thing
 about Haskell is, that hacks look like hacks.

 In Modula-3 modules using hacks must be explicitly marked as UNSAFE. See
   http://www.cs.purdue.edu/homes/hosking/m3/reference/unsafe.html
  Maybe this is also an option for Haskell?

I don't think this is a good idea.  It comes down to a question of
whether you think it should be allowed for Haskell code to be used to
write core Haskell libraries in a first-class manner.  Perhaps you
think libraries should always be in C in order to avoid the use of
unsafePerformIO, but I prefer to allow them to be written in Haskell.

But then, I don't see unsafePerformIO as inherently a hack.  It's the
only possible way that certain useful abstractions can be
impelemented--at least, that's understanding.  I'd be curious as to
how much of the Prelude would be marked unsafe if you had your wish...

David
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


  1   2   3   4   >