Plan 01: Type System Polymorphic Hierarchy
Goal: Replace the flat, string-based
TypeRefstruct with a polymorphicTypeinterface, eliminating string-based type checking, introducing static singletons for primitives, and supporting first-class function signatures and structural types. Inspiration: Go'sgo/types/type.go,cmd/compile/internal/types2, anduniverse.go.
1. Problem Statement & Root Cause
Currently, Kyna defines all types in compiler/kyna_types/include/kyna/semantics/type_model.hpp via:
struct TypeRef {
std::string name{"void"};
bool nullable{false};
std::vector<TypeRef> typeArgs;
std::vector<TypeRef> unionTypes;
std::string str() const;
};Critical Flaws
- Dynamic Heap String Allocations: Every primitive type check (
t("int"),t("str"),t("bool")) allocates a newstd::stringon the heap. - Loss of Function Signatures: Higher-order functions collapse to
TypeRef{"func"}, making it impossible to check argument or return type compatibility of callbacks. - Encoding Metadata in String Names: Classes are prefixed with
"class:Circle", modules with"module:math", and unions with"union". - Equality via Serialization: Type checks rely on
left.type.str() == right.type.str(), which is slow and prone to formatting bugs (e.g.TypeRef::str()formatting"union | int | str").
2. Target Architecture: The Polymorphic Type Hierarchy
2.1 The Type Interface
namespace kyna::types {
enum class TypeKind : uint8_t {
Basic,
Named,
Signature,
Interface,
Struct,
Array,
Map,
Union,
Nullable,
TypeParam
};
class Type {
public:
virtual ~Type() = default;
virtual TypeKind kind() const = 0;
virtual const Type* underlying() const = 0;
virtual std::string str() const = 0;
virtual bool isAssignableTo(const Type* target) const = 0;
virtual bool isIdenticalTo(const Type* other) const = 0;
};
using TypePtr = const Type*; // Types are interned and immutable
} // namespace kyna::types2.2 Concrete Type Implementations
-
BasicType: Singleton instances forint,float,bool,string,void,null,any.class BasicType : public Type { public: enum class BasicKind { Int, Float, Bool, String, Void, Null, Any }; BasicKind basicKind() const; TypeKind kind() const override { return TypeKind::Basic; } const Type* underlying() const override { return this; } std::string str() const override; bool isAssignableTo(const Type* target) const override; bool isIdenticalTo(const Type* other) const override; }; -
SignatureType: First-class function signatures.class SignatureType : public Type { private: std::vector<TypePtr> params_; TypePtr returnType_; TypePtr receiverType_{nullptr}; // for class methods bool isVariadic_{false}; public: TypeKind kind() const override { return TypeKind::Signature; } const std::vector<TypePtr>& params() const { return params_; } TypePtr returnType() const { return returnType_; } TypePtr receiverType() const { return receiverType_; } // ... }; -
NamedType: Nominal classes and user-defined types.class NamedType : public Type { private: std::string name_; TypePtr underlying_{nullptr}; std::vector<MethodSymbol> methods_; public: TypeKind kind() const override { return TypeKind::Named; } const std::string& name() const { return name_; } const Type* underlying() const override { return underlying_; } // ... }; -
Universe: Zero-allocation static registry.class Universe { public: static const BasicType* Int(); static const BasicType* Float(); static const BasicType* Bool(); static const BasicType* String(); static const BasicType* Void(); static const BasicType* Null(); static const BasicType* Any(); };
3. Implementation Steps
- Step 1: Create
compiler/kyna_types/include/kyna/types/type.hpp- Define
TypeKind,Typeabstract interface, andUniversefactory.
- Define
- Step 2: Implement Concrete Types
- Implement
BasicType,SignatureType,NamedType,UnionType,NullableTypeundercompiler/kyna_types/src/types/.
- Implement
- Step 3: Update
CMakeLists.txt- Add newly created source files explicitly to
compiler/kyna_types/CMakeLists.txt.
- Add newly created source files explicitly to
- Step 4: Provide Backward Compatibility Adapter
- Maintain
TypeRefas a thin wrapper or transition layer so existing code compiles incrementally.
- Maintain
- Step 5: Migrate Semantic Type Checker
- Update
type_checker.cppandanalyzer.cppto useUniverse::Int(),Universe::Bool(), and pointer comparisons instead of string matching.
- Update
- Step 6: Eliminate
TypeRef::str()Serialization for Comparison- Replace
sameParameters()instatement_checker.cppwithType::isIdenticalTo().
- Replace
4. Verification Plan
- Unit Tests:
- Create
tests/types/test_type_hierarchy.cppverifying pointer identity, assignability, and immutability.
- Create
- Regression Verification:
- Run
ctest --test-dir build-debug --output-on-failure.
- Run
- Repository Architecture Verifier:
- Run
python3 build_tools/verify_repository_architecture.py.
- Run
Source captured: 2026-10-11