Immutable nested functions

Tomek Sowiński just at ask.me
Tue Jan 4 13:23:43 PST 2011


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). What about annotated lambdas?

-- 
Tomek


More information about the Digitalmars-d mailing list