fsharp / fslang-suggestions

The place to make suggestions, discuss and vote on F# language and core library features
345 stars 21 forks source link

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

Open NatElkins opened 4 years ago

NatElkins commented 4 years ago

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:

The disadvantages of making this adjustment to F# are:

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:

Please tick all that apply:

charlesroddie commented 4 years ago

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?

NatElkins commented 4 years ago

@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).

abelbraaksma commented 4 years ago

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.

NatElkins commented 4 years ago

@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).

dsyme commented 2 years ago

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.