On Thursday, 20 December 2012 at 02:29:09 UTC, Jonathan M Davis
wrote:
On Thursday, December 20, 2012 03:19:17 bearophile wrote:
Jonathan M Davis:
> The problem is casting. It's not uncommon to create something
> as mutable and
> then cast it to immutable when done. It's stuff like that
> screws with being
> able to per-thread GCs. Which thread owns what isn't always
> clear.
I nearly never cast mutables to immutable. The purpose of casts
is to subvert the type system. If you accept that some type
system assumption doesn't hold just because casts exist, then
you
are doomed to ignore every kind of type system assumption, like
immutability, safety, purity, nothrowness, and so on. And this
is
so wrong. So I can't accept your justification that the
existence
casts disallow per-thread GCs. Do not use cast that way, and
give
us a "better" GC.
It's perfectly legal to cast from mutable to immutable. You
just have to make
sure that you don't have any other references to that data. In
many cases,
it's the only way to get an immutable version of an object
(e.g. if you wanted
an immutable AA). There's even a helper function for this in
the standard
library: std.exception.assumeUnique. There's no way that this
is going away,
and the GC is going to have to take that into account with
however it works.
It may still be possible to have a per-thread GC, but it
definitely complicates
things.
Casting to and from shared has similar issues and happens for
similar reasons.
And such casts are essentially forced by std.concurrency. So,
you're overly
optimistic if you think that the GC can ignore such casts. It
must take them
into account in whatever it does.
I think the right way to do that is to actually clone the object.
You can argue that is a performance cost, but considering the
implication on the GC, I'm pretty sure it is a win.
Another way to do it safely is to use pure function, but it
require that notion of isolated island, and as much as I love the
idea, I won't be in favor of introducing it right now into D.