Re: [Haskell-cafe] Can't figure out source of race condition when using System.Process
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?
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?
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?
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?
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?
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 ?
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
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?
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?
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?
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
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
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
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
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
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
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
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
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
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
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
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
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/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?
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?
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 -
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 -
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)
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
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
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?
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?
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
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??
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?
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?
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
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
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?
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/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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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?
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
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?
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/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?
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
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
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)
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)
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..]
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..]
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
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
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..]
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
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
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
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
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
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
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
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?
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
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
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
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
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
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
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
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
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
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?
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?
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?
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
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
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
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?
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