Re: let vs. where [was: Re: more unsafePerformIO questions (is it safe to use with ReadMode Handles)?]
G'day all. On Wed, Aug 20, 2003 at 07:42:59AM +0200, Jan Scheffczyk wrote: I always thought that there is a tiny difference between let and where: They're semantically equivalent. See, for example: http://haskell.org/onlinereport/decls.html#sect4.4.3.2 Cheers, Andrew Bromage ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
RE: more unsafePerformIO questions (is it safe to use with ReadMode Handles)?
I'm finishing up my Haskell interface to WordNet (http://www.cogsci.princeton.edu/~wn/) and have a standard unsafePerformIO question :). Basically, the interface functions by first calling an initialization function, 'initializeWordNet :: IO WordNetEnv'. WordNetEnv is essentially just a record of a lot of Handles which we will be reading from and doing binary search in. All the functions which use the WordNetEnv (i.e., every other function in the interface) basically do the following: - take one handle from the WordNetEnv and do binary search in it, read a line. - use that line to read another line from another of the handles - parse that last one of course, therefore, all of these functions have type '... - IO something'. However, one of the rules of thumb for using unsafePerformIO is when you can imagine a functional interface doing the same thing. I can: simply read in all the databases in initializeWordNet and then do Data.List.lookup on the results. Does this mean it's safe to wrap all these functions in unsafePerformIO? It sounds like your interface is pure, as long as you don't expect the contents of any of the databases to change during the run of your program. That is, it doesn't matter whether you do all the IO at the start or lazilly on demand. If the databases *do* change over time, then there are two possibilities: 1. the contents change due to external factors only 2. the contents change because this program doing the writing in (1), you can still pretend the interface is pure, by imagining that all the changes happened earlier. This works as long as you only read the external data once. In (2), you have a truly impure interface, so using unsafePerformIO would be wrong. Cheers, Simon ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
Re: more unsafePerformIO questions (is it safe to use with ReadMode Handles)?
On Tue, 19 Aug 2003 10:27:23 +0100, Simon Marlow [EMAIL PROTECTED] wrote: If the databases *do* change over time, then there are two possibilities: 1. the contents change due to external factors only 2. the contents change because this program doing the writing in (1), you can still pretend the interface is pure, by imagining that all the changes happened earlier. This works as long as you only read the external data once. Isn't there the possibility of inlining causing a read to happen twice even if it only appears to happen once? Ganesh ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
RE: more unsafePerformIO questions (is it safe to use with ReadMode Handles)?
If the databases *do* change over time, then there are two possibilities: 1. the contents change due to external factors only 2. the contents change because this program doing the writing in (1), you can still pretend the interface is pure, by imagining that all the changes happened earlier. This works as long as you only read the external data once. Isn't there the possibility of inlining causing a read to happen twice even if it only appears to happen once? In theory that would be a valid transformation, but in practice no compiler would duplicate arbitrary computations. GHC certainly doesn't. Cheers, Simon ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
Re: more unsafePerformIO questions (is it safe to use with ReadMode Handles)?
On Tue, 19 Aug 2003 10:52:57 +0100, Simon Marlow [EMAIL PROTECTED] wrote: Isn't there the possibility of inlining causing a read to happen twice even if it only appears to happen once? In theory that would be a valid transformation, but in practice no compiler would duplicate arbitrary computations. GHC certainly doesn't. I was thinking of a situation like let x = unsafePerformIO readFooFromDB in x+x I see from your Secrets of the GHC inliner paper that x wouldn't be inlined by GHC, but it seems to me like a serious abuse of the principle of referential transparency to write programs that _assume_ that. Cheers, Ganesh ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
RE: more unsafePerformIO questions (is it safe to use with ReadMode Handles)?
Isn't there the possibility of inlining causing a read to happen twice even if it only appears to happen once? In theory that would be a valid transformation, but in practice no compiler would duplicate arbitrary computations. GHC certainly doesn't. I was thinking of a situation like let x = unsafePerformIO readFooFromDB in x+x I see from your Secrets of the GHC inliner paper that x wouldn't be inlined by GHC, but it seems to me like a serious abuse of the principle of referential transparency to write programs that _assume_ that. Yes, I agree that one shouldn't rely on the no duplication of work property. However, folloing this argument we arrive at the conclusion that hGetContents is an invalid use of unsafePerformIO. (which is something I've been saying for a while now :-). Cheers, Simon ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
Re: more unsafePerformIO questions (is it safe to use with ReadMode Handles)?
G'day all. On Tue, Aug 19, 2003 at 11:11:23AM +0100, Ganesh Sittampalam wrote: I was thinking of a situation like let x = unsafePerformIO readFooFromDB in x+x I see from your Secrets of the GHC inliner paper that x wouldn't be inlined by GHC, but it seems to me like a serious abuse of the principle of referential transparency to write programs that _assume_ that. I would have thought that this was the principle of full laziness (which Haskell doesn't guarantee, but all compilers in practice support) was more important here. If the code instead was this: let x = expensiveComputation foo in x + x I would certainly hope that expensiveComputation wasn't called twice, and even though the language doesn't guarantee it, I have already written code that assumed it. Cheers, Andrew Bromage ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
let vs. where [was: Re: more unsafePerformIO questions (is it safe to use with ReadMode Handles)?]
Hi Andrew, let x = expensiveComputation foo in x + x I would certainly hope that expensiveComputation wasn't called twice, and even though the language doesn't guarantee it, I have already written code that assumed it. I always thought that there is a tiny difference between let and where: Using let expensiveComputation foo might be computed twice (depending on the compiler?). But using: x + x where x = expensiveComputation foo should compute the value for x only once. Therefore, I always try to use where for common subexpressions. Please correct me if I'm wrong here. Cheers, Jan ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell