fslang-suggestions icon indicating copy to clipboard operation
fslang-suggestions copied to clipboard

Allow full recursive processing of symbols in literals

Open cartermp opened this issue 5 years ago • 2 comments

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 nameof in 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

cartermp avatar Jun 19 '20 15:06 cartermp

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.

dsyme avatar Jun 19 '20 15:06 dsyme

Yep, as of https://github.com/dotnet/fsharp/issues/7897 it also affects it

cartermp avatar Jun 19 '20 16:06 cartermp