Allow const/immutable for normal functions, inner functions and delegates?

John Colvin john.loughran.colvin at gmail.com
Wed Feb 19 14:20:44 PST 2014


Good idea/bad idea/already done?

int ga = 1;
const int gb = 2;
immutable int gc = 3;

int foo() immutable
{
     // reference to gc is legal
     // any reference to ga or ba is an error
}
int bar() const
{
     // reference to ga, gb and gc is legal
     // cannot modify ga (or gb or gc, obviously)
}

void main()
{
     int a = 1;
     const int b = 2;
     immutable int c = 3;

     int innerFoo() immutable
     {
         // reference to c or gc is legal
         // any reference to a, ga, b or ba is an error
     }
     int innerBar() const
     {
         // reference to a, ga, b, gb c and gc is legal
         // cannot modify a or ga
     }
}

For the inner functions, it's as if the const/immutable is 
applied to the context pointer, the same as it is applied to 
"this" in a class/struct method.

This would be useful because it:
a) provides better control over the exact behaviour of functions 
w.r.t. global/outer state.

b) More importantly: functions/delegates marked immutable can be 
freely shared across threads! This could enable some cool stuff

e.g. this example using an immutable closure to offload work to a 
worker without any explicit handling of input data in the worker 
thread:

auto makeJob(int i, int[] arr)
{
     auto arrImm = arr.idup;
     immutable int iImm = i;

     int[] inner() immutable
     {
         return arr.map!((x) => x % iImm).array;
     }
     return &inner;
}

void worker(Tid tid)
{
     receive(
         (int[] delegate() work)
         {
             tid.send(work());
         }
     );
};

void main()
{
     auto tid = spawn(&worker, thisTid);

     tid.send(makeJob(3, [1,2,3,4,5]));
     receive(
         (int[] data)
         {
             assert(data == [1,2,0,1,2]);
         }
     );
}

All the worker needs to know about its workload is the return 
type of the delegate :) Batteries included!

Note: functions marked immutable are implicitly pure, allowing 
their return values to be implicitly cast to immutable.


More information about the Digitalmars-d mailing list