Directly Embed Type Constraints in Cpp2 Type Definitions
Summary:
I propose introducing a feature in Cpp2 that allows users to express constraints on types themselves directly in the type definition. This could be done using the syntax name:type:concept={...} or name:type is concept = {...}, allowing the defined type to automatically satisfy specific constraints (concepts).
Problem:
Currently in Cpp2, we can constrain deduced types (e.g., number: _ is std::regular = ...), but there is no straightforward way to enforce constraints on the type itself. This feature would close that gap and enable a more declarative way to ensure types meet certain requirements.
Proposed Syntax:
-
Current Cpp2 Syntax:
Point :type = { x: i32; y: i32; draw: (this) = .... }This generates the following Cpp1 code:
struct Point; struct Point { int x, y; void draw(); }; void draw() { // implementation } -
New Feature: The proposed feature would allow adding constraints directly to the type definition:
Point :type :drawable = { x: i32; y: i32; draw: (this) = .... }This would generate the following Cpp1 code with a
static_assertto ensure thatPointsatisfies thedrawableconcept:struct Point; struct Point { int x, y; void draw(); }; void draw() { static_assert(drawable<Point>); // implementation }
Benefits:
-
Self-Documenting: The constraint directly on the type definition acts as documentation. It makes the type's requirements clear and self-contained, so readers immediately understand what the type should satisfy without needing to refer to separate documentation.
-
Declarative Constraints: This feature allows constraints to be declared directly within the type definition, improving code readability. Instead of adding
static_assertor other checks manually in the implementation, constraints are declared in one place, making the code more concise and less error-prone. -
Aligns with Existing Features: Cpp2 already supports type constraints on deduced types using the syntax
name: _ is concept = .... Extending this syntax to constrain the type itself ensures consistency within the language and provides a more flexible and expressive way to enforce type contracts.