Skip to content

Commit 96685dc

Browse files
authored
Create representations.md (dotnet#13474)
1 parent 776799d commit 96685dc

File tree

1 file changed

+58
-0
lines changed

1 file changed

+58
-0
lines changed

docs/representations.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
---
2+
title: Representations
3+
category: Compiler Internals
4+
categoryindex: 200
5+
index: 350
6+
---
7+
# Representation Decisions in the F# Compiler
8+
9+
Consider the following declarations, all of which look very similar.
10+
11+
```fsharp
12+
module M =
13+
let z = 1
14+
let f = x + z
15+
16+
17+
type C(w: int, z: int) =
18+
19+
let f x = x + z
20+
let f x = f 3 + x
21+
22+
23+
let g (z: int) =
24+
let f x = x + 1
25+
```
26+
Part of the job of the F# compiler is to "decide" how these declarations are compiled. The following acts as a guide to how these different bindings are represented and where these decisions are made.
27+
28+
First for module-level `let` bindings. These representations are decided by code in `CheckExpressions.fs` and `CheckDeclarations.fs` based on syntax.
29+
30+
```fsharp
31+
module M =
32+
let z = 1 // z --> static property + field, required by spec, compiled name mandated
33+
let f x = x + z // f --> static method, required by spec, compiled name mandated
34+
```
35+
36+
Next for class-level `let` bindings. These representations are decided by code in `CheckIncrementalClasses.fs` based on analysis of use.
37+
```fsharp
38+
// Decided in CheckIncrementalClasses.fs based on analysis of use
39+
type C(w: int, z: int) = // w --> local to object constructor, required by spec
40+
// z --> private instance field, required by spec
41+
let f x = x + z // f --> private instance method, required by spec, compiled name not mandated
42+
// Note: initially uses an ephemeral 'f' Val then creates a member Val with compiled name
43+
44+
let f x = f 3 + x // f --> private instance method, required by spec, compiled name not mandated
45+
// Note: initially uses an ephemeral 'f' Val then creates a member Val with compiled name
46+
47+
static let g x = x + 1 // g --> private static method, required by spec, compiled name not mandated, initially uses an ephemeral 'g' Val then creates a member Val with compiled name
48+
49+
static let g x = g 3 // g --> private static method, required by spec, compiled name not mandated, initially uses an ephemeral 'g' Val then creates a member Val with compiled name
50+
```
51+
Next for expression-level `let` bindings. These representations are decided by code in various optimization phases.
52+
```fsharp
53+
let g (z: int) = // z --> local + field in closure for 'f', not mandated
54+
let f x = x + 1 // f --> FSharpFunc value, or maybe a static method, not mandated
55+
// Decided in various optimization phases
56+
```
57+
58+
> NOTE: The representation decision is implied by the addition of ValReprInfo to the `Val` node.

0 commit comments

Comments
 (0)