Immutable nested functions
Robert Jacques
sandford at jhu.edu
Fri Jan 7 17:19:48 PST 2011
On Fri, 07 Jan 2011 17:18:39 -0500, Don <nospam at nospam.com> wrote:
> 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.
Umm... int delegate(int) pure square = delegate(int z) pure { return
z*z; }; compiles and runs fine. What doesn't compile is (int z) pure {
return z*z; }; or anything similar.
More information about the Digitalmars-d
mailing list