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-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 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-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 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 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 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 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 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 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

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-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 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

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
 hellos 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 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-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 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
hellos 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 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
| hellos 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 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-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

 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-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


  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-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