aboutsummaryrefslogtreecommitdiff
path: root/docs/dotc-internals/periods.md
blob: 2385fd00b6f0b2307699f9e3ab518c087b01ef08 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# Dotc's concept of time

Conceptually, the `dotc` copmpiler's job is to maintain views of
various artifacts associated with source code at all points in time.
But what is *time* for `dotc`? In fact, it is a combination of
compiler runs and compiler phases.

The *hours* of the compiler's clocks are measured in compiler
[runs](https://github.com/lampepfl/dotty/blob/master/src/dotty/tools/dotc/Run.scala). Every
run creates a new hour, which follows all the compiler runs (hours) that
happened before. `dotc` is designed to be used as an incremental
compiler that can support incremental builds, as well as interactions
in an IDE and a REPL. This means that new runs can occur quite
frequently.  At the extreme, every keystroke in an editor or REPL can
potentially launch a new compiler run, so potentially an "hour" of
compiler time might take only a fraction of a second in real time.

The *minutes* of the compiler's clocks are measured in phases. At every
compiler run, the compiler cycles through a number of
[phases](https://github.com/lampepfl/dotty/blob/master/src/dotty/tools/dotc/core/Phases.scala).
There are currently about 60 phases per run, so the minutes/hours
analogy works out roughly. After every phase the view the compiler has
of the world changes: trees are transformed,  types are gradually simplified
from Scala types to JVM types, definitions are rearranged, and so on.

Many pieces in the information compiler are time-dependent. For
instance, a Scala symbol representing a definition has a type, but
that type will usually change as one goes from the higher-level Scala
view of things to the lower-level JVM view. There are different ways
to deal with this. Many compilers change the type of a symbol
destructively according to the "current phase". Another, more
functional approach might be to have different symbols representing
the same definition at different phases, which each symbol carrying a
different immutable type. `dotc` employs yet another scheme, which is
inspired by functional reactive programming (FRP): Symbols carry not a
single type, but a function from compiler phase to type. So the type
of a symbol is a time-indexed function, where time ranges over
compiler phases.

Typically, the definition of a symbol or other quantity remains stable
for a number of phases. This leads us to the concept of a
[period](https://github.com/lampepfl/dotty/blob/master/src/dotty/tools/dotc/core/Periods.scala).
Conceptually, period is an interval of some given phases in a given
compiler run. Periods are conceptually represented by three pieces of
information

 - the ID of the current run,
 - the ID of the phase starting the period
 - the number of phases in the period

All three pieces of information are encoded in a value class over a 32 bit integer.