
Hello, I was recently looking at the STM library, and I have a question about the function "unsafeIOToSTM". Can anyone explain to me what is unsafe about it, and what sort of use would be considered "safe"? Thanks, John

On Feb 12, 2008 6:28 PM, John Lato
Hello,
I was recently looking at the STM library, and I have a question about the function "unsafeIOToSTM". Can anyone explain to me what is unsafe about it, and what sort of use would be considered "safe"?
A few things. First, this will crash:
atomically $ unsafeIOToStm $ atomically $ return ()
The implementation requires that transactions must not be nested, and this function allows you to nest transactions. Also, it's unclear what "retry" means in the context of arbitrary IO actions. A memory transaction is really only defined for exactly that: memory stuff. When you start talking about user I/O, network, etc. the transactional idea breaks down. So mostly the way I think of it is that it's semantically nonsense. Luke

Hello, John Lato wrote:
I was recently looking at the STM library, and I have a question about the function "unsafeIOToSTM". Can anyone explain to me what is unsafe about it, and what sort of use would be considered "safe"?
it's unsafe to perform IO inside of a transaction as it can't be undone, when rolling it back. I guess, unsafeIOToSTM has been designed in order to allow us to inject debugging output into a transaction, but you really shouldn't use it to perform "real" IO (like writing files, etc.). HTH - Stephan -- Früher hieß es ja: Ich denke, also bin ich. Heute weiß man: Es geht auch so. - Dieter Nuhr

Thanks. Both this answer and Luke's make perfect sense.
John
On Feb 12, 2008 12:41 PM, Stephan Friedrichs
Hello,
John Lato wrote:
I was recently looking at the STM library, and I have a question about the function "unsafeIOToSTM". Can anyone explain to me what is unsafe about it, and what sort of use would be considered "safe"?
it's unsafe to perform IO inside of a transaction as it can't be undone, when rolling it back. I guess, unsafeIOToSTM has been designed in order to allow us to inject debugging output into a transaction, but you really shouldn't use it to perform "real" IO (like writing files, etc.).
HTH - Stephan
--
Früher hieß es ja: Ich denke, also bin ich. Heute weiß man: Es geht auch so.
- Dieter Nuhr

Stephan Friedrichs-2 wrote:
it's unsafe to perform IO inside of a transaction as it can't be undone, when rolling it back. I guess, unsafeIOToSTM has been designed in order to allow us to inject debugging output into a transaction, but you really shouldn't use it to perform "real" IO (like writing files, etc.).
Simon Peyton Jones provides a good example of this in http://research.microsoft.com/~simonpj/papers/stm/beautiful.pdf
atomically (do { x <- readTVar xv ; y <- readTVar yv ; if x>y then launchMissiles else return () })
where launchMissiles :: IO () causes serious international side-effects.
;-) -- Ricardo Guimarães Herrmann "There are only two industries that refer to their customers as 'users'" -- Edward Tufte -- View this message in context: http://www.nabble.com/question-about-STM-and-IO-tp15439579p15481669.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

Hello John, Tuesday, February 12, 2008, 9:28:22 PM, you wrote:
I was recently looking at the STM library, and I have a question about the function "unsafeIOToSTM". Can anyone explain to me what is unsafe about it, and what sort of use would be considered "safe"?
STM operations can be repeated if first transaction was unsuccessful. so, you may se here only operations that may be safely repeated - say, reading/writing memory areas, or reading/writing files, or even sending network message as long as its duplication is ok -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

On 2/20/08, Bulat Ziganshin
STM operations can be repeated if first transaction was unsuccessful. so, you may se here only operations that may be safely repeated - say, reading/writing memory areas, or reading/writing files, or even sending network message as long as its duplication is ok
Actually, you have to be even more careful than that; you may only include not just operations that may be safely repeated, but operations that may be erroneously executed. Consider the following snippet: badNews:: TVar Int -> TVar Int -> IO () badNews xRef yRef = atomically $ do x <- xRef y <- yRef if (x < y) then unsafeIOToSTM launchMissiles else return () (where launchMissiles has serious side effects, but can be called repeatedly without problem; the missiles will already have been launched in the second call). Even if (x < y) is never "atomically" true, launchMissiles could get executed during the evaluation of this STM action if it was run concurrently with another action that wrote new values to x and y in some order, such as the following snippet safe :: TVar Int -> TVar Int -> IO () safe xRef yRef = do atomically $ do writeTVar xRef 15 writeTVar yRef 13 main :: IO () main = do xRef <- newTVar 10 yRef <- newTVar 8 forkIO safe forkIO badNews If "badNews" runs to the point of reading from xRef, then "safe" runs in its entirety and commits successfully, then badNews resumes, launchMissiles will get called and then badNews will fail to commit and be restarted. The second runthrough of badNews will read the values, determine that x >= y, and just return (), but it's too late, the missiles have already been launched. -- ryan

I take it that this follows from the lack of any mechanism to rollback
IO? If so, I think that the following guidelines suffice for when
it's acceptable to use unsafeIOtoSTM:
1. The IO action must be able to be safely repeated.
2. The IO action must be able to be safely performed with
possibly-incorrect arguments, even if it isn't supposed to be
performed.
3. Don't try to nest transactions.
If I understand it correctly, I think that covers it.
Thanks to everyone who answered; I really appreciate it.
John
On Wed, Feb 20, 2008 at 8:02 PM, Ryan Ingram
On 2/20/08, Bulat Ziganshin
wrote: STM operations can be repeated if first transaction was unsuccessful. so, you may se here only operations that may be safely repeated - say, reading/writing memory areas, or reading/writing files, or even sending network message as long as its duplication is ok
Actually, you have to be even more careful than that; you may only include not just operations that may be safely repeated, but operations that may be erroneously executed. Consider the following snippet:

Hello Ryan, Thursday, February 21, 2008, 5:02:52 AM, you wrote:
values, determine that x >= y, and just return (), but it's too late, the missiles have already been launched.
it seems that "asymmetrical answer" of mr.Putin is just to hire a bit more Haskell Hackers :) -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com
participants (6)
-
Bulat Ziganshin
-
John Lato
-
Luke Palmer
-
Ricardo Herrmann
-
Ryan Ingram
-
Stephan Friedrichs