-
Notifications
You must be signed in to change notification settings - Fork 144
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Draft RFC for fsharp/fslang-suggestions#414
- Loading branch information
1 parent
77b2c82
commit c069dd0
Showing
1 changed file
with
84 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
# F# RFC FS-NNNN - [<RequireNamedArgument>] attribute | ||
|
||
The design suggestion [Add an attribute enforcing the use of named argument at callsite | ||
](https://github.com/fsharp/fslang-suggestions/issues/414) has been marked "approved in principle". | ||
|
||
|
||
This RFC covers the detailed proposal for this suggestion. | ||
|
||
- [x] Approved in principle | ||
- [ ] [Suggestion](https://github.com/fsharp/fslang-suggestions/issues/fill-me-in) | ||
- [ ] [Implementation](https://github.com/dotnet/fsharp/pull/FILL-ME-IN) | ||
- [ ] Design Review Meeting(s) with @dsyme and others invitees | ||
- [Discussion](https://github.com/fsharp/fslang-design/issues/PLEASE-ADD-A-DISCUSSION-ISSUE-AND-LINK-HERE) | ||
|
||
# Summary | ||
|
||
Allow to enforce usage of named arguments to method call sites by annotating `[<RequireNamedArgument>]` on the method definition. | ||
|
||
# Motivation | ||
|
||
This allows an API designer to enforce call sites abide to design choices in similar fashion to the existing attributes `RequireQualifiedAccess` and `RequiresExplicitTypeArguments`. | ||
|
||
Applying the `RequireNamedArgument` attribute to the method definition will enforce call sites to use the named argument syntax. | ||
|
||
This is most useful in cases where subsequent arguments of same type can be confusing or prone to introducing bugs at call sites or during refactorings. | ||
|
||
This impacts some type providers where the order of parameter of a type provided member may switch due to adjustment of the input provided to a type provider. | ||
|
||
# Detailed design | ||
|
||
Basic example: | ||
|
||
```fsharp | ||
type A() = | ||
static member x.B(dividend:int, divisor:int) = dividend / divisor | ||
[<RequireNamedArgument>] | ||
static member x.C(dividend:int, divisor:int) = dividend / divisor | ||
A.B(0, 15) // OK | ||
A.C(0, 15) // Not OK | ||
A.C(dividend=0, divisor=15) // OK | ||
``` | ||
|
||
Error message: | ||
|
||
`The method '%s' has the 'RequireNamedArgumentAttribute' attribute specified, use the named arguments syntax (e.g. 'MethodName(x = value)').` | ||
|
||
# Drawbacks | ||
|
||
* People consuming API using the feature may not adhere to the design choice made in the API design | ||
* Record types could be used for similar effect (but type providers don't have the facility to generate those at this time) | ||
* Increases FSharp.Core footprint | ||
|
||
# Alternatives | ||
|
||
Using record types. | ||
|
||
# Compatibility | ||
|
||
## Is this a breaking change? | ||
|
||
It is not a breaking change. | ||
|
||
## What happens when previous versions of the F# compiler encounter this design addition as source code? | ||
|
||
Code would still compile but the rule won't be enforced. | ||
|
||
## What happens when previous versions of the F# compiler encounter this design addition in compiled binaries? | ||
|
||
Code would still compile but the rule won't be enforced. | ||
|
||
## If this is a change or extension to FSharp.Core, what happens when previous versions of the F# compiler encounter this construct? | ||
|
||
Code would still compile but the rule won't be enforced. | ||
|
||
# Unresolved questions | ||
|
||
Whether the attribute would find a way to the BCL and support by other compilers. | ||
|
||
Does the compiler errors if the attribute is used on a function? or a warning? or ignored? | ||
|
||
What happens when the attribute is put on a virtual method but not on an overriden one? |