300 lines
5.5 KiB
Typst
300 lines
5.5 KiB
Typst
#import "@local/cetz:0.3.5": canvas, draw
|
|
#import "@preview/modpattern:0.1.0": modpattern
|
|
|
|
#let stripe(stroke) = line(
|
|
start: (0%, 100%),
|
|
end: (100%, 0%),
|
|
stroke: stroke,
|
|
)
|
|
|
|
#let state-fills = (
|
|
unread: red.lighten(80%),
|
|
current: yellow.lighten(80%),
|
|
done: green.lighten(80%),
|
|
skimmed: modpattern((10pt, 10pt), stripe(green.lighten(70%) + 4pt)),
|
|
)
|
|
|
|
#let chap(num, pos, state: "unread") = {
|
|
draw.content(
|
|
pos,
|
|
str(num),
|
|
padding: (x: 1em, y: .6em),
|
|
frame: "rect",
|
|
stroke: black,
|
|
name: str(num),
|
|
fill: state-fills.at(state, default: none),
|
|
)
|
|
}
|
|
|
|
#let chapters = (
|
|
"1": (
|
|
state: "done",
|
|
pos: (0, 0),
|
|
),
|
|
"2": (
|
|
state: "skimmed",
|
|
pos: (1, 0),
|
|
),
|
|
"3": (
|
|
state: "done",
|
|
pos: (2, 0),
|
|
depends-on: (2,),
|
|
),
|
|
"4": (
|
|
state: "done",
|
|
pos: (1, 1),
|
|
depends-on: (3,),
|
|
),
|
|
"5": (
|
|
state: "done",
|
|
pos: (2, 1),
|
|
depends-on: (3,),
|
|
),
|
|
"6": (
|
|
state: "done",
|
|
pos: (2, 2),
|
|
depends-on: (5,),
|
|
),
|
|
"7": (
|
|
state: "done",
|
|
pos: (1, 3),
|
|
depends-on: (4, 6),
|
|
),
|
|
"8": (
|
|
state: "done",
|
|
pos: (3, 1),
|
|
depends-on: (3,),
|
|
),
|
|
"9": (
|
|
state: "done",
|
|
pos: (3, 2),
|
|
depends-on: (5, 8),
|
|
),
|
|
"10": (
|
|
state: "done",
|
|
pos: (0.5, 4),
|
|
depends-on: (7, 9),
|
|
),
|
|
"11": (
|
|
state: "done",
|
|
pos: (3, 3),
|
|
depends-on: (9,),
|
|
),
|
|
"12": (
|
|
pos: (4, 3),
|
|
depends-on: (9,),
|
|
),
|
|
"13": (
|
|
pos: (1.5, 4),
|
|
depends-on: (11,),
|
|
),
|
|
"14": (
|
|
pos: (2.5, 4),
|
|
depends-on: (11,),
|
|
),
|
|
"15": (
|
|
pos: (3.5, 4),
|
|
depends-on: (11,),
|
|
),
|
|
"16": (
|
|
pos: (1, 5),
|
|
depends-on: (15,),
|
|
),
|
|
"17": (
|
|
pos: (0.5, 6),
|
|
depends-on: (10, 16),
|
|
),
|
|
"18": (
|
|
pos: (2, 5),
|
|
depends-on: (13, 15),
|
|
),
|
|
"19": (
|
|
pos: (4, 5),
|
|
depends-on: (15,),
|
|
),
|
|
"20": (
|
|
pos: (5, 5),
|
|
depends-on: (9,),
|
|
partly-depends-on: (15,),
|
|
),
|
|
"21": (
|
|
pos: (5, 6),
|
|
depends-on: (20, 15),
|
|
),
|
|
"22": (
|
|
pos: (4.5, 4),
|
|
depends-on: (11,),
|
|
),
|
|
"23": (
|
|
state: "current",
|
|
pos: (7, 3),
|
|
depends-on: (9,),
|
|
),
|
|
"24": (
|
|
pos: (6, 4),
|
|
depends-on: (23,),
|
|
),
|
|
"25": (
|
|
pos: (3, 5),
|
|
depends-on: (10, 24),
|
|
),
|
|
"26": (
|
|
pos: (7, 5),
|
|
depends-on: (15, 23),
|
|
partly-depends-on: (24,),
|
|
),
|
|
"27": (
|
|
pos: (5.5, 7),
|
|
depends-on: (18, 26),
|
|
),
|
|
"28": (
|
|
pos: (3, 6),
|
|
depends-on: (16, 26),
|
|
),
|
|
"29": (
|
|
pos: (3, 8),
|
|
depends-on: (23,),
|
|
),
|
|
"30": (
|
|
pos: (4, 8),
|
|
depends-on: (29,),
|
|
partly-depends-on: (28,),
|
|
),
|
|
"31": (
|
|
pos: (5.5, 8),
|
|
depends-on: (26, 30),
|
|
),
|
|
"32": (
|
|
pos: (6.5, 8),
|
|
depends-on: (27, 31),
|
|
),
|
|
)
|
|
|
|
#let compute-pos(pos) = {
|
|
let (x, y) = pos
|
|
return (x * 4em, -y * 5em)
|
|
}
|
|
|
|
#let diagram = canvas({
|
|
for (num, info) in chapters.pairs() {
|
|
let pos = compute-pos(info.pos)
|
|
chap(num, pos, state: info.at("state", default: "unread"))
|
|
draw.on-layer(-1, {
|
|
for dep in info.at("depends-on", default: ()) {
|
|
draw.line(
|
|
str(num),
|
|
str(dep),
|
|
mark: (end: ">", fill: black),
|
|
)
|
|
}
|
|
for dep in info.at("partly-depends-on", default: ()) {
|
|
draw.line(
|
|
str(num),
|
|
str(dep),
|
|
stroke: gray,
|
|
mark: (end: ">", fill: gray),
|
|
)
|
|
}
|
|
})
|
|
}
|
|
|
|
draw.content(
|
|
compute-pos((7.2, -0.2)),
|
|
anchor: "north-east",
|
|
padding: 5pt,
|
|
frame: "rect",
|
|
stroke: black,
|
|
)[
|
|
#grid(
|
|
columns: (auto, auto),
|
|
inset: (x: .4em, y: .2em),
|
|
align: (center + horizon, left + horizon),
|
|
grid.cell(colspan: 2)[*Legend*],
|
|
..for (name, fill) in state-fills.pairs() {
|
|
(
|
|
box(
|
|
width: 1.8em,
|
|
height: 1.2em,
|
|
fill: fill,
|
|
radius: .2em,
|
|
stroke: black,
|
|
),
|
|
name,
|
|
)
|
|
}
|
|
)
|
|
]
|
|
})
|
|
|
|
#align(center, text(size:1.5em)[*Current reading status of TAPL*])
|
|
|
|
#align(
|
|
center + horizon,
|
|
figure(
|
|
diagram,
|
|
caption: [TAPL chapters graph and reading status]
|
|
)
|
|
)
|
|
|
|
#pagebreak()
|
|
|
|
= Topics
|
|
|
|
#let topics = (
|
|
[Introduction],
|
|
[Mathematical Preliminaries],
|
|
[Untyped Arithmetic Expressions],
|
|
[An ML Implementation of Arithmetic Expressions],
|
|
[The Untyped Lambda-Calculus],
|
|
[Nameless Representation of Terms],
|
|
[An ML Implementation of the Lambda-Calculus],
|
|
[Typed Arithmetic Expressions],
|
|
[Simply Typed Lambda-Calculus],
|
|
[An ML Implementation of Simple Types],
|
|
[Simple Extensions],
|
|
[Normalization],
|
|
[References],
|
|
[Exceptions],
|
|
[Subtyping],
|
|
[Metatheory of Subtyping],
|
|
[An ML Implementation of Subtyping],
|
|
[Case Study: Imperative Objects],
|
|
[Case Study: Featherweight Java],
|
|
[Recursive Types],
|
|
[Metatheory of Recursive Types],
|
|
[Type Reconstruction],
|
|
[Universal Types],
|
|
[Existential Types],
|
|
[An ML Implementation of System F],
|
|
[Bounded Quantification],
|
|
[Case Study: Imperative Objects, Redux],
|
|
[Metatheory of Bounded Quantification],
|
|
[Type Operators and Kinding],
|
|
[Higher-Order Polymorphism],
|
|
[Higher-Order Subtyping],
|
|
[Case Study: Purely Functional Objects],
|
|
)
|
|
|
|
#{
|
|
show text: strong
|
|
show: align.with(center)
|
|
grid(
|
|
columns: 3,
|
|
align: (center, right, left).map(a => a + horizon),
|
|
column-gutter: 1em,
|
|
row-gutter: .6em,
|
|
..for (i, topic) in topics.enumerate(start: 1) {
|
|
let indicator = box(
|
|
width: 1.8em,
|
|
height: 1.2em,
|
|
radius: .2em,
|
|
fill: state-fills.at(
|
|
chapters.at(str(i))
|
|
.at("state", default: "unread")
|
|
),
|
|
stroke: black
|
|
)
|
|
(indicator, str(i), topic)
|
|
}.flatten()
|
|
)
|
|
} |