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

Source-Only Attributes (a.k.a. Attributes everywhere)

Open NatElkins opened this issue 4 years ago • 5 comments

Source-Only Attributes (a.k.a. Attributes everywhere)

I propose we create a new type of attribute, source-only attributes, that allow labeling of code but don't have any representation in IL.

The existing way of approaching this problem in F# is to use "real" attributes (ones that inherit from System.Attribute) where you're able to, otherwise use a very distinct pattern you think won't be used elsewhere (such as in https://github.com/dotnet/fsharp/pull/6811 / https://github.com/fsharp/fslang-design/issues/455)

Syntax TBD of course, but source-only attributes would allow developers to annotate syntax constructs today that are not permitted today such as expression locals:

let someFunction () = 
    let [<<SourceOnlyAttributeHere>>] aVarYouWantInspectedAtCompileTime = 1
    aVarYouWantInspectedAtCompileTime

Also with compile time code generation possibly becoming more common (e.g. source generators, Myriad, etc.) this kind of construct may become more useful.

Pros and Cons

The advantages of making this adjustment to F# are:

  • Allows developers to more clearly express intent to design-time and compile-time mechanisms
  • Not restricted to where .NET attributes can be represented in IL.
  • Has the potential to clean up workarounds as mentioned in proposal section.
  • Allow us to beat C# to the punch :)

The disadvantages of making this adjustment to F# are:

  • Additional complexity to the language.

Extra information

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

Related suggestions: (put links to related suggestions here)

https://github.com/fsharp/fslang-suggestions/issues/789 - Tag AST nodes for pattern recognition https://github.com/dotnet/csharplang/issues/2478 - Proposal: Attributes everywhere <-- some good discussion there

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 (I don't think so anyway)
  • [ ] I or my company would be willing to help implement and/or test this

NatElkins avatar May 21 '20 14:05 NatElkins

How would one project know about the source-only attributes in another project. If both projects are in the same solution with in-memory inter-project references on then it's clear. But in other cases?

charlesroddie avatar May 21 '20 18:05 charlesroddie

@charlesroddie They wouldn't be able to. I was thinking it would be implemented in the same way as described by https://github.com/dotnet/csharplang/issues/2478 , where it's a type of trivia and represented in the AST but otherwise isn't available in the IL and can't be seen by other assemblies (in F#, C#, or otherwise).

NatElkins avatar May 21 '20 18:05 NatElkins

Related: https://github.com/fsharp/fslang-suggestions/issues/848

And see my comment there: what to do with attributes when the function is curried, inlined, or passed as reference? Would the attribute be carried over and be available for discovery?

That other issue is not about "source only", but to some extend, the same challenges remain.

abelbraaksma avatar May 21 '20 18:05 abelbraaksma

@abelbraaksma I was really thinking of this in terms of being able to apply a label or annotation to a chunk of AST, and to restrict what parts of the AST a source attribute could be used on. So for most of those scenarios you raised, the answer is "probably not." Except for maybe inlining, if the AST chunk is maintained and just copied into wherever it's being inlined too (I'm not sure how inlining works at an AST level).

I did just think of another con, which is that this opens the door to some confusion around when to use an Attribute over a Source Attribute. This is really what attributes are for in spirit, but due to technical limitations of the CLR, using attributes on arbitrary syntax constructs just isn't possible (or at least it's not clear how to due it without doing something pretty hacky).

NatElkins avatar May 21 '20 19:05 NatElkins

I guess we would support this if it's a .NET standard. You're right that they are potentially of use to source analysis tools.

dsyme avatar Jun 15 '22 10:06 dsyme