The design suggestion Struct representation for active patterns has been marked "approved in principle". This RFC covers the detailed proposal for this suggestion.
- Approved in principle
- Suggestion
- Details: under discussion
- Implementation: In progress
We should be able to compile active patterns using struct versions of FSharpOption
and FSharpChoice
unions.
Such powerful and extensible feature is worthy to be near-zero-cost abstraction. We should be able to providing better performance just via a simple attribute addition!
How to use:
let (|Even|Odd|) n =
if n % 2 = 0 then
Even
else
Odd
Put the StructAttribute
on the active pattern definition.
[<Struct>]
let (|Even|Odd|) n =
if n % 2 = 0 then
Even
else
Odd
It should be compiled as function that returns struct version of FSharpChoice<Unit, Unit>
union. In F#4.1 it's possible to define struct discriminated unions, so we can avoid extra allocations.
The same for partial active patterns.
let (|Int|_|) str =
match System.Int32.TryParse(str) with
| (true,int) -> Some(int)
| _ -> None
[<Struct>]
let (|Int|_|) str =
match System.Int32.TryParse(str) with
| (true,int) -> StructSome(int)
| _ -> StructNone
You might to note in struct version different names of Some
/None
cases are used. This is because of we need to distinguish between struct and non-struct versions of the option
type.
Сonsequently we need to make this changes in compiler and FSharp.Core:
- add new struct versions for
FSharpOption
andFSharpChoice
types - allow
StructAttribute
on active patterns - change codegen
- It's one more trick for F# programmers to learn
- Require programmers to code complex matching by hands without expressiveness of active patterns
- Provide better inlining and optimization for active patterns. It can be hard to achieve.
It's not breaking change due to it doesn't require new syntax at all, just addition to FSharp.Core and changes in codegen
- We need good names for struct versions of
FSharpOptions
andFSharpChoice
. Same forSome
/None
cases - Shouldn't we add utility functions for struct options in FSharp.Core? Like
StructOption
module withbind
andmap
- Can we consider changing defaults and omitting
StructAttribute
for future major version of F#?