Heinrich Apfelmus <apfelmus at quantentunnel.de> wrote:
> In particular, the World -> (a,World) model is unsuitable even without
> concurrency because it cannot distinguish
>> loop, loop' :: IO ()
> loop = loop
> loop' = putStr "c" >> loop'
>> I interpret the "EDSL model" to be the operational semantics presented
> in the tutorial paper.
Huh?! Let's translate them. 'loop' becomes:
undefined
But 'loop\'' becomes:
\w0 -> let (w1, ()) = putStr "c" w0
in loop w1
Because this program runs forever it makes no sense to ask what its
result is after the program is run, but that's evaluation semantics.
Semantically they are both undefined. But execution is something
separate and there is no Haskell notion for it. In particular execution
is /not/ evaluation, and the program's monadic result is not related to
the world state. There is nothing wrong with it being undefined. You
could even have:
type RealWorld = [WorldRevision]
You can view execution as the transition from one state to the next, or
in other words: Each time a new world value pops up, this is the
current world's state. Old revisions of the world may be kept, because
of late garbage collection, but only the most recent revision is the
current state of the world. If you take RealWorld to be a list (at
which point the two loops above /may/ be semantically different), then
it's something like a movie of world revisions.
The only thing which this model really cannot capture is that of
premature exit of the program. However, you can change it to:
type IO = ContT RealWorld (State RealWorld)
which would even invalidate the above statement that the two loops can't
be distinguished. At that point it would even capture exceptions.
Greets,
Ertugrul
--
nightmare = unsafePerformIO (getWrongWife >>= sex)
http://ertes.de/