Can't Update Mutable Field in Struct?











up vote
1
down vote

favorite












Can anyone tell me why this Counter struct won't work? It always resets the value to 0 between calls to Incr.



type Counter = 
struct

val mutable i: int

member public this.Incr() =
this.i <- this.i + 1

member public this.Count =
this.i
end

let noCounty(s:string): int =
let x = new Counter()
x.Incr()
x.Incr()
x.Count









share|improve this question






















  • Don't do this. :-) I mean do not mutate inside structs. You can if you want to by explicitly making making x mutable.
    – s952163
    Nov 8 at 0:09






  • 1




    I made the counter int mutable? This is a simplified code snippet showing my problem. I need to do this for performance reasons. I'm updating fields as I iterate over millions of 3D points. I don't want to box ints and floats into ref types.
    – EricP
    Nov 8 at 0:19










  • Yes, of course. struct is a value type and is passed by value, hence you need make the value that holds the struct itself mutable, because when you mutate the counter you also mutate the whole struct.
    – s952163
    Nov 8 at 0:24















up vote
1
down vote

favorite












Can anyone tell me why this Counter struct won't work? It always resets the value to 0 between calls to Incr.



type Counter = 
struct

val mutable i: int

member public this.Incr() =
this.i <- this.i + 1

member public this.Count =
this.i
end

let noCounty(s:string): int =
let x = new Counter()
x.Incr()
x.Incr()
x.Count









share|improve this question






















  • Don't do this. :-) I mean do not mutate inside structs. You can if you want to by explicitly making making x mutable.
    – s952163
    Nov 8 at 0:09






  • 1




    I made the counter int mutable? This is a simplified code snippet showing my problem. I need to do this for performance reasons. I'm updating fields as I iterate over millions of 3D points. I don't want to box ints and floats into ref types.
    – EricP
    Nov 8 at 0:19










  • Yes, of course. struct is a value type and is passed by value, hence you need make the value that holds the struct itself mutable, because when you mutate the counter you also mutate the whole struct.
    – s952163
    Nov 8 at 0:24













up vote
1
down vote

favorite









up vote
1
down vote

favorite











Can anyone tell me why this Counter struct won't work? It always resets the value to 0 between calls to Incr.



type Counter = 
struct

val mutable i: int

member public this.Incr() =
this.i <- this.i + 1

member public this.Count =
this.i
end

let noCounty(s:string): int =
let x = new Counter()
x.Incr()
x.Incr()
x.Count









share|improve this question













Can anyone tell me why this Counter struct won't work? It always resets the value to 0 between calls to Incr.



type Counter = 
struct

val mutable i: int

member public this.Incr() =
this.i <- this.i + 1

member public this.Count =
this.i
end

let noCounty(s:string): int =
let x = new Counter()
x.Incr()
x.Incr()
x.Count






struct f# mutable






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 7 at 22:01









EricP

455




455












  • Don't do this. :-) I mean do not mutate inside structs. You can if you want to by explicitly making making x mutable.
    – s952163
    Nov 8 at 0:09






  • 1




    I made the counter int mutable? This is a simplified code snippet showing my problem. I need to do this for performance reasons. I'm updating fields as I iterate over millions of 3D points. I don't want to box ints and floats into ref types.
    – EricP
    Nov 8 at 0:19










  • Yes, of course. struct is a value type and is passed by value, hence you need make the value that holds the struct itself mutable, because when you mutate the counter you also mutate the whole struct.
    – s952163
    Nov 8 at 0:24


















  • Don't do this. :-) I mean do not mutate inside structs. You can if you want to by explicitly making making x mutable.
    – s952163
    Nov 8 at 0:09






  • 1




    I made the counter int mutable? This is a simplified code snippet showing my problem. I need to do this for performance reasons. I'm updating fields as I iterate over millions of 3D points. I don't want to box ints and floats into ref types.
    – EricP
    Nov 8 at 0:19










  • Yes, of course. struct is a value type and is passed by value, hence you need make the value that holds the struct itself mutable, because when you mutate the counter you also mutate the whole struct.
    – s952163
    Nov 8 at 0:24
















Don't do this. :-) I mean do not mutate inside structs. You can if you want to by explicitly making making x mutable.
– s952163
Nov 8 at 0:09




Don't do this. :-) I mean do not mutate inside structs. You can if you want to by explicitly making making x mutable.
– s952163
Nov 8 at 0:09




1




1




I made the counter int mutable? This is a simplified code snippet showing my problem. I need to do this for performance reasons. I'm updating fields as I iterate over millions of 3D points. I don't want to box ints and floats into ref types.
– EricP
Nov 8 at 0:19




I made the counter int mutable? This is a simplified code snippet showing my problem. I need to do this for performance reasons. I'm updating fields as I iterate over millions of 3D points. I don't want to box ints and floats into ref types.
– EricP
Nov 8 at 0:19












Yes, of course. struct is a value type and is passed by value, hence you need make the value that holds the struct itself mutable, because when you mutate the counter you also mutate the whole struct.
– s952163
Nov 8 at 0:24




Yes, of course. struct is a value type and is passed by value, hence you need make the value that holds the struct itself mutable, because when you mutate the counter you also mutate the whole struct.
– s952163
Nov 8 at 0:24












3 Answers
3






active

oldest

votes

















up vote
2
down vote



accepted










The semantics of mutable structs is always confusing, because there are situations where the struct is unexpectedly copied when you use it in certain ways - so it is a good idea to avoid mutation inside structs.



You can make this work by marking the x variable inside noCounty mutable. Given your current definition of Counter, the following works as expected:



let noCounty() = 
let mutable x = new Counter()
x.Incr()
x.Incr()
x.Count


I agree this is pretty confusing. I think the logic is that if you define the variable as immutable, then the compiler copies the value of the struct into a new variable before making any call that might mutate it. As a result, the compiled code looks more like:



let noCounty () = 
let x = new Counter()
(let t1 = x in t1.Incr())
(let t2 = x in t2.Incr())
(let t3 = x in t3.Count)


I would expect the compiler to give me some warning about this - so perhaps the lack of warning in this case should be reported as a compiler bug. (Though the behaviour is probably intended.)






share|improve this answer

















  • 1




    I thought I was doing something wrong, but ILSpy confirmed this. If it sees any mutable member (even internal), it silently clones the variable. I may have to abort using F#. I'll be using commercial libraries written in c# and can't have method calls triggering a silent duplication of large 3D meshes.
    – EricP
    Nov 8 at 1:03






  • 1




    @EricP If you mark the variable as mutable, then there is no silent duplication. Also, if you have large 3D meshes, then they are presumably stored in an array (or something like that), so they'll be heap allocated anyway (and even if the struct that stores the reference was duplicated, the mesh itself would not...).
    – Tomas Petricek
    Nov 8 at 1:13






  • 1




    If you set the warning level to 5 or activate warnon 52 the compiler will warn you about defensive copying.
    – CaringDev
    Nov 8 at 7:48










  • @TomasPetricek Thank you. F# being immutable is now less mysterious. I was worried that arrays were immutable, but no reference types are. I changed the Counter definition to a class and the caller did not have to specify mutable for it to work. This raises the question of why all the talk about immutability and thread safety benefits of F#. .NET defaults that params are passed by val. I'm seeing it as a pointless set of local rules for val types and an interesting OO pattern of read-only, linked objects everywhere else.
    – EricP
    Nov 8 at 19:18










  • @EricP That's a topic for much longer explanation :-). There are two concepts - immutable objects and immutable variables. Immutable objects are much more important than immutable variables.
    – Tomas Petricek
    Nov 8 at 21:31


















up vote
1
down vote













I do not know why it does not work the way you have it, but it works this way:



type Counter() = 
[<DefaultValue>]
val mutable i: int

member public this.Incr() =
this.i <- this.i + 1

member public this.Count =
this.i





share|improve this answer

















  • 1




    This is slightly different though, this is a class not a struct.
    – s952163
    Nov 8 at 0:08


















up vote
0
down vote













If you really want to do this, you can:



[<Struct>]
type Counter =
val mutable i: int

member public this.Incr() =
this.i <- this.i + 1

member public this.Count =
this.i

let mutable x = Counter() // You need to make the struct itself mutable
x.Incr()
x.Incr()
x.Count
//val it : int = 2


To be honest, the compiler should complain about this behavior. While it's not a good idea to mutate in general, and in structs specifically; you can, but you need to make the x itself mutable, because you are changing the struct itself, which is a value type. The other answer gives you a class, which is a reference type.






share|improve this answer





















    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














     

    draft saved


    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53198513%2fcant-update-mutable-field-in-struct%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    2
    down vote



    accepted










    The semantics of mutable structs is always confusing, because there are situations where the struct is unexpectedly copied when you use it in certain ways - so it is a good idea to avoid mutation inside structs.



    You can make this work by marking the x variable inside noCounty mutable. Given your current definition of Counter, the following works as expected:



    let noCounty() = 
    let mutable x = new Counter()
    x.Incr()
    x.Incr()
    x.Count


    I agree this is pretty confusing. I think the logic is that if you define the variable as immutable, then the compiler copies the value of the struct into a new variable before making any call that might mutate it. As a result, the compiled code looks more like:



    let noCounty () = 
    let x = new Counter()
    (let t1 = x in t1.Incr())
    (let t2 = x in t2.Incr())
    (let t3 = x in t3.Count)


    I would expect the compiler to give me some warning about this - so perhaps the lack of warning in this case should be reported as a compiler bug. (Though the behaviour is probably intended.)






    share|improve this answer

















    • 1




      I thought I was doing something wrong, but ILSpy confirmed this. If it sees any mutable member (even internal), it silently clones the variable. I may have to abort using F#. I'll be using commercial libraries written in c# and can't have method calls triggering a silent duplication of large 3D meshes.
      – EricP
      Nov 8 at 1:03






    • 1




      @EricP If you mark the variable as mutable, then there is no silent duplication. Also, if you have large 3D meshes, then they are presumably stored in an array (or something like that), so they'll be heap allocated anyway (and even if the struct that stores the reference was duplicated, the mesh itself would not...).
      – Tomas Petricek
      Nov 8 at 1:13






    • 1




      If you set the warning level to 5 or activate warnon 52 the compiler will warn you about defensive copying.
      – CaringDev
      Nov 8 at 7:48










    • @TomasPetricek Thank you. F# being immutable is now less mysterious. I was worried that arrays were immutable, but no reference types are. I changed the Counter definition to a class and the caller did not have to specify mutable for it to work. This raises the question of why all the talk about immutability and thread safety benefits of F#. .NET defaults that params are passed by val. I'm seeing it as a pointless set of local rules for val types and an interesting OO pattern of read-only, linked objects everywhere else.
      – EricP
      Nov 8 at 19:18










    • @EricP That's a topic for much longer explanation :-). There are two concepts - immutable objects and immutable variables. Immutable objects are much more important than immutable variables.
      – Tomas Petricek
      Nov 8 at 21:31















    up vote
    2
    down vote



    accepted










    The semantics of mutable structs is always confusing, because there are situations where the struct is unexpectedly copied when you use it in certain ways - so it is a good idea to avoid mutation inside structs.



    You can make this work by marking the x variable inside noCounty mutable. Given your current definition of Counter, the following works as expected:



    let noCounty() = 
    let mutable x = new Counter()
    x.Incr()
    x.Incr()
    x.Count


    I agree this is pretty confusing. I think the logic is that if you define the variable as immutable, then the compiler copies the value of the struct into a new variable before making any call that might mutate it. As a result, the compiled code looks more like:



    let noCounty () = 
    let x = new Counter()
    (let t1 = x in t1.Incr())
    (let t2 = x in t2.Incr())
    (let t3 = x in t3.Count)


    I would expect the compiler to give me some warning about this - so perhaps the lack of warning in this case should be reported as a compiler bug. (Though the behaviour is probably intended.)






    share|improve this answer

















    • 1




      I thought I was doing something wrong, but ILSpy confirmed this. If it sees any mutable member (even internal), it silently clones the variable. I may have to abort using F#. I'll be using commercial libraries written in c# and can't have method calls triggering a silent duplication of large 3D meshes.
      – EricP
      Nov 8 at 1:03






    • 1




      @EricP If you mark the variable as mutable, then there is no silent duplication. Also, if you have large 3D meshes, then they are presumably stored in an array (or something like that), so they'll be heap allocated anyway (and even if the struct that stores the reference was duplicated, the mesh itself would not...).
      – Tomas Petricek
      Nov 8 at 1:13






    • 1




      If you set the warning level to 5 or activate warnon 52 the compiler will warn you about defensive copying.
      – CaringDev
      Nov 8 at 7:48










    • @TomasPetricek Thank you. F# being immutable is now less mysterious. I was worried that arrays were immutable, but no reference types are. I changed the Counter definition to a class and the caller did not have to specify mutable for it to work. This raises the question of why all the talk about immutability and thread safety benefits of F#. .NET defaults that params are passed by val. I'm seeing it as a pointless set of local rules for val types and an interesting OO pattern of read-only, linked objects everywhere else.
      – EricP
      Nov 8 at 19:18










    • @EricP That's a topic for much longer explanation :-). There are two concepts - immutable objects and immutable variables. Immutable objects are much more important than immutable variables.
      – Tomas Petricek
      Nov 8 at 21:31













    up vote
    2
    down vote



    accepted







    up vote
    2
    down vote



    accepted






    The semantics of mutable structs is always confusing, because there are situations where the struct is unexpectedly copied when you use it in certain ways - so it is a good idea to avoid mutation inside structs.



    You can make this work by marking the x variable inside noCounty mutable. Given your current definition of Counter, the following works as expected:



    let noCounty() = 
    let mutable x = new Counter()
    x.Incr()
    x.Incr()
    x.Count


    I agree this is pretty confusing. I think the logic is that if you define the variable as immutable, then the compiler copies the value of the struct into a new variable before making any call that might mutate it. As a result, the compiled code looks more like:



    let noCounty () = 
    let x = new Counter()
    (let t1 = x in t1.Incr())
    (let t2 = x in t2.Incr())
    (let t3 = x in t3.Count)


    I would expect the compiler to give me some warning about this - so perhaps the lack of warning in this case should be reported as a compiler bug. (Though the behaviour is probably intended.)






    share|improve this answer












    The semantics of mutable structs is always confusing, because there are situations where the struct is unexpectedly copied when you use it in certain ways - so it is a good idea to avoid mutation inside structs.



    You can make this work by marking the x variable inside noCounty mutable. Given your current definition of Counter, the following works as expected:



    let noCounty() = 
    let mutable x = new Counter()
    x.Incr()
    x.Incr()
    x.Count


    I agree this is pretty confusing. I think the logic is that if you define the variable as immutable, then the compiler copies the value of the struct into a new variable before making any call that might mutate it. As a result, the compiled code looks more like:



    let noCounty () = 
    let x = new Counter()
    (let t1 = x in t1.Incr())
    (let t2 = x in t2.Incr())
    (let t3 = x in t3.Count)


    I would expect the compiler to give me some warning about this - so perhaps the lack of warning in this case should be reported as a compiler bug. (Though the behaviour is probably intended.)







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 8 at 0:13









    Tomas Petricek

    197k13285458




    197k13285458








    • 1




      I thought I was doing something wrong, but ILSpy confirmed this. If it sees any mutable member (even internal), it silently clones the variable. I may have to abort using F#. I'll be using commercial libraries written in c# and can't have method calls triggering a silent duplication of large 3D meshes.
      – EricP
      Nov 8 at 1:03






    • 1




      @EricP If you mark the variable as mutable, then there is no silent duplication. Also, if you have large 3D meshes, then they are presumably stored in an array (or something like that), so they'll be heap allocated anyway (and even if the struct that stores the reference was duplicated, the mesh itself would not...).
      – Tomas Petricek
      Nov 8 at 1:13






    • 1




      If you set the warning level to 5 or activate warnon 52 the compiler will warn you about defensive copying.
      – CaringDev
      Nov 8 at 7:48










    • @TomasPetricek Thank you. F# being immutable is now less mysterious. I was worried that arrays were immutable, but no reference types are. I changed the Counter definition to a class and the caller did not have to specify mutable for it to work. This raises the question of why all the talk about immutability and thread safety benefits of F#. .NET defaults that params are passed by val. I'm seeing it as a pointless set of local rules for val types and an interesting OO pattern of read-only, linked objects everywhere else.
      – EricP
      Nov 8 at 19:18










    • @EricP That's a topic for much longer explanation :-). There are two concepts - immutable objects and immutable variables. Immutable objects are much more important than immutable variables.
      – Tomas Petricek
      Nov 8 at 21:31














    • 1




      I thought I was doing something wrong, but ILSpy confirmed this. If it sees any mutable member (even internal), it silently clones the variable. I may have to abort using F#. I'll be using commercial libraries written in c# and can't have method calls triggering a silent duplication of large 3D meshes.
      – EricP
      Nov 8 at 1:03






    • 1




      @EricP If you mark the variable as mutable, then there is no silent duplication. Also, if you have large 3D meshes, then they are presumably stored in an array (or something like that), so they'll be heap allocated anyway (and even if the struct that stores the reference was duplicated, the mesh itself would not...).
      – Tomas Petricek
      Nov 8 at 1:13






    • 1




      If you set the warning level to 5 or activate warnon 52 the compiler will warn you about defensive copying.
      – CaringDev
      Nov 8 at 7:48










    • @TomasPetricek Thank you. F# being immutable is now less mysterious. I was worried that arrays were immutable, but no reference types are. I changed the Counter definition to a class and the caller did not have to specify mutable for it to work. This raises the question of why all the talk about immutability and thread safety benefits of F#. .NET defaults that params are passed by val. I'm seeing it as a pointless set of local rules for val types and an interesting OO pattern of read-only, linked objects everywhere else.
      – EricP
      Nov 8 at 19:18










    • @EricP That's a topic for much longer explanation :-). There are two concepts - immutable objects and immutable variables. Immutable objects are much more important than immutable variables.
      – Tomas Petricek
      Nov 8 at 21:31








    1




    1




    I thought I was doing something wrong, but ILSpy confirmed this. If it sees any mutable member (even internal), it silently clones the variable. I may have to abort using F#. I'll be using commercial libraries written in c# and can't have method calls triggering a silent duplication of large 3D meshes.
    – EricP
    Nov 8 at 1:03




    I thought I was doing something wrong, but ILSpy confirmed this. If it sees any mutable member (even internal), it silently clones the variable. I may have to abort using F#. I'll be using commercial libraries written in c# and can't have method calls triggering a silent duplication of large 3D meshes.
    – EricP
    Nov 8 at 1:03




    1




    1




    @EricP If you mark the variable as mutable, then there is no silent duplication. Also, if you have large 3D meshes, then they are presumably stored in an array (or something like that), so they'll be heap allocated anyway (and even if the struct that stores the reference was duplicated, the mesh itself would not...).
    – Tomas Petricek
    Nov 8 at 1:13




    @EricP If you mark the variable as mutable, then there is no silent duplication. Also, if you have large 3D meshes, then they are presumably stored in an array (or something like that), so they'll be heap allocated anyway (and even if the struct that stores the reference was duplicated, the mesh itself would not...).
    – Tomas Petricek
    Nov 8 at 1:13




    1




    1




    If you set the warning level to 5 or activate warnon 52 the compiler will warn you about defensive copying.
    – CaringDev
    Nov 8 at 7:48




    If you set the warning level to 5 or activate warnon 52 the compiler will warn you about defensive copying.
    – CaringDev
    Nov 8 at 7:48












    @TomasPetricek Thank you. F# being immutable is now less mysterious. I was worried that arrays were immutable, but no reference types are. I changed the Counter definition to a class and the caller did not have to specify mutable for it to work. This raises the question of why all the talk about immutability and thread safety benefits of F#. .NET defaults that params are passed by val. I'm seeing it as a pointless set of local rules for val types and an interesting OO pattern of read-only, linked objects everywhere else.
    – EricP
    Nov 8 at 19:18




    @TomasPetricek Thank you. F# being immutable is now less mysterious. I was worried that arrays were immutable, but no reference types are. I changed the Counter definition to a class and the caller did not have to specify mutable for it to work. This raises the question of why all the talk about immutability and thread safety benefits of F#. .NET defaults that params are passed by val. I'm seeing it as a pointless set of local rules for val types and an interesting OO pattern of read-only, linked objects everywhere else.
    – EricP
    Nov 8 at 19:18












    @EricP That's a topic for much longer explanation :-). There are two concepts - immutable objects and immutable variables. Immutable objects are much more important than immutable variables.
    – Tomas Petricek
    Nov 8 at 21:31




    @EricP That's a topic for much longer explanation :-). There are two concepts - immutable objects and immutable variables. Immutable objects are much more important than immutable variables.
    – Tomas Petricek
    Nov 8 at 21:31












    up vote
    1
    down vote













    I do not know why it does not work the way you have it, but it works this way:



    type Counter() = 
    [<DefaultValue>]
    val mutable i: int

    member public this.Incr() =
    this.i <- this.i + 1

    member public this.Count =
    this.i





    share|improve this answer

















    • 1




      This is slightly different though, this is a class not a struct.
      – s952163
      Nov 8 at 0:08















    up vote
    1
    down vote













    I do not know why it does not work the way you have it, but it works this way:



    type Counter() = 
    [<DefaultValue>]
    val mutable i: int

    member public this.Incr() =
    this.i <- this.i + 1

    member public this.Count =
    this.i





    share|improve this answer

















    • 1




      This is slightly different though, this is a class not a struct.
      – s952163
      Nov 8 at 0:08













    up vote
    1
    down vote










    up vote
    1
    down vote









    I do not know why it does not work the way you have it, but it works this way:



    type Counter() = 
    [<DefaultValue>]
    val mutable i: int

    member public this.Incr() =
    this.i <- this.i + 1

    member public this.Count =
    this.i





    share|improve this answer












    I do not know why it does not work the way you have it, but it works this way:



    type Counter() = 
    [<DefaultValue>]
    val mutable i: int

    member public this.Incr() =
    this.i <- this.i + 1

    member public this.Count =
    this.i






    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 7 at 22:31









    AMieres

    1,40647




    1,40647








    • 1




      This is slightly different though, this is a class not a struct.
      – s952163
      Nov 8 at 0:08














    • 1




      This is slightly different though, this is a class not a struct.
      – s952163
      Nov 8 at 0:08








    1




    1




    This is slightly different though, this is a class not a struct.
    – s952163
    Nov 8 at 0:08




    This is slightly different though, this is a class not a struct.
    – s952163
    Nov 8 at 0:08










    up vote
    0
    down vote













    If you really want to do this, you can:



    [<Struct>]
    type Counter =
    val mutable i: int

    member public this.Incr() =
    this.i <- this.i + 1

    member public this.Count =
    this.i

    let mutable x = Counter() // You need to make the struct itself mutable
    x.Incr()
    x.Incr()
    x.Count
    //val it : int = 2


    To be honest, the compiler should complain about this behavior. While it's not a good idea to mutate in general, and in structs specifically; you can, but you need to make the x itself mutable, because you are changing the struct itself, which is a value type. The other answer gives you a class, which is a reference type.






    share|improve this answer

























      up vote
      0
      down vote













      If you really want to do this, you can:



      [<Struct>]
      type Counter =
      val mutable i: int

      member public this.Incr() =
      this.i <- this.i + 1

      member public this.Count =
      this.i

      let mutable x = Counter() // You need to make the struct itself mutable
      x.Incr()
      x.Incr()
      x.Count
      //val it : int = 2


      To be honest, the compiler should complain about this behavior. While it's not a good idea to mutate in general, and in structs specifically; you can, but you need to make the x itself mutable, because you are changing the struct itself, which is a value type. The other answer gives you a class, which is a reference type.






      share|improve this answer























        up vote
        0
        down vote










        up vote
        0
        down vote









        If you really want to do this, you can:



        [<Struct>]
        type Counter =
        val mutable i: int

        member public this.Incr() =
        this.i <- this.i + 1

        member public this.Count =
        this.i

        let mutable x = Counter() // You need to make the struct itself mutable
        x.Incr()
        x.Incr()
        x.Count
        //val it : int = 2


        To be honest, the compiler should complain about this behavior. While it's not a good idea to mutate in general, and in structs specifically; you can, but you need to make the x itself mutable, because you are changing the struct itself, which is a value type. The other answer gives you a class, which is a reference type.






        share|improve this answer












        If you really want to do this, you can:



        [<Struct>]
        type Counter =
        val mutable i: int

        member public this.Incr() =
        this.i <- this.i + 1

        member public this.Count =
        this.i

        let mutable x = Counter() // You need to make the struct itself mutable
        x.Incr()
        x.Incr()
        x.Count
        //val it : int = 2


        To be honest, the compiler should complain about this behavior. While it's not a good idea to mutate in general, and in structs specifically; you can, but you need to make the x itself mutable, because you are changing the struct itself, which is a value type. The other answer gives you a class, which is a reference type.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 8 at 0:17









        s952163

        5,02531740




        5,02531740






























             

            draft saved


            draft discarded



















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53198513%2fcant-update-mutable-field-in-struct%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            這個網誌中的熱門文章

            Post-Redirect-Get with Spring WebFlux and Thymeleaf

            Xamarin.form Move up view when keyboard appear

            JBPM : POST request for execute process go wrong