1 Introduction to Typing
This chapter introduces typing as the discipline that gives meaning to raw bits, distinguishes code from data, and constrains what values are allowed where. It motivates types with real-world stakes (such as unit mismatches) and frames them as sets of possible values plus the valid operations on those values. A type system applies rules—either at compile time or at run time—to assign, infer, and enforce these types, converting many potential failures into early, actionable feedback. With this lens, types offer broad correctness guarantees, and the chapter briefly nods to the deep connection between types and logic, where well-typed programs embody proofs of desired properties.
The practical benefits center on five themes: correctness, immutability, encapsulation, composability, and readability. Correctness improves by shrinking the state space—rejecting invalid inputs and disallowing unsafe states before execution. Immutability preserves verified assumptions and curbs data races, while encapsulation prevents misuse by hiding representation behind safe interfaces. Composability emerges from generic, reusable building blocks that separate algorithms from data and reduce duplication. Readability rises as explicit types serve as precise, enforced documentation, with type inference reducing boilerplate without sacrificing clarity when used judiciously.
The chapter surveys the landscape of type systems: dynamic versus static (when checks occur) and weak versus strong (how many implicit conversions are permitted), using JavaScript and TypeScript to illustrate tradeoffs and pitfalls like surprising coercions. It clarifies how inference still operates at compile time and when explicit annotations are valuable. Finally, it sets expectations for the book’s pragmatic focus and audience, outlining the journey from primitive types and type composition through function types, subtyping, and generics, culminating in higher-kinded types—all aimed at helping practicing developers leverage modern static typing to build safer, more maintainable systems.
A sequence of bits can be interpreted in multiple ways
The sequence of bits typed as a signed 16-bit integer. The type information (16-bit signed integer) tells the compiler and/or runtime that the sequence of bits represents an integer value between -32768 and 32767, ensuring the correct interpretation as -15709.
Source code is transformed by a compiler or interpreter into code which can be executed by a runtime. The runtime is either a physical computer or a virtual machine, like Java’s JVM, or a browser’s JavaScript engine.
declaring a type correctly we can disallow invalid values: the first type is too loose and allows for values we don’t want (😈, 💀). The second, more restrictive type, won’t compile if the code tries to assign an unwanted value to a variable.
Summary
- A type is a classification of data that defines the operations that can be done on that data, the meaning of the data, and the set of allowed values
- A type system is a set of rules which assign and enforce types to elements of a programming language.
- Types restrict the range of values a variable can take, so in some cases what would’ve been a run-time error becomes a compile-time error
- Immutability is a property of the data enabled by typing, which ensures values don’t change when they’re not supposed to
- Visibility is another type-level property which determines what components are allowed to access what data
- Generic programming enables powerful decoupling and code reuse
- Type notations make the code easier to understand for readers of the code
- Dynamic typing or “duck typing” determines types at run-time
- Static typing checks types at compile time, catching type errors which otherwise would’ve become run-time errors
- The strength of a type system is a measure how many implicit conversions between types are allowed
- Modern type checkers have powerful type inference algorithms which enables them to determine what are the types of variables, functions and so on without you having to explicitly write them out
In the next chapter we will look at primitive types, which are the building blocks of the type system. We’ll learn how to avoid some common mistakes that arise when using these types and see how we can build pretty much any data structure from arrays and references.
Programming with Types ebook for free