Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mutable contents in Anonymous Records #732

Open
5 tasks done
cartermp opened this issue Apr 6, 2019 · 5 comments
Open
5 tasks done

Mutable contents in Anonymous Records #732

cartermp opened this issue Apr 6, 2019 · 5 comments

Comments

@cartermp
Copy link
Member

cartermp commented Apr 6, 2019

I propose we allow for mutable contents in F# anonymous records. Today, it is not possible either as a declaration expression or when creating a new anonymous record:

image

(Note that the syntax in the screenshot is not necessarily what the syntax should be, it's just what felt the most natural to me)

Syntax could look like this:

// Declaration
let f (r: {| mutable Doot: string |})  = ()

// Instantiation
let _ = {| mutable Yoder: flat |}

This would be analogous to mutable contents in regular F# records.

The spec does not mention mutable labels, hence this suggestion.

You can have a type be a ref cell today, so you can still mutate:

image

However this does incur the additional allocation and readability costs of references cells.

Pros and Cons

The advantages of making this adjustment to F# are:

  • More parity with record types
  • No more need to use ref cells if this is the pattern you're using

The disadvantages of making this adjustment to F# are:

  • More avenues to mutation
  • Is there a good instantiation syntax?

Extra information

Estimated cost (XS, S, M, L, XL, XXL): S-M

Affidavit (please submit!)

Please tick this by placing a cross in the box:

  • This is not a question (e.g. like one you might ask on stackoverflow) and I have searched stackoverflow for discussions of this issue
  • I have searched both open and closed suggestions on this site and believe this is not a duplicate
  • This is not something which has obviously "already been decided" in previous versions of F#. If you're questioning a fundamental design decision that has obviously already been taken (e.g. "Make F# untyped") then please don't submit it.

Please tick all that apply:

  • This is not a breaking change to the F# language design
  • I or my company would be willing to help implement and/or test this
@charlesroddie
Copy link

charlesroddie commented Apr 7, 2019

Writing F# code you have to think a lot about the structures, i.e. types. Write down the type definitions, and the rest of the code often writes itself.

For quick passing of data you can use tuples and now anonymous records without having to define these types in advance. So anonymous records serve the role of tuples but with named fields.

Records with mutable fields don't fall into the category of passing around data. There must be a special purpose which required mutable fields. I believe this should be made clear with an explicit type definition.

@smoothdeveloper
Copy link
Contributor

It feels like a sensible extension, adding to the parity with record types.

Pondering if anonymous record with mutable fields can be consumed this way:

let v = {| mutable field1 = 1 |}

let f (v: {| field1: int |}) = v.field1

f v

Should this be allowed?

@natalie-o-perret
Copy link

Thank god I thought I was only one feeling that there was something missing: no latter than yesterday I was writing:

let a = {| mutable Field1 = List.empty<int>
           mutable Field2 = List.empty<int> |}

And realized that it cannot compile awww

Definitely +1 for this addition to the language

@0x53A
Copy link
Contributor

0x53A commented Oct 3, 2019

I think this would be really helpful for Fable and TS2Fable.

With this addition, many Typescript constructs can be represented as Anonymous Records.

@GratianPlume
Copy link

GratianPlume commented Nov 29, 2020

I don't like any mutable field in record or anonymous records. Because they calculat the HashCode including the mutable field.

After it put into a Hashset or Dictionary as key. Once the value is change,it's can never be found.

        type Test = {
             mutable Value: int
            Text: string
        }

        let set = new HashSet<_>()
        let x = { Value = 0; Text = "" }
        let _ = set.Add x 
        x.Value <- 1

        let (a, _) = set.TryGetValue({Value = 0; Text = ""})   // a is false
        let (a, _) = set.TryGetValue({Value = 1; Text = ""})  // a is false too
        let (a, _) = set.TryGetValue(x)                      // a is false three

we can custom the record's equalizer to avoid it, but anonymous records how?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants