-
Notifications
You must be signed in to change notification settings - Fork 309
[RFC] inline op_Implicit for Erased Unions #4143
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
base: main
Are you sure you want to change the base?
[RFC] inline op_Implicit for Erased Unions #4143
Conversation
This change reminded me of an experimentation I did for Glutinum: glutinum-org/cli#80 Looking at my comments it seems like one potential issue/limitation is with anonymous record. However, because the proposed changes are for "generics" types and not direct binding like in Glutinum I don't think this limitation apply as much |
A good example of how it's so easy to tunnel vision and miss obvious bugs/issues, I would have never thought there were issues with anonymous records and hit a real head scratcher if something like that happened. Thank you for the info, I'll have to try remember to put this in a PR for the docs at some point when Fable 5 is coming getting released |
I'm going to quickly take this chance to add this to the xml docs |
Yes, it is difficult to remember that anonymous record have this limitation because I think they are the only F# type to have it. I probably discovered it because Glutinum "stupidly" generate code and its how I am mapping literal types in certain scenario. |
Full type docs are not shown with code completion/intellisense as demonstrated in second image. I like this, what do you think? Thoughts on this type of doc usage? According to MSDN it's standard, but I only have real experience with Rider. /// <summary>
/// Erased union type to represent one of two possible value types mainly intended for typing the signature of imported
/// JS functions.
/// </summary>
/// <remarks>
/// Pattern matching is possible, but should consider the implications of the Erased union and JS type testing (see the
/// docs for details).<br/>
/// Member concrete types will be implicitly cast into the union, and will provide a warning to this effect. Usage of
/// the explicit cast operator <c>!^</c> available in <c>Fable.Core.JsInterop</c> will remove this warning.
/// <a href="https://github.com/fable-compiler/Fable/pull/4143">Collection types, can provide an error</a> that will
/// only be resolved with the explicit operator. <a href="https://github.com/glutinum-org/cli/issues/80">Anonymous
/// records have other considerations that may be relevant if you are encountering issues.</a>
/// <code>
/// let test(arg: U3<string, int, float[]>) =
/// match arg with
/// | U3.Case1 x -> printfn "A string %s" x
/// | U3.Case2 x -> printfn "An int %i" x
/// | U3.Case3 xs -> Array.sum xs |> printfn "An array with sum %f"
/// </code>
/// </remarks>
/// <seealso href="https://fable.io/docs/communicate/js-from-fable.html#erase-attribute"/> |
Seems good to me, as long as we have the full tooltip using hover Can you please use I also discovered that I would also place |
Tsk. Jealous 😢 . Do we have a general time frame for Fable 5? I'd like to have a through and through on the codebase to update documentation before its released |
There is not time frame for Fable 5 but it will happens after this 2 features are done:
The reason to way for both of these features is because they can introduce change to the AST or big AST manipulation. I would love also to rework the CLI commands/arguments but this can be done latter in a Fable 6 release. |
op_Implicit for Erased Unions
The suggested change is to provide inlined implicit casting into the erased union.
This would allow method/other calls to accept arguments of the type implicitly in situations where the inferred type is concrete. It will provide an error with generic type parameters and still error unless
!^
explicitly cast which is fine. See above.This would not concretely change anything fundamental about the usage or behaviour of these erased unions in implementation. The advantage here is that the erased union would provide a warning (from the implicit cast) rather than an error, which better
suits the use case of the discriminated union as an interface for F# to dynamic languages when interop-ing.
In this situation, workflow would ideally not be broken when providing an input to bindings that accept multiple types. Especially since the erased operator is defined in the JsInterop module.
I would argue appropriate highlighting of a potential issue that can be adjusted afterwards and made explicit instead of outright being invalid would align with the majority use case of these erased unions.
I've had this implemented in my own libraries for a while as I find it to be a great DX improvement without cost