-
Notifications
You must be signed in to change notification settings - Fork 21
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
Implicit mapping between Normalized and Anonymous Record types #1266
Comments
If #1253 is implemented you'll be able to write let inputPolymorphism () =
// anonymous record is implicitly extracted from `myCoolRecord`
someInputFun {| ...myCoolRecord |}
let outputPolymorphism: TinyRecord =
// `TinyRecord` is implicitly constructed from anonymous record
{ ...(someOutputfun false) } |
Yes I agree this is really a use case for #1253 |
@Lanayx Would the spread operator really allow this syntax without the surrounding brackets? |
@Happypig375 I don't see why not :) You can write do that today with other operators, for example |
I think @Happypig375 is talking about this let x = {| ... y |}
// vs above
let x = ... y |
You are absolutely right, the curly braces have to be there, I've updated my example |
I propose we allow type directed, implicit mapping (a la automapper) for functions that receive or output anonymous records, without actually changing how anonymous records behave, are created, and are represented in compiled code. I'm envisioning more of a macro rather than a wholly different approach to types.
The existing way of approaching anonymous records in F# is explicitly and manually mapping each property in the construction of the resulting record.
My proposition is to use the available type information to make implicit mappings if and only if the anonymous and normalized record types are strictly subtypes one of the other. E.g., Large type gets mapped into a smaller type. This should only work if every mapped field is of the exact same name and type. E.g.,
{ A : int } = {| A : int |}
,{ A : int } <> { A : float }
. If properties dont match, this should result in a compile-time type mismatch error, or anFS0764: No assignment given for field X of type Y
.Using the types above, the proposal would look like
It's also possible to achieve this pseudo structural typing using reflection, but we lose compile-time errors for type mismatches.
Pros and Cons
The advantages of making this adjustment to F# are ...
Enables something that resembles row polymorphism, without altering IL representations, ideally. It also reduces lines of code in such cases where mapping would result in boilerplate and encourages the usage of anonymous records.
The disadvantages of making this adjustment to F# are ...
Enables row polymorphism, contrary to anon records design principle, as stated in the original RFC for anonymous records here, but I would like to argue that this was chosen to simplify IL representation and maintain an achievable goal for that proposal. Now that anon records were successfully introduced into the language, this change seems like a good QoL addition that shouldn't disrupt the existing implementation.
Extra information
Estimated cost (XS, S, M, L, XL, XXL): Naively, I wanna say that this is a small feature.
Related Suggestions:
#1251
#1253 (sorta, implies implicit mappings as well)
Affidavit (please submit!)
Please tick this by placing a cross in the box:
Please tick all that apply:
For Readers
If you would like to see this issue implemented, please click the 👍 emoji on this issue. These counts are used to generally order the suggestions by engagement.
The text was updated successfully, but these errors were encountered: