Allow full recursive processing of symbols in literals
Title of Suggestion
I propose we solidify the interaction between literals defined in a recursive context to allow expressions like this:
let rec [<Literal>] SomeTag = nameof SomeTag
module rec M =
let rec [<Literal>] SomeOtherTag = nameof SomeOtherTag
And if https://github.com/fsharp/fslang-suggestions/issues/539 is implemented, the following would also work:
// Access 'y' defined below
module M =
let rec [<Literal>] x = y+1
and y = 1
module rec M =
let [<Literal>] x = y+1
let y = 1
It's important to note that this does overlap with suggestions like https://github.com/fsharp/fslang-suggestions/issues/539 because if they are implemented, this issue becomes more pronounced.
Currently, there is no reasonable workaround. The examples with nameof need to be written in one of these two ways:
let rec [<Literal>] SomeTag = 1 // dummy value
and y = nameof SomeTag // not a literal
let rec SomeOtherTag = nameof SomeOtherTag
Neither actually accomplishes the goal of the desired code though.
Pros and Cons
The advantages of making this adjustment to F# are:
- More use of
nameofin places where it feels natural - Nicely overlaps with suggestions like https://github.com/fsharp/fslang-suggestions/issues/539
The disadvantages of making this adjustment to F# are
- A surprisingly complicated implementation, meaning that ensuring the right behavior happens with F# as it is today is complicated
- Other features, such as https://github.com/fsharp/fslang-suggestions/issues/539 may also be needed to really see the value
Extra information
Estimated cost (XS, S, M, L, XL, XXL): M-L
Related suggestions: (put links to related suggestions here)
Affidavit (please submit!)
Please tick this by placing a cross in the box:
- [x] This is not a question (e.g. like one you might ask on stackoverflow) and I have searched stackoverflow for discussions of this issue
- [x] I have searched both open and closed suggestions on this site and believe this is not a duplicate
- [x] 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:
- [x] This is not a breaking change to the F# language design
- [x] I or my company would be willing to help implement and/or test this
Just to say that it might be worth mentioining that [<Literal>] is often used unnecessarily in F# code - though of course it has its uses. So the workaround
module rec Tags =
let SomeOtherTag = nameof SomeOtherTag
does often achieve what's necessary.
Also to say that this change would also affect processing of literals in signature files.
Yep, as of https://github.com/dotnet/fsharp/issues/7897 it also affects it