Tomek Sowin'ski wrote:
A while ago I pointed out that the result of an immutably pure function (all 
arguments immutable, doesn't mutate globals) can be safely converted to 
immutable. More here:
http://d.puremagic.com/issues/show_bug.cgi?id=5081

It helps with building complex immutable structures. Problem is, virtually 
every construction site is different so one is forced to define a new 
initializer function every time. To illustrate:

void main() {
    immutable Node* init_leaf = ... ;
    uint breadth = ... ;
    immutable Node* tree = grow_tree(init_leaf, breadth);
}

Node* grow_tree(immutable Node* init_leaf, uint breadth) pure {
    Node* root = new Node;
    foreach (0..breadth) {
        Node* leaf = new Node(init_leaf);
        leaf.parent = root;
        root.leaves ~= leaf;
    }
    return root;
}

I tried to find a way to create ad-hoc functions conveniently. Naturally, I 
turned to nested functions:

void main() {
    immutable Node* init_leaf = ... ;
    uint breadth = ... ;
Node* grow_tree() pure immutable {
        Node* root = new Node;
        foreach (0..breadth) {
            Node* leaf = new Node(init_leaf);
            leaf.parent = root;
            root.leaves ~= leaf;
        }
        return root;
    }
immutable Node* tree = grow_tree();
}

Nested functions to be immutably pure must also guarantee that nothing gets 
mutated through its stack frame pointer. But there's a problem -- the compiler 
won't accept 'immutable' on a nested function. I think it should -- just like 
an immutable member function (e.g. in a class) is allowed to play only with 
immutable members of that class, an immutable nested function should be allowed 
to play only with the immutable members of the stack frame. It may seem a 
lesser change but I'm pretty excited as it solves the long-standing problems 
with immutable structure initialization.

Excitement aside, I got questions:

1. I'm proposing to proliferate the concept of immutability from 'this' 
reference to a stack frame pointer. Although I'm confident it makes sense as 
these are interchangeable in delegates, I could use some criticism to either 
reject or strengthen the idea.

2. What about delegates? Should there be means to express a "delegate that doesn't 
mutate through its 'this'/stack frame pointer"? What should the syntax be for 
defining such delegate type and for lambdas (delegate literals)?

3. (vaguely related) Should there be means to express annotated delegates in 
general (e.g. pure, nothrow).

There is.
 int delegate(int) pure square
                = cast( int delegate(int z) pure )
                (int z) { return z*z; };

What about annotated lambdas?

See the line above -- at the moment it requires a cast. Yuck yuck yuck.
The other option would be for the compiler to automatically determine purity. I believe it always has access to the source code of the lambda, so there should be no problem to determine purity.

Reply via email to