Slide 1

Slide 1 text

A Journey to Type-safe Vectors in F# 2020/04/17 @ Kata-System Matsuri Online cannorin

Slide 2

Slide 2 text

$ whoami cannorin Member of F# Software Foundation Member of Ionide Maintainer of / Contributing to: - fsprojects/FSharpPlus - ionide/Ionide-vim - ocaml/ocaml-lsp, etc Visit 7colou.red for more details

Slide 3

Slide 3 text

SPOILER ALERT! ● Type-level naturals and booleans ● Efficient and type-safe vectors (fixed-length array) ● Clean and intuitive syntax to use them ● As a vanilla F# library (not as a language extension!)

Slide 4

Slide 4 text

Type-level Naturals, at the very beginning Naturals as Peano numbers

Slide 5

Slide 5 text

Type-level Naturals, at the very beginning Defining addition for Peano naturals

Slide 6

Slide 6 text

Type-level Naturals, at the very beginning Now we must bring it to the type-level, but how to define addition for this?

Slide 7

Slide 7 text

Exploiting overload resolution “Inline” functions can use ad-hoc polymorphism

Slide 8

Slide 8 text

This allows us to write overloaded functions Overload resolution = Matching against types Exploiting overload resolution

Slide 9

Slide 9 text

We can define addition (and other operations) with recursive overload resolution Exploiting overload resolution

Slide 10

Slide 10 text

We need type-level Booleans, too

Slide 11

Slide 11 text

We need type-level Booleans, too So that we can have type-level assertions

Slide 12

Slide 12 text

Vector implementation, the first try And now we can implement vectors!

Slide 13

Slide 13 text

We can also implement type-safe index access thanks to type-level naturals, but... Vector implementation, the first try

Slide 14

Slide 14 text

The Cons (definitely not about the list constructor ) ● Type naturals are tedious to write by hand (1) ● Vector creation is not really type-safe (2)

Slide 15

Slide 15 text

The solution (also definitely not about that thing in Visual Studio) ➔ Create type naturals from compile-time constants ➔ Use tuples and count their arity to create vectors

Slide 16

Slide 16 text

Creating type naturals from compile-time constants We can use Type Providers for this

Slide 17

Slide 17 text

Creating type naturals from compile-time constants Type Providers: • Compile-time type generator, basically • Can take constant values (such as JSON schemas) as input and generate types based on them • Fully integrated into the language = Nice IDE support • No deep dive today, would deserves a separate talk

Slide 18

Slide 18 text

Here TypeNat<_> and Vector.Get<_> are type providers, which takes an integer and generates a specialized type to work with the corresponding type-level natural Creating type naturals from compile-time constants

Slide 19

Slide 19 text

n-tuples (n > 7) have nested representations under the hood Using tuples for vector creation

Slide 20

Slide 20 text

Being nested means we can effectively match against them Using tuples for vector creation

Slide 21

Slide 21 text

• Count the arity of a given tuple with type naturals • Extract elements from the tuple and store them in an array • All done with overload resolution, with no reflection involved Using tuples for vector creation

Slide 22

Slide 22 text

Finally, we get this... • Clean, intuitive, and type-safe • Very small run-time overhead (no reflection/boxing)

Slide 23

Slide 23 text

Looks awesome? You can use them soon™! Included as part of upcoming FSharpPlus[1] v2.0 release with a lot of familiar and useful functions such as: [1]: https://fsprojects.github.io/FSharpPlus/

Slide 24

Slide 24 text

One more thing...