Skip to content

Latest commit

 

History

History
94 lines (67 loc) · 2.96 KB

FS-1039-struct-representation-for-active-patterns.md

File metadata and controls

94 lines (67 loc) · 2.96 KB

F# RFC FS-1039 - (Struct representation for active patterns)

The design suggestion Struct representation for active patterns has been marked "approved in principle". This RFC covers the detailed proposal for this suggestion.

Summary

We should be able to compile active patterns using struct versions of FSharpOption and FSharpChoice unions.

Motivation

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!

Detailed design

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 and FSharpChoice types
  • allow StructAttribute on active patterns
  • change codegen

Drawbacks

  • It's one more trick for F# programmers to learn

Alternatives

  • 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.

Compatibility

It's not breaking change due to it doesn't require new syntax at all, just addition to FSharp.Core and changes in codegen

Unresolved questions

  • We need good names for struct versions of FSharpOptions and FSharpChoice. Same for Some/None cases
  • Shouldn't we add utility functions for struct options in FSharp.Core? Like StructOption module with bind and map
  • Can we consider changing defaults and omitting StructAttribute for future major version of F#?