On Sat, May 10, 2008 at 10:51 AM, Richard Jones <rich@annexia.org> wrote:

> As you cannot mutate anything that is ancient (since it might be
> concurrently
> accessed),

There are various restrictions on mutating the ancient data, which are
explained in the README.  It is not true that ancient data is
completely immutable, just that you really need to understand what
you're doing in order to do it correctly.

I'm not talking of mutating atomic values here.

I'm saying that you certainly can't have the GC or someone else mutate the data for
traversal purposes.
 
 There are additional
restrictions to mutating [any] data concurrently, but I didn't explain
those because they are obvious, and can be solved with standard
threading techniques (mutexes, etc.)..

> you cannot mark or modify them in-place for ad-hoc marshalling or
> deep copying.  Is that correct?

I'm not sure what this means.  I haven't tried to Marshal ancient
data, because ancient data can already be persisted, so marshaling it
doesn't make much sense.
'Deep copying' of ancient data can be done just like deep copying any
other OCaml value.

As in: it can't be done polymorphically, unless you resort to Marshal, which
doesn't work on ancient data.
 
> Comparison does not mark (and thus does not work on cyclic structures).
> Does it work on values in the ancient heap (I'm not talking of handles
> here)?

Your use of 'value', 'handle' etc. is confusing me.

By handle I meant values behind of type 'a ancient.
 
I suggest you
take a look at how OCaml values are stored (eg. <caml/mlvalues.h> is a
good place to start).

I suggest you look at extern.c & intern.c to see how Ocaml values are marshalled.
A joke of course, I assume you already know.

Anyhow, the polymorphic primitives (like %compare) don't work, just
because they make the assumption that anything outside the normal
OCaml heap is incomparable

And that can be quite annoying, so we'd like a way to take values of out
the ancient heap.
 
, but you can certainly write your own
comparison functions to replace those, eg. comparing
character-by-character for strings.

Not. Polymorphic.
 
This has nothing to do with 'marking'.

Well, walking over a value graph, either for complete hashing/comparison/copying or
serialization requires marking unless your graph is a tree.

> So it seems that adding a generic copy-out-of-the-ancient heap function
> (which marks in a private area) would be worthwhile.  Should not be too
> difficult.

As I said earlier, you can just copy values from the ancient heap as
you would any other value, eg. using { ... with ... } syntax or
Array.copy / String.copy etc.

That is not polymorphic.

Let's say this again.  Values on the ancient heap look just like
values anywhere else in the program.  You can pass them to functions,
print them out, add them up, do whatever else you would normally do,
with very few restrictions.  The differences are:

 - the polymorphic primitives don't work (so you can't compare or hash them)

That's very annoying for what I had in mind: communication for concurrency.
 
  - they don't get garbage collected
 
Again, if you want to store an ancient value in a new one, you're toast.

- you should be very careful about mutating them

That I can understand.  Something like

  val Ancient.get : int -> 'a(immutable)

would have been nice.

--
Berke