.net - What is the difference between member val and member this in F#? -
when created class containing generic, mutable .net stack in f# example below, stack ignores push onto it.
open system.collections.generic type interp(code: int array) = member val pc = 0 get, set member this.stack: stack<int> = new stack<int>() member this.code = code let interp = interp([|1;2;3|]) interp.stack.push(1) printfn "%a" interp.stack // prints "seq[]" wat?!
yet if make stack mutable via property:
open system.collections.generic type interp(code: int array) = member val pc = 0 get, set member val stack: stack<int> = new stack<int>() get, set member this.code = code let interp = interp([|1;2;3|]) interp.stack.push(1) printfn "%a" interp.stack // prints "seq[1]"
everything magically works i'd expect.
what on earth going on here? understanding of immutability previous languages (c# mostly) though stack in first example immutable member, immutablity should go far reference (aka shouldn't able reassign stack itself). should still able push values to/from it. missing, , if trying mutate stack wrong thing, why doesn't throw exception or compile error?
if try compile first version, , use e.g. reflector decompile c#, you'll see stack member defined this:
public class interp { public stack<int> stack { { return new stack<int>(); } } // other members omitted clarity... }
as can see, valid c# code, not want.
the second version cross-compiles this:
public class interp { internal int[] code; internal stack<int> stack@; public interp(int[] code) : this() { this.code = code; this.stack@ = new stack<int>(); } public stack<int> stack { { return this.stack@; } set { this.stack@ = value; } } // other members omitted clarity... }
this seems more you'd want property do.
Comments
Post a Comment