Beyond Hindley-Milner: A Tutorial on the Cubiml Compiler with Algebraic Subtyping

2025-06-13

This blog post series introduces Cubiml, a compiler tutorial built around a novel type inference system called "cubic biunification," an improvement on Algebraic Subtyping. It addresses the limitations of the Hindley-Milner system's lack of subtyping support, providing more powerful and intuitive type inference. The tutorial walks through the implementation of Cubiml with detailed code examples, covering booleans, conditionals, records, functions, let bindings, recursive let bindings, mutual recursion, and case type matching. The ultimate goal is a compiler that type-checks programs without requiring manual type annotations.

Read more
Development

Goodbye Mysterious Type Errors: How PolySubML Improves Type Inference Error Messages

2025-05-23

PolySubML is a programming language combining global type inference with subtyping and advanced polymorphism. This post explores how PolySubML designs good type error messages and explains why existing languages often fall short in improving type inference error messages. The author proposes five rules: 1. Never guess or backtrack; 2. Don't jump to conclusions; 3. Ask the user to clarify intent; 4. Allow the user to write explicit type annotations; 5. Don't include static type inference in your runtime execution model. By following these rules, PolySubML successfully addresses many common issues with type inference, significantly improving code debuggability.

Read more
Development type inference

Beyond OOP: The Evolution of Subtyping in Programming Languages

2025-03-29

This article explores the crucial role of subtyping in programming language design. The author, drawing on their experience developing several programming languages, explains that subtyping is not limited to class inheritance in object-oriented programming but is a more fundamental concept: type X is a subtype of type Y if a value of type X can be used wherever a value of type Y is expected. The article clearly explains why subtyping is crucial even in performance-oriented low-level languages, enabling the compiler to statically check for null values, aliasing, and other issues, thereby improving code reliability and ultimately driving the evolution of programming languages.

Read more
Development subtyping

Four Surprising Limitations of Rust's Borrow Checker

2024-12-24

This article delves into four surprising limitations of Rust's borrow checker encountered even by experienced Rustaceans. The first limitation involves the borrow checker's inability to fully account for match and return statements, leading to redundant checks when working with HashMaps. The second limitation concerns asynchronous programming, where Rust currently lacks the ability to express certain asynchronous callback type signatures. The third centers around FnMut closures not allowing re-borrowing of captured variables, restricting access to mutable state in async operations. Finally, the Send checker's lack of control flow awareness results in some Futures that should be Send being incorrectly flagged as non-Send. The author illustrates these limitations and their challenges with concrete code examples and workarounds, advocating for improvements to Rust's type system to enhance developer productivity.

Read more