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

Adding advisory on the ref keyword itself #1248

Closed
4 of 5 tasks
sksallaj82 opened this issue Feb 21, 2023 · 8 comments
Closed
4 of 5 tasks

Adding advisory on the ref keyword itself #1248

sksallaj82 opened this issue Feb 21, 2023 · 8 comments

Comments

@sksallaj82
Copy link

sksallaj82 commented Feb 21, 2023

I propose we add an advisory on the ref keyword itself; make it explicit that reference cells are no longer being recommended and that mutual should be used instead, though this is purely from assumption from the material I've been reading.

I've read the discussion that stemmed back in 2017 - 2021: #569 and read the proposal in the following link: fsharp-refcells-ops

I've been noticing in recent versions of F#, that there has been a shift away from using reference cells in favor of declaring mutable variables with the mutable keyword.

let x = ref 1
x := !x + 1

In VS2022, I'm told,

The use of '!' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change '!cell' to 'cell.Value'.

So I change my code

x := x.Value + 1

But then I'm told:

The use of ':=' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'cell := expr' to 'cell.Value <- expr'

x <- x.Value + 1

So I change my code, and now I'm told:

"This value is not mutable. Consider using the mutable keyword"

forcing me to do

let mutable x = 1

So if this is the pathway, why not just put an advisory on using the ref keyword in general?

Next, during my refactor, I am allowed to have the following line with no errors, which to me doesn't make sense:

let mutable x = ref 1

I don't see how this should ever be allowed. So I feel if ref is being allowed, that there should be a note about how we should pick ref or mutable.

So now I'm questioning, where are we on reference cells? Is this feature being deprecate? I see an article about Reference cells with no mention of deprecation: F# Reference cells

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

For Readers

If you would like to see this issue implemented, please click the 👍 emoji on this issue. These counts are used to generally order the suggestions by engagement.

@cartermp
Copy link
Member

Seems pretty reasonable to me.

@BentTranberg
Copy link

Not to me. I believe this

x <- x.Value + 1

should be this

x.Value <- x.Value + 1

And it looks like wrong things happen from there on. If this suggestion is based on one or two misunderstandings while exploring ref vs mutable, that isn't a good starting point for a language suggestion. Would be better to discuss this in a forum or forums first, to make the situation about the features clear.

I also wonder whether there are situations where reference cells are needed and/or more practical than mutables, in which case general advice about not using it would be strange.

@sksallaj82
Copy link
Author

I was able to get the ref to work using:

x.Value <- x.Value + 1

The point is that if you had the original code of conversion x := !x + 1, when you get to the state of x <- x.Value + 1 the advisory says that x is not mutable and then guides you to use mutable instead when using the incorrect syntax, this part is what's confusing. So if ref isn't okay to use based on the literature and reasoning of the previous context for the advisory, my suggestion does make sense. Otherwise, the advisory should tell me I forgot to use .Value since we know that x is a ref. It seems the guidance and articles gravitate more toward mutable to be used.

@Martin521
Copy link

I also wonder whether there are situations where reference cells are needed and/or more practical than mutables, in which case general advice about not using it would be strange.

I think the forward reference in fparsec is an example. At least I did not find a way to express this with mutables.

@cartermp
Copy link
Member

Hmm, yes, there are also a few parts of FSharp.Core implementations that rely on passing a mutable value to lock and while technically that should be possible, it fails to typecheck due to how lock works in F#.

@BentTranberg
Copy link

BentTranberg commented Feb 22, 2023

The documentation seems to lack information about recent changes.

doc : https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/reference-cells

more :

https://github.com/fsharp/fslang-design/blob/main/FSharp-6.0/FS-1111-refcell-op-information-messages.md

#569

When the changes were released, excellent release information about these was also given. Not sure where it is, but should be easy to find, and can probably be largely pasted into the docs.

EDIT on 2 March 2023: This is where I found the information first: https://devblogs.microsoft.com/dotnet/whats-new-in-fsharp-6/#bringing-f-forward-reducing-use-of-rarely-used-symbolic-operators

@dsyme
Copy link
Collaborator

dsyme commented Mar 1, 2023

@BentTranberg I updated the docs here: dotnet/docs#34337

@dsyme
Copy link
Collaborator

dsyme commented Mar 1, 2023

The suggestion itself doesn't make a lot of sense to me - ref is fine for creating reference cells.

The mistake was misreading

The use of ':=' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'cell := expr' to 'cell.Value <- expr'

but the message is pretty clear isn't it?

@dsyme dsyme closed this as completed Mar 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants