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

Support for consuming C# TupleNamedElementsAttribute metadata to make ValueTuple member access safer. #1354

Open
5 of 6 tasks
smoothdeveloper opened this issue Mar 16, 2024 · 5 comments

Comments

@smoothdeveloper
Copy link
Contributor

smoothdeveloper commented Mar 16, 2024

I propose F# leverages TupleNamedElementsAttribute that C# compilers puts on tuple when the items are named and part of the member signature.

Despite F# discourages usage of tuples in APIs (beside certain constructs that are conventionally established in FSharp.Core, that return tuples), it seems the BCL is making use of this C# feature (
https://github.com/dotnet/runtime/blob/7740dbd7fdb54e87c6aec5eb7b193bc7d21b68f1/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs#L3151) and overall, C# developers tend to use it, where F# would use anonymous record types.

Pros

It makes consuming C# APIs that exposes tuples annotated with TupleNamedElementsAttribute more natural and safer.

Cons

  • Spend more time parsing of the referenced assemblies
  • Spend more time type checking ValueTuple member access (I believe the C# feature only applies to ValueTuple types)

Extra information

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

Related suggestions: #1341, #1134, #616, #207

Affidavit

  • This is not a question (e.g. like one you might ask on StackOverflow) and I have searched StackOverflow for discussions of this issue
  • This is a language change and not purely a tooling change (e.g. compiler bug, editor support, warning/error messages, new warning, non-breaking optimisation) belonging to the compiler and tooling repository
  • 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
  • I have searched both open and closed suggestions on this site and believe this is not a duplicate

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
@T-Gro
Copy link

T-Gro commented Mar 18, 2024

Is it also expected to flow this information into other calls as the tuple is passed in / further returned?
Or just the immediate scope after the first return?

@auduchinok
Copy link

auduchinok commented Mar 18, 2024

Is it also expected to flow this information into other calls as the tuple is passed in / further returned?
Or just the immediate scope after the first return?

I'd vote for the names to flow through the calls, but it probably means we'd have to include them in the tuple types from F# point of view everywhere and to pickle them in F# metadata, changing the format somehow. And if we decide to add the component names to the type system then we could also allow defining such component names in F# as well, because it'd likely be the easier part. 🙂

@vzarytovskii
Copy link

pickle them in F# metadata, changing the format somehow

A very triggering and nightmare inducing phrase. This might mean that we make all the libraries not consumable by older compiler. Why do we need to pickle them? Aren't they only useable when emitting IL or consuming it?

@auduchinok
Copy link

auduchinok commented Mar 18, 2024

A very triggering and nightmare inducing phrase.

Huh, indeed. 🙂

Why do we need to pickle them?

I might be wrong, but AFAIK if an assembly includes the F# metadata, then the compiler uses this metadata as the source of truth instead of the normal IL one for the symbols from this assembly, so various F#-specific bits like type abbreviations are used instead of their compiled representations. Then lots of the places in the compiler pattern match these symbols from assemblies and often use separate logic for 1) F# symbols, 2) IL symbols, and 3) provided symbols. Please correct me if I'm missing something.

This might mean that we make all the libraries not consumable by older compiler.

Unless we find a clever way to add them next to the existing info without changing the existing format.

Aren't they only useable when emitting IL or consuming it?

I was wondering about what implications would be if we ever made them a real part of F# type system, like they are in C#.

@T-Gro
Copy link

T-Gro commented Mar 19, 2024

This is why I asked, if they would become an essential part of the Tuple TType.

We could in theory avoid the need to pickling them if they use the standard IL Attribute-based representation on the cross-assembly boundaries - merging the pickled data with IL import at reading time.

Alternative would be to immediately translate and treat them as struct anon records at time of import from a C# lib.
That would however carry some small runtime cost for the copying from System.ValueTuple to the struct anon record.
Why?
Because I believe OP is right that their usage in C# covers what F# uses anonymous records for.

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

4 participants