Skip to content

Language record

F#

F# files are indexed with the signature/definition split in mind: a .fsi surface and its .fs implementation publish one symbol rather than two, a discriminated union becomes an enum carrying its cases, and a type member lands as a method on the type that owns it.

.fs, .fsi, .fsx · 1 registry id · 11 of 14 relationship types

The registry row this page is generated from

Read at render time from the same family row the register reads, so nothing in this block can disagree with it.

Extensions
.fs, .fsi, .fsx
Registry names
fsharp
Recorded symbols
modules · functions · types · methods

Relationship types this analyzer constructs

11 of 14 constructed, read from this analyzer's source and re-derived by the languages gate. Each row below is one of the engine's types, in the engine's own order.

Relationship typeConstructed
callsconstructed by this analyzer
extendsconstructed by this analyzer
implementsconstructed by this analyzer
usesconstructed by this analyzer
importsconstructed by this analyzer
exportsconstructed by this analyzer
containsconstructed by this analyzer
referencesconstructed by this analyzer
overridesconstructed by this analyzer
instantiatesconstructed by this analyzer
decoratesruled absent
rendersruled absent
mixes_inruled absent
part_ofconstructed by this analyzer

11 constructed, 3 not constructed. All 3 absent types are recorded as ruled absent: the written reason and the corpus measurement behind each are in this family's completeness record. The register explains what each label means.

What this analyzer does not resolve

  • new is the only thing that distinguishes a construction in F#, so a bare Foo(...) stays a call — a capitalised name is not evidence — and the undecided calls/instantiates boundary is the largest class on both sides of the differential, 116 edges against 14.
  • The ambiguous type X = SomeType is refused rather than guessed at: a one-case union and a type abbreviation are the same text, and a pinned corpus measured 114 such sites per 400 files.
  • The member val X : int with get, set form does not parse under the pinned grammar, so such a property is recorded as a parse error rather than as a symbol, and roughly 890 occurrences of it exist in the F# compiler corpus alone.

Every line above was written against F#’s own analyzer module and is named against a construct in it, so it can be checked against the source. Nothing here is inherited from a template, or from another language’s page.

Where you meet it in a repository

Recognised by extension — .fs, .fsi, .fsx. Everything below is about where those files actually sit in a working repository.

  • A library ships an .fsi surface beside its .fs implementation, so the public surface is declared once and defined once and bb merges the two into one symbol.
  • A record and a discriminated union are the workhorses of an F# domain model, and each case or field becomes a symbol of its own.
  • Computation expressions wrap a whole body in one call, so the work inside a let! chain reads as part of the enclosing function rather than as separate calls.

Questions this index answers

Phrased as retrievals, because that is what an index can honestly do: it holds the symbols and the edges between them, and hands them back with the evidence attached.

  1. Which modules does this file open?
  2. Which union cases does this type have?
  3. Which members does this type declare, and which override its base?
  4. Where is this value bound, and is it a function or a plain value?

What the analyzer sees in code like this

An opened module, a record type, a discriminated union and a member
module MyApp.Orders                  // bb records: module MyApp.Orders
open System                          // bb records: an opened module

type Order = { Id: int; Total: decimal }   // bb records: type Order · fields Id, Total
type Shape = | Circle of float | Rect of float * float   // bb records: cases Circle, Rect

Symbols are stored with the file they came from and the bytes they span, so a hit points at a line rather than at a guess. The annotations in the sample are commentary for the reader, not strings the index would store.

Languages that turn up in the same repository

Functional & declarative — the count beside each name is how many relationship types that family’s analyzer constructs.

The extensions, registry names, recorded symbols and relationship types above are the parser registry row for F#, read while the page rendered — the same row the register reads, so the two surfaces cannot tell two stories. Every relationship type listed as constructed appears in src/ast/real-*, the analyzer modules bb ships. bb 0.1.0 answers from a local store over 50 languages (53 registry ids, three of them aliases). There is no benchmark on this page: every claim here is one you can go and read in the source.