Re: unsafePerformIO safety.

2007-03-07 Thread Isaac Dupree
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

Simon Marlow wrote:
> You're right that sometimes you really want it to be inlined - this is
> why there's a function called inlinePerformIO in Data.ByteString.Base,
> for example.  You'd better really know what you're doing before using
> that one, though :-)

yep, it should be generally available as unsafeInlineUnsafePerformIO (-:

It's especially unsafe because... all of the IO might not be executed,
due to lazy evaluation + optimization? Some of the IO might be run twice
without other parts of it being so?

Isaac
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.3 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFF7p9jHgcxvIWYTTURAqAKAKCu8dJ4rpyMcMH7ebPv0HfIUyGSgACgy0Jq
naeTCZk/2xZraOrSJtyObm8=
=oKKG
-END PGP SIGNATURE-
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: unsafePerformIO safety.

2007-03-07 Thread Simon Marlow

Lennart Augustsson wrote:
I wouldn't like if unsafePerformIO could never be inlined, sometimes you 
want it inlined for performance.
And not all uses are hacky, it's just that when I use it, then burden is 
on me to convince myself that it is safe.


unsafePerformIO is currently not inlined - there's a NOINLINE pragma on its 
definition in GHC.IOBase, and some comments in there to explain why.


You're right that sometimes you really want it to be inlined - this is why 
there's a function called inlinePerformIO in Data.ByteString.Base, for example. 
 You'd better really know what you're doing before using that one, though :-)


Cheers,
Simon
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: unsafePerformIO safety.

2007-03-07 Thread Lennart Augustsson
I wouldn't like if unsafePerformIO could never be inlined, sometimes  
you want it inlined for performance.
And not all uses are hacky, it's just that when I use it, then burden  
is on me to convince myself that it is safe.


On Mar 6, 2007, at 23:56 , Neil Mitchell wrote:


Hi

On 3/6/07, Lennart Augustsson <[EMAIL PROTECTED]> wrote:
Yeah, you really need {-# NOINLINE var #-} to make it reasonable  
safe.


Couldn't GHC bake in knowledge about unsafePerformIO, and never inline
it? It is a slightly hacky solution, but since unsafePerformIO is
pretty much only used in hacks, I think its almost fitting.

Thanks

Neil


___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: unsafePerformIO safety.

2007-03-06 Thread David Brown
Neil Mitchell wrote:

> On 3/6/07, Lennart Augustsson <[EMAIL PROTECTED]> wrote:
>> Yeah, you really need {-# NOINLINE var #-} to make it reasonable safe.
>
> Couldn't GHC bake in knowledge about unsafePerformIO, and never inline
> it? It is a slightly hacky solution, but since unsafePerformIO is
> pretty much only used in hacks, I think its almost fitting.

It seems to be used a bit more than just as a hack.  Many things that
interface with the real world, but try to present lazy interfaces have
to use it.

Maintaining a shared state that doesn't have to be passed around to
everything that uses it isn't really a hack.

As an example, I would like to have something that performs logging,
and is used by many clients.  Without the unsafePerformIO, everything
has to somehow find and pass around the state of this logging system,
whereas with it, it can just allocate one when first needed.

Non-strict semantics are kind of a new thing for me.  I'm still trying
to get a good grasp of what can be lazy, what should live in the IO
Monad, and what should have a carefully crafted "bridge" between the
two.  Things like hGetContents have somewhat set a trend here.

Dave

___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: unsafePerformIO safety.

2007-03-06 Thread Neil Mitchell

Hi

On 3/6/07, Lennart Augustsson <[EMAIL PROTECTED]> wrote:

Yeah, you really need {-# NOINLINE var #-} to make it reasonable safe.


Couldn't GHC bake in knowledge about unsafePerformIO, and never inline
it? It is a slightly hacky solution, but since unsafePerformIO is
pretty much only used in hacks, I think its almost fitting.

Thanks

Neil
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: unsafePerformIO safety.

2007-03-06 Thread Lennart Augustsson

Yeah, you really need {-# NOINLINE var #-} to make it reasonable safe.

On Mar 6, 2007, at 23:18 , David Brown wrote:


Seth Kurtzberg wrote:

On Tue, 06 Mar 2007 12:03:05 -0800
David Brown <[EMAIL PROTECTED]> wrote:


I've noticed quite a few pages referencing constructs such as:

  var :: MVar ([Foo])
  var = unsafePerformIO (newMVar ([]))

and the likes.  Is there a danger of different uses of 'var' getting
new MVars instead of all sharing one.

Having a reliable way to create a piece of global state would be  
very

convenient.


This operation is unsafe by definition.  I use it extensively,
without problems.  The "unsafe" in the name reminds you that there
are situations for which the function is inappropriate, but all of
my deployed commercial programs have functionality of this sort.
Understand the risk, but don't hesitate to use it.


Do you do anything to keep 'var' from getting inlined?  I can envision
a case where the code would be inlined, and then each use would get a
separate MVar.

Thanks,
Dave

___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: unsafePerformIO safety.

2007-03-06 Thread Isaac Dupree
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

David Brown wrote:
> I've noticed quite a few pages referencing constructs such as:
> 
>   var :: MVar ([Foo])
>   var = unsafePerformIO (newMVar ([]))
> 
> and the likes.  Is there a danger of different uses of 'var' getting
> new MVars instead of all sharing one.

If I remember correctly, you "should" put {-# NOINLINE var #-} on a line
just before that.

> 
> Having a reliable way to create a piece of global state would be very
> convenient.

This is well known and extensively discussed - unfortunately it is a
complicated (or at least controversial) issue

Isaac

-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.3 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFF7fiFHgcxvIWYTTURAoMXAJ9SCryCX+daNLKrMIhWlMh/aJmVXwCghosx
6/lBweYnNslHLal57RAtX0Y=
=2oIN
-END PGP SIGNATURE-
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: unsafePerformIO safety.

2007-03-06 Thread David Brown
Seth Kurtzberg wrote:
> On Tue, 06 Mar 2007 12:03:05 -0800
> David Brown <[EMAIL PROTECTED]> wrote:
>
>> I've noticed quite a few pages referencing constructs such as:
>>
>>   var :: MVar ([Foo])
>>   var = unsafePerformIO (newMVar ([]))
>>
>> and the likes.  Is there a danger of different uses of 'var' getting
>> new MVars instead of all sharing one.
>>
>> Having a reliable way to create a piece of global state would be very
>> convenient.
>
> This operation is unsafe by definition.  I use it extensively,
> without problems.  The "unsafe" in the name reminds you that there
> are situations for which the function is inappropriate, but all of
> my deployed commercial programs have functionality of this sort.
> Understand the risk, but don't hesitate to use it.

Do you do anything to keep 'var' from getting inlined?  I can envision
a case where the code would be inlined, and then each use would get a
separate MVar.

Thanks,
Dave

___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: unsafePerformIO safety.

2007-03-06 Thread Seth Kurtzberg
On Tue, 06 Mar 2007 12:03:05 -0800
David Brown <[EMAIL PROTECTED]> wrote:

> I've noticed quite a few pages referencing constructs such as:
> 
>   var :: MVar ([Foo])
>   var = unsafePerformIO (newMVar ([]))
> 
> and the likes.  Is there a danger of different uses of 'var' getting
> new MVars instead of all sharing one.
> 
> Having a reliable way to create a piece of global state would be very
> convenient.

This operation is unsafe by definition.  I use it extensively, without 
problems.  The "unsafe" in the name reminds you that there are situations for 
which the function is inappropriate, but all of my deployed commercial programs 
have functionality of this sort.  Understand the risk, but don't hesitate to 
use it.

Seth Kurtzberg

> 
> Dave
> 
> ___
> Glasgow-haskell-users mailing list
> Glasgow-haskell-users@haskell.org
> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
> 
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: unsafePerformIO and NOINLINE Pragma

2005-09-14 Thread Jan Christiansen
Am Dienstag, 13. September 2005 16:13 schrieb David Sabel:
> Hi,
>
> > Hi!
> >
> > I want to analyse the laziness of a data structure. To check how many
> > nodes are constructed I use a global counter.
> >
> > counter :: IORef Int
> > counter = unsafePerformIO (newIORef 0)
> >
> > This counter is increased every time the constructor is called by
> > redefining the constructor OBDD as follows.
> >
> > oBDD low var high =
> >   seq (unsafePerformIO (modifyIORef counter (+1))) (OBDD low var high)
> >
> > This works fine.
> > When I compile with optimisations the counter is always set to one no
> > matter how many nodes are constructed. I thought this would be caused by
> > inlining. Therefore I have added two NOINLINE pragmata.
> >
> > {-# NOINLINE counter #-}
> > {-# NOINLINE oBDD #-}
> >
> > Although the counter doesn't work. Is there another optimisation that can
> > cause harm? Is there something wrong with the pragmata?
>
> Two comments:
> 1. There are other optimisations than inlining that can break sharing, e.g.
>common subexpression elimination, full-laziness-transformation.
>
> 2. I tested the following:
>
>   {-# NOLINE counter #-}
>   {-# INLINE oBDD #-}
>
>   then the counter "seems" to work correct.  In my opinion
>   oBDD is an abstraction and can always be inlined.

Sadly this solution doesn't work in my environment. The counter is always set 
to 2 while it should be something around 15.000. I think it's not worth going 
into detail of the transformations for me thus I will check the number of 
nodes without optimisations and the performance with optimisations. Thanks 
anyway.
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: unsafePerformIO and NOINLINE Pragma

2005-09-13 Thread David Sabel
Hi,

> Hi!
> 
> I want to analyse the laziness of a data structure. To check how many nodes 
> are constructed I use a global counter.
> 
> counter :: IORef Int
> counter = unsafePerformIO (newIORef 0)
> 
> This counter is increased every time the constructor is called by redefining 
> the constructor OBDD as follows.
> 
> oBDD low var high =
>   seq (unsafePerformIO (modifyIORef counter (+1))) (OBDD low var high)
> 
> This works fine. 
> When I compile with optimisations the counter is always set to one no matter 
> how many nodes are constructed. I thought this would be caused by inlining. 
> Therefore I have added two NOINLINE pragmata.
> 
> {-# NOINLINE counter #-}
> {-# NOINLINE oBDD #-}
> 
> Although the counter doesn't work. Is there another optimisation that can 
> cause harm? Is there something wrong with the pragmata?

Two comments:
1. There are other optimisations than inlining that can break sharing, e.g. 
   common subexpression elimination, full-laziness-transformation.

2. I tested the following:

  {-# NOLINE counter #-}
  {-# INLINE oBDD #-}

  then the counter "seems" to work correct.  In my opinion 
  oBDD is an abstraction and can always be inlined.

Cheer,
  David
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: unsafePerformIO

2004-04-08 Thread George Russell
Sven Panne wrote:
Huh? I'm not sure what you mean exactly, but with the help of unsafePerformIO
and a pragma for clever compilers you can simulate something like a global
variable in Haskell. Here an excerpt from the GLUT menu handling module:
{-# NOINLINE theMenuTable #-}
theMenuTable :: IORef MenuTable
theMenuTable = unsafePerformIO (newIORef emptyMenuTable)
...
Definitely not something to be proud of, but quite handy from time to time. :-)
Alternatives are passing the IORef to every function which needs it (but this
would clutter up the GLUT API in the above case) or using the FFI for holding
global data on the C side. GHC uses a similar hack internally, too, BTW.
This is not just handy from time to time, but very frequently.  I've
just discovered it occurs about 100 times in 100K LOC that I am
responsible for, so often that I have stopped feeling guilty about it.
I don't really know what else I could do.  One solution would be to use
implicit parameters to pass a global state variable around, but this would
require me to change the type of huge numbers of functions, since implicit
parameters are still explicit in types.
I don't remember having any actual bugs caused by unsafePerformIO.  Well,
only one, before I knew about putting NOINLINE in.
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


RE: unsafePerformIO and IORefs

2002-11-19 Thread Simon Marlow
> Hal Daume III wrote:
>  > You can't. [...]
> 
> Well, you can, but only for CAFs. This idiom/hack is used
> quite happily throughout GHC, HOpenGL, H/Direct, ...

I think "quite happily" is a bit strong ;-)  We'd much rather have a
safe way to do what is really quite a reasonable thing.

Cheers,
Simon
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



RE: unsafePerformIO and IORefs

2002-11-19 Thread Simon Marlow
> At 2002-11-18 11:05, Sven Panne wrote:
> 
> >global :: a -> IORef a
> >global a = unsafePerformIO (newIORef a)
> 
> This is useful, you can do this with it:
> 
>   ref = global Nothing
> 
>   convert :: a -> IO b
>   convert a = do
> writeIORef ref (Just a)
> Just b <- readIORef ref
> return b

This particular "flexibility" provided by unsafePerformIO is actually
documented...

http://www.haskell.org/ghc/docs/latest/html/base/System.IO.Unsafe.html#u
nsafePerformIO

Cheers,
Simon
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



Re: unsafePerformIO and IORefs

2002-11-18 Thread Lennart Augustsson
Yes, there are several reasons for having UNSAFE in the name. :-)

   -- Lennart

Ashley Yakeley wrote:


At 2002-11-18 11:05, Sven Panne wrote:

 

global :: a -> IORef a
global a = unsafePerformIO (newIORef a)
   


This is useful, you can do this with it:

 ref = global Nothing

 convert :: a -> IO b
 convert a = do
   writeIORef ref (Just a)
   Just b <- readIORef ref
   return b


 




___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



Re: unsafePerformIO and IORefs

2002-11-18 Thread Ashley Yakeley
At 2002-11-18 11:05, Sven Panne wrote:

>global :: a -> IORef a
>global a = unsafePerformIO (newIORef a)

This is useful, you can do this with it:

  ref = global Nothing

  convert :: a -> IO b
  convert a = do
writeIORef ref (Just a)
Just b <- readIORef ref
return b


-- 
Ashley Yakeley, Seattle WA

___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



Re: unsafePerformIO and IORefs

2002-11-18 Thread Michael Weber
On Mon, Nov 18, 2002 at 10:36:05AM -0800, Hal Daume III wrote:
> You can't.  CSE (common subexpression elimination) will replace any
> occurances of 'newState 0' in a function body with the same value.
> 
> In short: don't use upIO :)

Sorry, cannot resist to pour a little salt onto the wound :)

[232]% grep global ghc/compiler/utils/Util.lhs 
, global
global :: a -> IORef a
global a = unsafePerformIO (newIORef a)
[233]%

ghc/compiler/HsVersions.h:
[...]
#ifdef __GLASGOW_HASKELL__
#define GLOBAL_VAR(name,value,ty)  \
name = Util.global (value) :: IORef (ty); \
{-# NOINLINE name #-}
#endif


[237]% grep -r GLOBAL_VAR ghc/compiler | wc -l  
 90


Muahahah... ;-P


Cheers,
Michael
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



Re: unsafePerformIO and IORefs

2002-11-18 Thread Sven Panne
Hal Daume III wrote:
> You can't. [...]

Well, you can, but only for CAFs. This idiom/hack is used
quite happily throughout GHC, HOpenGL, H/Direct, ...

Slightly modified stuff from GHC's sources:


-- global variables in Haskell :-)


global :: a -> IORef a
global a = unsafePerformIO (newIORef a)

#define GLOBAL_VAR(name,value,ty) \
name :: IORef (ty) ; \
name = global (value) ; \
{-# NOINLINE name #-}


-- examples


GLOBAL_VAR(counter, 0, Int)
GLOBAL_VAR(flag, False, Bool)



Cheers,
   S.

___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



Re: unsafePerformIO and IORefs

2002-11-18 Thread Hal Daume III
You can't.  CSE (common subexpression elimination) will replace any
occurances of 'newState 0' in a function body with the same value.

In short: don't use upIO :)

If I'm wrong, someone will correct me.  But expect a few "what are you
trying to do" email messages or people suggesting implicit paremeters or
monad wrappers (in fact, count this as the first of said emails).

 - Hal

--
Hal Daume III

 "Computer science is no more about computers| [EMAIL PROTECTED]
  than astronomy is about telescopes." -Dijkstra | www.isi.edu/~hdaume

On Mon, 18 Nov 2002, Nicolas Oury wrote:

> I want to write something like
> 
> type State a = IORef a
> 
> newState :: a -> State a
> newState v = unsafePerformIO (newIORef  v)
> 
> 
> But I don't want the compileer to inline this nor to inline any 
> application of this.
> 
> {#NOINLINE newState#}
> 
> But how can I stop this function to be inlined when applied for example :
> 
> let x = newState 0 in
> {... code where x is used twice ...}
> 
> How to be sure that x isn't inlined and that all occurences of x are 
> pointing to the same memory place ?
> 
> Best regards,
> Nicolas Oury
> 
> ___
> Glasgow-haskell-users mailing list
> [EMAIL PROTECTED]
> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
> 

___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



RE: unsafePerformIO

2002-10-14 Thread Simon Marlow


> [...]
> 
> 
> > As for sharing, we currently don't provide any guarnatees, 
> although we
> > should.  It is currently the case that if you write
> >
> > a = unsafePerformIO (putStr "hello")
> > b = unsafePerformIO (putStr "hello")
> >
> > and both a and b are evaluated, then you may get either one or two
> > "hello"s on stdout.  You can currently make things more 
> deterministic by
> > (a) adding NOINLINE pragmas for a and b, and (b) using the 
> flag -fno-cse
> > to disable common sub-expression elimination.  Then you'll 
> get exactly
> > two instances of "hello" on stdout, although we won't guarantee that
> > behaviour for ever.  At some point we'll fix it so that 
> unsafePerformIO
> > applications are never duplicated or coalesced.
> 
> 
> Are there any (short) examples available where using of 
> unsafePerformIO
> leads to unexpected behaviour,
> especially an example with the terms a and b from above?

I don't have any examples to hand, but you ought to be able to make one
up without too much difficulty.  You just need two identical bindings
such as in the example above, and compile with -O.

Cheers,
Simon
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



Re: unsafePerformIO

2002-10-09 Thread David Sabel


- Original Message -
From: "Simon Marlow" <[EMAIL PROTECTED]>
Sent: Tuesday, September 24, 2002 2:58 PM
Subject: RE: unsafePerformIO

[...]


> As for sharing, we currently don't provide any guarnatees, although we
> should.  It is currently the case that if you write
>
> a = unsafePerformIO (putStr "hello")
> b = unsafePerformIO (putStr "hello")
>
> and both a and b are evaluated, then you may get either one or two
> "hello"s on stdout.  You can currently make things more deterministic by
> (a) adding NOINLINE pragmas for a and b, and (b) using the flag -fno-cse
> to disable common sub-expression elimination.  Then you'll get exactly
> two instances of "hello" on stdout, although we won't guarantee that
> behaviour for ever.  At some point we'll fix it so that unsafePerformIO
> applications are never duplicated or coalesced.


Are there any (short) examples available where using of unsafePerformIO
leads to unexpected behaviour,
especially an example with the terms a and b from above?

with best regards, David

-
JWGU Frankfurt

___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



Re: unsafePerformIO

2002-09-24 Thread Alastair Reid


Koen Claessen <[EMAIL PROTECTED]> writes:
> However, I for example have no idea what happens when unsafely
> executing something that throws exceptions, performs a forkIO,
> something that uses MVar's, etc.

I won't dare to try to characterize the difference exactly but you
should expect very different behaviour between Hugs and GHC when using
unsafePerformIO with threads and exceptions.  The Hugs version of
unsafePerformIO isn't intended to receive as much abuse as the GHC
version whereas the GHC version has been (ab)used by large numbers of
people.

--
Alastair

___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



RE: unsafePerformIO

2002-09-24 Thread Simon Peyton-Jones

Koen

Based on this info, how would you like to write the notes you would like
to see on unsafePerformIO?  The starting point is at
http://haskell.cs.yale.edu/ghc/docs/latest/html/base/GHC.IOBase.html#uns
afePerformIO

If you write the notes, we'll check their veracity and add them.  We'll
do the formatting too!

Simon

| -Original Message-
| From: Simon Marlow [mailto:[EMAIL PROTECTED]]
| Sent: 24 September 2002 13:59
| To: Koen Claessen; [EMAIL PROTECTED]
| Subject: RE: unsafePerformIO
| 
| > But it is a fact that many of us have at least some idea of
| > what happens "under the hood" when we use unsafePerformIO.
| > This is also described in your paper "Stretching the storage
| > manager: weak pointers and stable names in Haskell".
| >
| > However, I for example have no idea what happens when
| > unsafely executing something that throws exceptions,
| > performs a forkIO, something that uses MVar's, etc.
| 
| Exceptions: an exception raised by the computation inside
| unsafePerformIO will be propagated to the enclosing expression, as per
| the normal semantics for imprecise exceptions.  The exception raised
by
| an application of unsafePerformIO may of course also be imprecise;
| consider 'unsafePerformIO $ (1/0 + error "foo") `seq` return ()'.
| 
| The behaviour of forkIO and other side-effecting operations inside
| unsafePerforIO can I think be explained by the following statement: if
| an expression "unsafePerformIO e" has been reduced to head normal
form,
| then all the I/O computations in e have been performed.  The exact
| timing of the evaluation is underspecified, just as any other
expression
| in Haskell.  However, if you're using unsafePerformIO with real side
| effects, then I suspect that what you're doing is highly dodgy and you
| should find another way to do it :-)
| 
| Does that help?
| 
| As for sharing, we currently don't provide any guarnatees, although we
| should.  It is currently the case that if you write
| 
| a = unsafePerformIO (putStr "hello")
| b = unsafePerformIO (putStr "hello")
| 
| and both a and b are evaluated, then you may get either one or two
| "hello"s on stdout.  You can currently make things more deterministic
by
| (a) adding NOINLINE pragmas for a and b, and (b) using the flag
-fno-cse
| to disable common sub-expression elimination.  Then you'll get exactly
| two instances of "hello" on stdout, although we won't guarantee that
| behaviour for ever.  At some point we'll fix it so that
unsafePerformIO
| applications are never duplicated or coalesced.
| 
| If you're interested in when unsafePerformIO is "safe" to use, see:
| 
|
http://www.haskell.org/pipermail/glasgow-haskell-users/2002-July/003683.
| html
| 
| (and see my followups for an alternative view).
| 
| Cheers,
|   Simon
| ___
| Glasgow-haskell-users mailing list
| [EMAIL PROTECTED]
| http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



RE: unsafePerformIO

2002-09-24 Thread Simon Marlow

> But it is a fact that many of us have at least some idea of
> what happens "under the hood" when we use unsafePerformIO.
> This is also described in your paper "Stretching the storage
> manager: weak pointers and stable names in Haskell".
> 
> However, I for example have no idea what happens when
> unsafely executing something that throws exceptions,
> performs a forkIO, something that uses MVar's, etc.

Exceptions: an exception raised by the computation inside
unsafePerformIO will be propagated to the enclosing expression, as per
the normal semantics for imprecise exceptions.  The exception raised by
an application of unsafePerformIO may of course also be imprecise;
consider 'unsafePerformIO $ (1/0 + error "foo") `seq` return ()'.

The behaviour of forkIO and other side-effecting operations inside
unsafePerforIO can I think be explained by the following statement: if
an expression "unsafePerformIO e" has been reduced to head normal form,
then all the I/O computations in e have been performed.  The exact
timing of the evaluation is underspecified, just as any other expression
in Haskell.  However, if you're using unsafePerformIO with real side
effects, then I suspect that what you're doing is highly dodgy and you
should find another way to do it :-)

Does that help?

As for sharing, we currently don't provide any guarnatees, although we
should.  It is currently the case that if you write

a = unsafePerformIO (putStr "hello")
b = unsafePerformIO (putStr "hello")

and both a and b are evaluated, then you may get either one or two
"hello"s on stdout.  You can currently make things more deterministic by
(a) adding NOINLINE pragmas for a and b, and (b) using the flag -fno-cse
to disable common sub-expression elimination.  Then you'll get exactly
two instances of "hello" on stdout, although we won't guarantee that
behaviour for ever.  At some point we'll fix it so that unsafePerformIO
applications are never duplicated or coalesced.

If you're interested in when unsafePerformIO is "safe" to use, see:

http://www.haskell.org/pipermail/glasgow-haskell-users/2002-July/003683.
html

(and see my followups for an alternative view).

Cheers,
Simon
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



RE: unsafePerformIO

2002-09-24 Thread Koen Claessen

Simon Peyton-Jones wrote:

 | The actions performed by unsafePerformIO are simply
 | done at some entirely unpredictable time, perhaps
 | interleaved with actions on the main execution path.

But it is a fact that many of us have at least some idea of
what happens "under the hood" when we use unsafePerformIO.
This is also described in your paper "Stretching the storage
manager: weak pointers and stable names in Haskell".

However, I for example have no idea what happens when
unsafely executing something that throws exceptions,
performs a forkIO, something that uses MVar's, etc.

It would be nice to see what happens in such a case, and at
least a document that informally describes what happens.
This includes issues such as loss of sharing because of
inlining, etc.

"unsafePerformIO" is the best thing since sliced bread for
someone who wants to add stuff to the compiler without
changing the compiler. The usefulness/portability at the
moment is limited since nobody "dares" to say what is going
on.

/Koen.

___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



RE: unsafePerformIO

2002-09-24 Thread Simon Peyton-Jones

The actions performed by unsafePerformIO are simply done at some
entirely unpredictable time, perhaps interleaved with actions on the
main execution path. 

The formal semantics in the notes doesn't have a good way to express
that because the purely-functional part is given a denotational
semantics... yet unsafePerformIO can occur in the middle of that.

So it's tiresome to characterise in theory, and hard to predict in
practice.  You should only use it when the state it is fiddling with is
well partitioned.


Simon

| -Original Message-
| From: David Sabel [mailto:[EMAIL PROTECTED]]
| Sent: 20 September 2002 13:48
| To: Simon Peyton-Jones; [EMAIL PROTECTED]
| Subject: unsafePerformIO
| 
| In read your paper ""Tackling the Awkward Squad: monadic input /
output,
| concurrency, exceptions, and foreign-language calls in Haskell",  and
have
| a question about unsafePerformIO.
| 
| In your operational semantic of the IO-Monad you tell nothing about,
how
| 'unsafe' IO actions are performed, is there another paper /
documentation
| about
| this available, or can you - or someone else - give me a review about
that?
| 
| David
| JWGU Frankfurt
| 

___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



Re: unsafePerformIO

2002-09-20 Thread Hal Daume III

I'm not sure of a reference, the basic idea is this:

  IO a is represented by the pair (RealWorld, a) (unboxed, really
  but whatever)
  When an IO action is run (via main), a RealWorld state is provided
  by the compiler and passes it around.
  When you do unsafePerformIO, the compiler conjures up some
  value of type RealWorld to use.  It is unsafe because it
  doesn't guarentee the relative order of IO actions.

Of course, someone correct me if I'm mistaken.

 - Hal

--
Hal Daume III

 "Computer science is no more about computers| [EMAIL PROTECTED]
  than astronomy is about telescopes." -Dijkstra | www.isi.edu/~hdaume

On Fri, 20 Sep 2002, David Sabel wrote:

> In read your paper ""Tackling the Awkward Squad: monadic input / output,
> concurrency, exceptions, and foreign-language calls in Haskell",  and have
> a question about unsafePerformIO.
> 
> In your operational semantic of the IO-Monad you tell nothing about, how
> 'unsafe' IO actions are performed, is there another paper / documentation
> about
> this available, or can you - or someone else - give me a review about that?
> 
> David
> JWGU Frankfurt
> 
> 
> ___
> Glasgow-haskell-users mailing list
> [EMAIL PROTECTED]
> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
> 

___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



RE: unsafePerformIO around FFI calls

2002-07-09 Thread Simon Marlow


> > That's a nice succinct way to describe it.  Another way, which boils
> > down to the same thing but which is a little more concrete, is to
> > ask:
> 
> >   - Does the function's result depend only on the values of its
> > arguments?
> 
> I have two problems with this alternative test:
> 
> 1) It is sometimes slightly stricter test than necessary.
> 
>Consider a hypothetical pair of C functions
>
>  Foo toFoo(int);
>  int fromFoo(Foo);
>
>which satisfy the property
>
>  fromFoo(toFoo(x)) == x
>
>but such that the result of toFoo does not depend on its argument.
>(Perhaps toFoo allocates some memory in which to stores its result
>and returns a pointer to that memory.)
>
>The function's result does vary independently of its values so it
>fails your test.
>
>But if toFoo/fromFoo are the only functions on Foo, then we could
>obviously have implemented the same API in Haskell with the aid of
>newtype so it passes my test.

Ok, if we're going to nit pick :)  When talking about equality you have
to restrict that to "observable equivalence" in the context of whatever
abstract types you're dealing with.  If a function always returns
observably equivalent results when given observably equivalent
arguments, then it is "safe".

For example, toFoo would not be safe if you can test for equality
between pointers.  But if all you can do is convert it back using
fromFoo, then you're ok.

> 2) It fails to recognise the fact that IO actions have side effects.

Well, side effects are usually only visible in the IO monad so that's
ok.  In your free() example, the result is either () or _|_, so the
function does depend on more than just the value of the argument.  I
think the definition holds (but only just).

For example, we normally consider a function which uses some temporary
allocation on the C heap as "safe" to use from unsafePerformIO.  But its
side effect is visible from the IO monad by inspecting the C heap
pointer.

Cheers,
Simon
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



Re: unsafePerformIO around FFI calls

2002-07-09 Thread Alastair Reid


> That's a nice succinct way to describe it.  Another way, which boils
> down to the same thing but which is a little more concrete, is to
> ask:

>   - Does the function's result depend only on the values of its
> arguments?

I have two problems with this alternative test:

1) It is sometimes slightly stricter test than necessary.

   Consider a hypothetical pair of C functions
   
 Foo toFoo(int);
 int fromFoo(Foo);
   
   which satisfy the property
   
 fromFoo(toFoo(x)) == x
   
   but such that the result of toFoo does not depend on its argument.
   (Perhaps toFoo allocates some memory in which to stores its result
   and returns a pointer to that memory.)
   
   The function's result does vary independently of its values so it
   fails your test.
   
   But if toFoo/fromFoo are the only functions on Foo, then we could
   obviously have implemented the same API in Haskell with the aid of
   newtype so it passes my test.


2) It fails to recognise the fact that IO actions have side effects.

   For example, the C library function 'free' always returns the same
   result (i.e., '()') but it's a bad idea to call free twice on the
   same argument.

   One could argue that the side effect is part of the result because
   IO actions return a modified world but only a long term functional
   programmer would think like that so it doesn't help the man in the
   street.  (In fact, IIRC, the Concurrent Haskell semantics doesn't
   use the state-passing explanation so you don't even see side effects
   reflected as changes in the returned world state.)


-- 
Alastair Reid [EMAIL PROTECTED]  
Reid Consulting (UK) Limited  http://www.reid-consulting-uk.ltd.uk/alastair/

___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



RE: unsafePerformIO around FFI calls

2002-07-09 Thread Simon Marlow

> Hal Daume <[EMAIL PROTECTED]> writes:
> > I'm curious exactly what is "safe" and what is "unsafe" to wrap
> > unsafePerformIO around when it comes to FFI calls. 
> 
> Here's a simple test:
> 
>  Could you imagine an alternative implementation of the same API in
>  pure Haskell?  (Don't consider efficiency or effort required to write
>  the implementation, just whether it can be done.)
> 
>  If so, then it is ok to use unsafePerformIO and the ffi to implement
>  the API instead.
> 
> If it fails that test, it is incredibly unlikely that it is ok and a
> proof that it is ok is likely to be pretty complex - maybe worth a
> PLDI paper or some such.

That's a nice succinct way to describe it.  Another way, which boils
down to the same thing but which is a little more concrete, is to ask:

  - Does the function's result depend only on the values of its
arguments?

(obviously only makes sense for a top-level IO function which you want
to wrap in unsafePerformIO - for a non-top-level function or expression
just replace 'arguments' with 'arguments and free variables').

Cheers,
Simon
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



Re: unsafePerformIO around FFI calls

2002-07-08 Thread Alastair Reid


Hal Daume <[EMAIL PROTECTED]> writes:
> I'm curious exactly what is "safe" and what is "unsafe" to wrap
> unsafePerformIO around when it comes to FFI calls. 

Here's a simple test:

 Could you imagine an alternative implementation of the same API in
 pure Haskell?  (Don't consider efficiency or effort required to write
 the implementation, just whether it can be done.)

 If so, then it is ok to use unsafePerformIO and the ffi to implement
 the API instead.

If it fails that test, it is incredibly unlikely that it is ok and a
proof that it is ok is likely to be pretty complex - maybe worth a
PLDI paper or some such.

--
Alastair Reid [EMAIL PROTECTED]  
Reid Consulting (UK) Limited  http://www.reid-consulting-uk.ltd.uk/alastair/
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users