digitalmars.D - Allow const/immutable for normal functions, inner functions and
- John Colvin (75/75) Feb 19 2014 Good idea/bad idea/already done?
- John Colvin (3/5) Feb 19 2014 Don't want to add any confusion there.
- Timon Gehr (6/44) Feb 19 2014 Does not work as there is no context pointer to qualify and it would add...
- Meta (2/10) Feb 19 2014 Doesn't pure already do this?
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.
Feb 19 2014
On Wednesday, 19 February 2014 at 22:20:45 UTC, John Colvin wrote:e.g. this example using an immutable closure to offloadThat should bee.g. this example using a closure marked immutable to offloadDon't want to add any confusion there.
Feb 19 2014
On 02/19/2014 11:20 PM, John Colvin wrote: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) } ...Does not work as there is no context pointer to qualify and it would add strange limitations to const/... member functions and/or language inconsistencies.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. ...I've brought this up a few times too. This _must_ be done. The current behaviour of DMD is unacceptable here.
Feb 19 2014
On Wednesday, 19 February 2014 at 22:20:45 UTC, John Colvin wrote: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 }Doesn't pure already do this?
Feb 19 2014