why cannot i get the value of a IORef variable ?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
15 messages Options
Reply | Threaded
Open this post in threaded view
|

why cannot i get the value of a IORef variable ?

z_axis
> let aaa = unsafePerformIO  $ newIORef []
> writeIORef aaa [1,2,3]
> readIORef aaa
[(),(),()]

sincerely!
e^(π.i) + 1 = 0
Reply | Threaded
Open this post in threaded view
|

Re: why cannot i get the value of a IORef variable ?

Kyle Murphy-2
I assume you're trying this at the GHCi prompt, which is where you're problem is coming from, specifically on the first line.
When you do:
> let aaa = unsafePerformIO $ newIORef []
GHCi takes a wild stab at the type of [] and comes up with the type [()], so now you have a IORef [()] type, which is why when you try
to store [1,2,3] in the IORef you get back [(),(),()]. Try this instead and it should work:
> let aaa = unsafePerformIO $ newIORef ([] :: [Int])

-R. Kyle Murphy
--
Curiosity was framed, Ignorance killed the cat.


On Thu, Oct 22, 2009 at 01:02, zaxis <[hidden email]> wrote:

> let aaa = unsafePerformIO  $ newIORef []
> writeIORef aaa [1,2,3]
> readIORef aaa
[(),(),()]

sincerely!
--
View this message in context: http://www.nabble.com/why-cannot-i-get-the-value-of-a-IORef-variable---tp26004111p26004111.html
Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe


_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: why cannot i get the value of a IORef variable ?

Thomas DuBuisson
In reply to this post by z_axis
zaxis <[hidden email]> wrote:
>> let aaa = unsafePerformIO  $ newIORef []
>> writeIORef aaa [1,2,3]
>> readIORef aaa
> [(),(),()]

What in Haskells name do you think you're doing?  Don't use
unsafePerformIO like that!  Its unnecessary and a bit concerning,
really.

Prelude> :m Data.IORef
Prelude Data.IORef> x <- newIORef [] :: IO (IORef [Int])
Prelude Data.IORef> writeIORef x [1,2,3]
Prelude Data.IORef> readIORef x
[1,2,3]


>
> sincerely!
> --
> View this message in context: http://www.nabble.com/why-cannot-i-get-the-value-of-a-IORef-variable---tp26004111p26004111.html
> Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.
>
> _______________________________________________
> Haskell-Cafe mailing list
> [hidden email]
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: why cannot i get the value of a IORef variable ?

z_axis
In reply to this post by Kyle Murphy-2
Yes, it works now!  thank you very much!

Kyle Murphy-2 wrote
I assume you're trying this at the GHCi prompt, which is where you're
problem is coming from, specifically on the first line.
When you do:
> let aaa = unsafePerformIO $ newIORef []
GHCi takes a wild stab at the type of [] and comes up with the type [()], so
now you have a IORef [()] type, which is why when you try
to store [1,2,3] in the IORef you get back [(),(),()]. Try this instead and
it should work:
> let aaa = unsafePerformIO $ newIORef ([] :: [Int])

-R. Kyle Murphy
--
Curiosity was framed, Ignorance killed the cat.


On Thu, Oct 22, 2009 at 01:02, zaxis <z_axis@163.com> wrote:

>
> > let aaa = unsafePerformIO  $ newIORef []
> > writeIORef aaa [1,2,3]
> > readIORef aaa
> [(),(),()]
>
> sincerely!
> --
> View this message in context:
> http://www.nabble.com/why-cannot-i-get-the-value-of-a-IORef-variable---tp26004111p26004111.html
> Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.
>
> _______________________________________________
> 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
e^(π.i) + 1 = 0
Reply | Threaded
Open this post in threaded view
|

Re: why cannot i get the value of a IORef variable ?

z_axis
In reply to this post by Thomas DuBuisson
thank you! In fact i really donot understand "unsafePerformIO" very much !

Thomas DuBuisson wrote
zaxis <z_axis@163.com> wrote:
>> let aaa = unsafePerformIO  $ newIORef []
>> writeIORef aaa [1,2,3]
>> readIORef aaa
> [(),(),()]

What in Haskells name do you think you're doing?  Don't use
unsafePerformIO like that!  Its unnecessary and a bit concerning,
really.

Prelude> :m Data.IORef
Prelude Data.IORef> x <- newIORef [] :: IO (IORef [Int])
Prelude Data.IORef> writeIORef x [1,2,3]
Prelude Data.IORef> readIORef x
[1,2,3]


>
> sincerely!
> --
> View this message in context: http://www.nabble.com/why-cannot-i-get-the-value-of-a-IORef-variable---tp26004111p26004111.html
> Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.
>
> _______________________________________________
> 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
e^(π.i) + 1 = 0
Reply | Threaded
Open this post in threaded view
|

Re: why cannot i get the value of a IORef variable ?

Colin Paul Adams

    zaxis> thank you! In fact i really donot understand
    zaxis> "unsafePerformIO" very much !

Then all you have to understand is - never use it!
--
Colin Adams
Preston Lancashire
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: why cannot i get the value of a IORef variable ?

Gregory Crosswhite-2
For clarity, one trick that uses "unsafePerformIO" which you may have  
seen posted on this list earlier today is the following way of  
creating a globally visible IORef:

import Data.IORef
import System.IO.Unsafe

*** counter = unsafePerformIO $ newIORef 0 ***

next = do
   modifyIORef counter (+1)
   readIORef counter

The key line has been starred;  this created a counter IORef that  
"next" could access without having to be explicitly given it on each  
call.

Personally, though, I never use this approach because it creates a  
race condition.  Because Haskell is lazy, "counter" will not be  
evaluated until the first time that it is accessed.  If two threads  
access it at the same time before it has been evaluated, then in GHC  
there are conditions under which they could both evaluate it and  
create a new IORef simultaneously, resulting in each thread  
effectively ending up with its own counter variable when you  
specifically wanted a globally shared counter variable.

This is why I personally use the ReaderT monad if I want to implicitly  
share a global IORef, rather than using this trick.

Cheers,
Greg


On Oct 21, 2009, at 10:50 PM, Colin Paul Adams wrote:

>
>    zaxis> thank you! In fact i really donot understand
>    zaxis> "unsafePerformIO" very much !
>
> Then all you have to understand is - never use it!
> --
> Colin Adams
> Preston Lancashire
> _______________________________________________
> Haskell-Cafe mailing list
> [hidden email]
> http://www.haskell.org/mailman/listinfo/haskell-cafe

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: why cannot i get the value of a IORef variable ?

Thomas DuBuisson
> For clarity, one trick that uses "unsafePerformIO" which you may have seen
> posted on this list earlier today is the following way of creating a
> globally visible IORef:
>
> import Data.IORef
> import System.IO.Unsafe
>
> *** counter = unsafePerformIO $ newIORef 0 ***
>
> next = do
>  modifyIORef counter (+1)
>  readIORef counter

This is still unsafe but it can evidently be slightly improved with
NOINLINE pragma:

    {-# NOINLINE counter #-}
    counter = unsafePerformIO $ newIORef 0

without said pragma the counter could be initialized numerous times,
as I understand it.  All this said, I hope people avoid
unsafePerformIO for mutable globals - reader monad, state monad, and
partial application should be sufficient tools.

Thomas
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: why cannot i get the value of a IORef variable ?

David Menendez-2
In reply to this post by Gregory Crosswhite-2
On Thu, Oct 22, 2009 at 2:23 AM, Gregory Crosswhite
<[hidden email]> wrote:
> For clarity, one trick that uses "unsafePerformIO" which you may have seen
> posted on this list earlier today is the following way of creating a
> globally visible IORef:
>
> import Data.IORef
> import System.IO.Unsafe
>
> *** counter = unsafePerformIO $ newIORef 0 ***

Danger! If the monomorphism restriction is disabled, this ends up
creating a value of type forall a. Num a => IORef a, which can be used
to break type safety.

More generally,

cell :: IORef a
cell = unsafePerformIO $ newIORef undefined

unsafeCoerce :: a -> b
unsafeCoerce x = unsafePerformIO $ do
    writeIORef cell x
    readIORef cell

This way lies segmentation faults. That "unsafe" is there for a reason.

--
Dave Menendez <[hidden email]>
<http://www.eyrie.org/~zednenem/>
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: why cannot i get the value of a IORef variable ?

Gregory Crosswhite-2
Yes, I was once taught that "Every time you use unsafePerformIO, God  
kills a kitten,"  so every time I consider using it I first ask  
myself:  is this really worth an innocent kitten's life?

Cheers,
Greg

On Oct 22, 2009, at 11:32 AM, David Menendez wrote:

> On Thu, Oct 22, 2009 at 2:23 AM, Gregory Crosswhite
> <[hidden email]> wrote:
>> For clarity, one trick that uses "unsafePerformIO" which you may  
>> have seen
>> posted on this list earlier today is the following way of creating a
>> globally visible IORef:
>>
>> import Data.IORef
>> import System.IO.Unsafe
>>
>> *** counter = unsafePerformIO $ newIORef 0 ***
>
> Danger! If the monomorphism restriction is disabled, this ends up
> creating a value of type forall a. Num a => IORef a, which can be used
> to break type safety.
>
> More generally,
>
> cell :: IORef a
> cell = unsafePerformIO $ newIORef undefined
>
> unsafeCoerce :: a -> b
> unsafeCoerce x = unsafePerformIO $ do
>    writeIORef cell x
>    readIORef cell
>
> This way lies segmentation faults. That "unsafe" is there for a  
> reason.
>
> --
> Dave Menendez <[hidden email]>
> <http://www.eyrie.org/~zednenem/>

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: why cannot i get the value of a IORef variable ?

Tim Wawrzynczak
Well, I apologize for starting this whole thread which involves so many dead kittens :(  I was just trying to help answer a question :) 
I guess I assumed too much.. that someone would think to be careful when using a function with the word 'unsafe' in it...

So, be warned, all Haskellers!  Be careful when using any function that starts with the word 'unsafe'!  You may kill a kitten!  And I guess this says something about using 'unsafe' functions... http://upload.wikimedia.org/wikipedia/en/1/11/God-kills-kitten.jpg (NSFW)...

Cheers and sorry all,
Tim


On Thu, Oct 22, 2009 at 1:59 PM, Gregory Crosswhite <[hidden email]> wrote:
Yes, I was once taught that "Every time you use unsafePerformIO, God kills a kitten,"  so every time I consider using it I first ask myself:  is this really worth an innocent kitten's life?

Cheers,
Greg


On Oct 22, 2009, at 11:32 AM, David Menendez wrote:

On Thu, Oct 22, 2009 at 2:23 AM, Gregory Crosswhite
<[hidden email]> wrote:
For clarity, one trick that uses "unsafePerformIO" which you may have seen
posted on this list earlier today is the following way of creating a
globally visible IORef:

import Data.IORef
import System.IO.Unsafe

*** counter = unsafePerformIO $ newIORef 0 ***

Danger! If the monomorphism restriction is disabled, this ends up
creating a value of type forall a. Num a => IORef a, which can be used
to break type safety.

More generally,

cell :: IORef a
cell = unsafePerformIO $ newIORef undefined

unsafeCoerce :: a -> b
unsafeCoerce x = unsafePerformIO $ do
  writeIORef cell x
  readIORef cell

This way lies segmentation faults. That "unsafe" is there for a reason.

--
Dave Menendez <[hidden email]>
<http://www.eyrie.org/~zednenem/>

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe


_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: why cannot i get the value of a IORef variable ?

Colin Paul Adams
In reply to this post by Gregory Crosswhite-2
>>>>> "Gregory" == Gregory Crosswhite <[hidden email]> writes:

    Gregory> Yes, I was once taught that "Every time you use
    Gregory> unsafePerformIO, God kills a kitten," so every time I
    Gregory> consider using it I first ask myself: is this really
    Gregory> worth an innocent kitten's life?

I've changed my mind.

Everyone go out and use unsafePerformIO all the time. That way we can
get rid of all those mudering kittens, and the dragonflies will live longer.
--
Colin Adams
Preston Lancashire
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: why cannot i get the value of a IORef variable ?

Anton van Straaten
Colin Paul Adams wrote:

>>>>>> "Gregory" == Gregory Crosswhite <[hidden email]> writes:
>
>     Gregory> Yes, I was once taught that "Every time you use
>     Gregory> unsafePerformIO, God kills a kitten," so every time I
>     Gregory> consider using it I first ask myself: is this really
>     Gregory> worth an innocent kitten's life?
>
> I've changed my mind.
>
> Everyone go out and use unsafePerformIO all the time. That way we can
> get rid of all those mudering kittens, and the dragonflies will live longer.

You're missing the bigger picture.  It's clear from the literature[*]
that the IO monad, the type system, and possibly even Haskell itself, is
powered by kittens.  If you use up all the kittens, Haskell will just
stop working.  Terms won't even reach WHNF, they'll be stuck in KAF,
Kittenless Abnormal Form.

On the plus side, this does make for a slogan with high market appeal:

    Haskell: Kittens inside

--
[*] http://arcanux.org/lambdacats.html
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: why cannot i get the value of a IORef variable ?

Derek Elkins
In reply to this post by David Menendez-2
On Thu, Oct 22, 2009 at 1:32 PM, David Menendez <[hidden email]> wrote:

> On Thu, Oct 22, 2009 at 2:23 AM, Gregory Crosswhite
> <[hidden email]> wrote:
>> For clarity, one trick that uses "unsafePerformIO" which you may have seen
>> posted on this list earlier today is the following way of creating a
>> globally visible IORef:
>>
>> import Data.IORef
>> import System.IO.Unsafe
>>
>> *** counter = unsafePerformIO $ newIORef 0 ***
>
> Danger! If the monomorphism restriction is disabled, this ends up
> creating a value of type forall a. Num a => IORef a, which can be used
> to break type safety.
>
> More generally,
>
> cell :: IORef a
> cell = unsafePerformIO $ newIORef undefined
>
> unsafeCoerce :: a -> b
> unsafeCoerce x = unsafePerformIO $ do
>    writeIORef cell x
>    readIORef cell
>
> This way lies segmentation faults. That "unsafe" is there for a reason.

This is exactly what happened in the original example.
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: why cannot i get the value of a IORef variable ?

Martijn van Steenbergen-2
In reply to this post by Anton van Straaten
Anton van Straaten wrote:
> On the plus side, this does make for a slogan with high market appeal:
>
>    Haskell: Kittens inside

Thanks. Now I have trouble getting this image of lambda-shaped bonsai
kittens out of my head.

;-)

Martijn.

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe