That is an extremely interesting story that I would like to understand better. Which pointers would you recommend to read more about mutation in HANSEI?

My intuition would be that the mutation should not be observable in this case, as it is only done on "private" data that the List.map function allocate, owns, and which never escapes in its immutable form. While I understand why mutating global data is an observable side-effect that can play badly with any form of backtracking/probabilistic monad, I do not have any intuition about why mutating a privately-owned heap fragment would perturb the system. If I was pressed to make an hypothesis (while not knowing the system), I would guess that this is because of an implementation detail of HANSEI, not because of its actual semantic requirements.

On Tue, Sep 30, 2014 at 10:46 AM, <oleg@okmij.org> wrote:

Gabriel Scherer wrote
> it is safe to Obj.magic a mutable data-structure into an immutable
> one. The Obj.magic-using code for List.map, implemented in Extlib and
> inherited by Batteries, is careful to use an unsafe cast in exactly
> the second situation. This is a feature that other languages
> (eg. Mezzo) safely provide.

Let me relay a short anecdote about the List.map function in
Batteries. Once I received a message from a person who was using the
Hansei library of probabilistic programming. He reported a problem:
his program produced clearly wrong results. He even traced the problem
to the function 'List.map' -- saying that if he wrote List.map himself,
the problem disappeared. I was initially puzzled: how one can possibly
mis-write List.map. I asked for more details and he said that he was
using Batteries. That gave me a hunch: I went to the Battery
repository to look at the source code and found what I expected --
mutation. In probabilistic programs, mutation has to be done
carefully. Mutation to the global heap forces correlation on what
should be independent ``possible worlds''. Mutation has to be done
with world-local heaps, which Hansei provides for that purpose. There
are times when hidden optimizations come to bite us.

I guess in Mezzo I would have seen from the type that a mutation is
performed, and would have avoided the optimized Map (or the type
checker would make me avoid it).