Skip to content

T02, your code is data - #40

Merged
tamnd merged 1 commit into
mainfrom
lesson-t02
Sep 6, 2026
Merged

tamnd merged 1 commit into
mainfrom
lesson-t02

Conversation

@tamnd

@tamnd tamnd commented Sep 6, 2026

Copy link
Copy Markdown
Owner

The second lesson of the tour. T01 walked one line of C# through ten stages and went past the assembly on its way to somewhere else. This one stops and opens the assembly, and reads it as what it actually is, which is a database.

The shared L1 program

This is the part that affects every lesson from here on, so it is worth reading even if the lesson itself is not interesting to you.

lessons/shared/l1/Shapes.cs is now in the repository. It is the canonical L1 program from the pedagogy notes, the ten line shapes program the book is meant to come back to at greater depth in every part. Until now each lesson invented its own fixture, which is fine for a smoke test and wrong for a book whose argument is that the same ordinary program looks different from ten different heights.

xray builds <lesson>/fixture/*.csproj and has no notion of a fixture living anywhere else, and this did not seem worth changing the tool for. So the source sits in lessons/shared/l1 and a lesson's own fixture project pulls it in.

<ItemGroup>
  <Compile Include="../../shared/l1/*.cs" />
</ItemGroup>

Each lesson gets its own build in its own output directory, so two lessons cannot tread on each other and a lesson that needs a different configuration can have one. lessons/shared/l1/README.md records that, plus why the program is shaped the way it is and what changing it would cost.

The fixture project turns nothing off. A census of a program built with things muted for convenience would be tidier than a census of a normal build, and it would be worth less than nothing.

What is on the page

Thirteen blocks, eleven of which print, all reading the same L1.dll with System.Reflection.Metadata, which ships in the box. Nothing here needs a debugger, a runtime build or a privilege.

  • The table census. Thirteen tables with anything in them, eighty seven rows for the whole program, and the fact that empty tables are not written at all, so the shape of the census already tells you something before you read a row.
  • Five types, of which somebody typed three.
  • Eight methods, of which somebody typed four, and why the row numbers have to be contiguous and in type order rather than the compiler being tidy.
  • Every name the file defines, and three names from the source that are not among them.
  • The pdb next door, which has those three, and the slot number with no name against it because it is the enumerator the foreach needed.
  • The MemberRef table read as a transcript, where foreach turns up as GetEnumerator, MoveNext, get_Current and Dispose, and the interpolated string turns up as a handler struct. First sight of lowering, which T04 does properly.
  • Five types defined against nineteen named and twenty six members named, and why that ratio is the reason .NET can load lazily.
  • Fourteen attributes on a program with none written on it anywhere, and the coded index that explains why the table comes out in the order it does.
  • The scale gap against System.Private.CoreLib.

Three prediction gates: how many types a three class program defines, whether an assembly containing no using statement references IDisposable.Dispose, and whether the name total is in the assembly. Every option has a written reason, including the wrong ones.

One new diagram, docs/diagrams/rows-and-tokens.dg, showing the three reference tables chained together and a four byte token split into a table number and a row number. It has no counts in it on purpose. Counts belong on the page, where the build regenerates them, because a number in a diagram is a number nothing checks.

How it is checked

Eight captured outputs are committed, and they include row counts and token values. That is deliberate, and it is the same call T01 made when it committed IL bytes: those are exactly the things that should turn red when a compiler changes what it emits.

Two blocks are dropped, because they print things that belong to the machine rather than to .NET, and both are covered by assertions instead. The scale block asserts three lines, the shape of the program's own row count, and that the library is more than a thousand times the program, a threshold set well under the real ratio of over two thousand so that a future library shedding rows does not turn a true statement red. The machine block asserts one of the four supported platforms and a three part release version. Every claim has a written reason.

Verified before opening this

Locally on osx-arm64, and on server3 on linux-x64, both against the committed expected output, and both matched byte for byte. A lesson with eight captured outputs full of row counts is the kind of thing that turns out to differ on the second platform, so it is worth finding that out before the CI legs rather than after.

Not in here

No runtime: citations. pin.json still holds a null commit, so none of them would resolve, and the page says so plainly. The portable pdb format is specified in dotnet/runtime rather than in ECMA-335 and gets a proper citation once the pin lands.

Reads the assembly built from L1 as what it is, a database. The table
census, the five types, the eight methods, every name the file defines
and the three local names that are not among them, the pdb next door
that holds those three, the MemberRef table read as a transcript of the
lowering, the ratio of names to definitions, the fourteen attributes
nobody applied, and the scale gap against System.Private.CoreLib.

Adds lessons/shared/l1, the canonical L1 program from the pedagogy
notes. xray only builds a fixture inside a lesson directory, so the
source lives here and each lesson's fixture project pulls it in with a
Compile Include and builds its own copy.

Adds docs/diagrams/rows-and-tokens.dg, which has no counts in it on
purpose, since counts belong on the page where the build regenerates
them.

Verified against the committed expected output on osx-arm64 and on
server3 on linux-x64. Both matched byte for byte.
@tamnd tamnd added this to the M2 The tour milestone Sep 6, 2026
@tamnd tamnd added priority/p0 Blocks the current milestone area/pedagogy Sequencing, the beginner ramp and assessment labels Sep 6, 2026
@tamnd
tamnd merged commit 8b20b7f into main Sep 6, 2026
22 checks passed
@tamnd
tamnd deleted the lesson-t02 branch September 6, 2026 00:53
@tamnd tamnd mentioned this pull request Sep 6, 2026
6 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/pedagogy Sequencing, the beginner ramp and assessment priority/p0 Blocks the current milestone

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant