Andrei Alexandrescu via Digitalmars-d
digitalmars-d at puremagic.com
Fri Nov 13 15:10:04 PST 2015
I created a simple persistent list with reference counting and custom
allocation at http://dpaste.dzfl.pl/0981640c2835. It's a good
illustration of a number of issues. In particular, each cast must be
Here's my exegesis:
* Lines 6: By construction the list doesn't work with mutable objects.
This is because it uses sharing internally (in the classic manner of
functional containers) to give the illusion of many copies.
* Lines 11-12: I came to terms with the notion that some types cannot be
made immutable. We've been trying to do reference counting on immutable
objects for a long time. It's time to acknowledge that true immutability
(which the immutable keyword models) and reference counting don't mix.
Const does work (more below). But overall I'm at peace with the notion
that if you can't live without immutable, I'll refer you to the garbage
* Lines 26-29: The allocator is fundamentally a mutable part of the
container. This is an insufficiency of our type system - we can't say
"this object may be constant, but this reference is to a mutable part of
it". We can't explain that necessity out of existence, and List is part
of the proof. So we need to make that cast legal.
One simple solution is to simply allow the cast. One more involved is to
define an attribute @mutable with the following rules: (a) @mutable data
is not affected by const; (b) if a type T contains transitively any
@mutable member, immutable(T) is illegal. That would allow us to not
need a cast in line 28.
* Line 35: the constness of the Node is taken away before deallocation.
This is acceptable.
* Lines 40, 46: same matter as with the allocator - the reference count
is a mutable part of a possibly const object.
* Line 65: deallocation again is allowed to cast things, even in safe
code; the point here is we know we can do something the type system
* Lines 104-112: using recursion in the construction of objects with
const parts is, I think, a major emerging idiom in D.
* Lines 141-152: I couldn't make tail() work with inout. Generally I'm
very unhappy about inout. I don't know how to use it. Everything I read
about it is extremely complicated compared to its power. I wish we
removed it from the language and replaced it with an understandable idiom.
* Lines 161-185: Same problem: inout.
* Lines 191-199: Same problem: inout.
* Lines 208-259: I made inout work for getting the range of the list.
Please reply with improvements, ideas, comments, and such. Thanks!
More information about the Digitalmars-d