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