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