Acknowledgements & influences
Viscosity and this book stand on other people’s work. This page names those people and says plainly what each one’s ideas shaped. Full citations are in the bibliography.
A special note on Crafting Interpreters: Robert Nystrom’s code and test files are MIT-licensed, and this book’s Drip test suite is adapted from his Lox tests with that licence kept. His prose and illustrations are licensed CC BY-NC-ND 4.0, so nothing here copies or adapts them. The explanations and diagrams in this book are original, and his book is warmly recommended alongside it.
The problem Viscosity attacks
- Lukas Makor, Sebastian Kloibhofer, David Leopoldseder, Daniele Bonetta, Lukas Stadler, Hanspeter MössenböckAutomatic Array Transformation to Columnar Storage at Run Time (2022)The core idea behind Viscosity: transform arrays of JavaScript objects into columnar (struct-of-arrays) storage automatically, and amortize the cost of the transformation.
- Sebastian Kloibhofer, Lukas Makor, David Leopoldseder, Daniele Bonetta, Lukas Stadler, Hanspeter MössenböckControl Flow Duplication for Columnar Arrays in a Dynamic Compiler (2023)Specialized code paths for transformed arrays, and handling nested (multi-level) objects; the reason Viscosity plans for duplicated, layout-specialized loops.
- Bui Huy Giap (“Zap”, ziap)Struct of Arrays (SoA) in TypeScript with metaprogramming (2025)Showed SoA in TypeScript winning on field-subset reads and losing when whole objects must be rebuilt; the reason Viscosity chooses a layout instead of always using SoA.
- Matt Pharr, William R. Markispc: A SPMD Compiler for High-Performance CPU Programming (2012)ISPC’s soa<N> types: the AoSoA (blocked) layout that Viscosity can choose.
- The Intel ISPC projectIntel ISPC User’s Guide: Structure of Array TypesHow a language can keep ordinary indexing syntax while storing data as blocked SoA.
- The Odin project (odin-lang.org documentation contributors)Overview: SOA data typesChapter 118: a language where the programmer chooses SoA with one keyword, the opposite of Viscosity’s automatic choice.
- Mike ActonData-Oriented Design and C++ (2014)Chapter 23 and the cost model behind it: the layout is chosen from the data and the loops that read it, not fixed in advance, because different data is a different problem.
- Thomas Würthinger, Christian Wimmer, Andreas Wöß, Lukas Stadler, Gilles Duboscq, Christian Humer, Gregor Richards, Doug Simon, Mario WolczkoOne VM to Rule Them All (2013)Truffle and Graal, the runtime in which the columnar-array research was built.
How the book teaches languages and compilers
- Robert NystromCrafting Interpreters (2021)The whole shape of this book: build a language twice (a tree-walking interpreter, then a bytecode VM), and in Track B rebuild everything in a second, lower-level language. The Drip test suite is adapted from its MIT-licensed Lox tests. Its prose and illustrations (CC BY-NC-ND 4.0) are not copied or adapted here.
- Vaughan R. PrattTop Down Operator Precedence (1973)Chapter 33’s Pratt parser, and every parser built on it after that: chapter 48’s single-pass compiler, chapter 92’s JavaScript expressions and the Rust compiler in chapters 151–152.
- Keith D. Cooper, Linda TorczonEngineering a Compiler (3rd edition) (2022)The compiler middle-end part: control-flow graphs, dataflow analysis, optimization passes.
- Ron Cytron, Jeanne Ferrante, Barry K. Rosen, Mark N. Wegman, F. Kenneth ZadeckEfficiently Computing Static Single Assignment Form and the Control Dependence Graph (1991)Chapter 78’s “other way” to build SSA: placing phis at the dominance frontiers of each definition, then renaming over the dominator tree, which is what LLVM’s mem2reg does and what Braun et al.’s method avoids.
- Matthias Braun, Sebastian Buchwald, Sebastian Hack, Roland Leißa, Christoph Mallon, Andreas ZwinkauSimple and Efficient Construction of Static Single Assignment Form (2013)The SSA construction algorithm used by Viscosity’s IR (VIR).
- The LLVM ProjectUsing the New Pass ManagerViscosity’s pass manager: cached analyses that are invalidated when a transform changes the program.
- Mathias Bynens, Benedikt MeurerJavaScript engine fundamentals: Shapes and Inline Caches (2018)The explanation of shapes (hidden classes) and inline caches in the engine-internals part.
- Urs Hölzle, Craig Chambers, David UngarOptimizing Dynamically-Typed Object-Oriented Programming Languages with Polymorphic Inline Caches (1991)Chapter 64: the polymorphic inline cache, and the idea that what an IC has seen is type feedback for the optimizing tiers.
- Steve Klabnik, Carol Nichols, Chris KrychoThe Rust Programming Language (3rd edition) (2026)Track B: how the book teaches Rust.
- Boshen, VoidZero Inc. and contributorsOxc, the Oxidation Compiler (README)Chapter 172: what oxc is, and which of its parts the Rust port uses.
How the book helps you remember
- Henry L. Roediger III, Jeffrey D. KarpickeTest-Enhanced Learning: Taking Memory Tests Improves Long-Term Retention (2006)Why the book asks you to recall answers (retrieval practice) instead of only rereading.
- Allan PaivioMental Representations: A Dual Coding Approach (1986)Dual coding: every key idea comes with both words and a picture.
- Junyao Ye, Jingyong Su, Yilong CaoA Stochastic Shortest Path Algorithm for Optimizing Spaced Repetition Scheduling (2022)The research behind FSRS, the scheduler that decides when each review prompt in this book comes back.
- Jarrett Ye (Junyao Ye), the open-spaced-repetition contributorsFSRS: Free Spaced Repetition SchedulerThe scheduling algorithm for the book’s spaced-repetition prompts.
- ishiko732, the open-spaced-repetition contributorsts-fsrs (TypeScript implementation of FSRS), MIT licenceThe library that runs FSRS in your browser for the review prompts.
Reference documentation
- MDN contributorsFunctions (JavaScript Guide)The reference for chapter 1 (functions).
- MDN contributorsWorking with objects (JavaScript Guide)The reference for chapters 3 and 4 (objects, and comparing objects by reference).
- MDN contributorsEquality comparisons and samenessThe reference for chapter 4 (identity and ===).
- MDN contributorsconsole: log() static methodconsole.log, which every runnable example uses.
- MDN contributorsJavaScript typed arraysFloat64Array and friends: the storage Viscosity generates.
- MDN contributorsArrayChapter 2: arrays count from index 0, the last index is length − 1, and push grows the length.