Re: let vs. where [was: Re: more unsafePerformIO questions (is it safe to use with ReadMode Handles)?]

2003-08-20 Thread Andrew J Bromage
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)?

2003-08-19 Thread Simon Marlow
 
 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)?

2003-08-19 Thread Ganesh Sittampalam
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)?

2003-08-19 Thread Simon Marlow
 
 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)?

2003-08-19 Thread Ganesh Sittampalam
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)?

2003-08-19 Thread Simon Marlow
 
  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)?

2003-08-19 Thread Andrew J Bromage
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)?]

2003-08-19 Thread Jan Scheffczyk
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