Skip to content

Release 0.1

This is the first published release of Incan.

Incan is a 0.x release: expect evolution as the language and toolchain stabilize. See the Stability policy for what changes are allowed in minor vs patch releases.

Highlights

  • A complete docs site (Start here, Tooling, Language Guide, Reference), built with MkDocs
  • A make-first developer workflow (make install, make smoke-test)
  • A usable CLI surface: incan build, incan run, incan fmt, incan test
  • A generated language reference to keep documentation and implementation aligned
  • Multi-file web applications with typed route extractors
  • Model field aliases and metadata for schema-safe mapping (RFC 021)
  • Start at: Language and Tooling
  • For "first steps" workflows, use the CLI and Make targets referenced there.

Looking for contributors?

Incan is still early and we'd love help—whether that's improving docs, fixing bugs, or implementing RFC-backed features.

  • Start here: Contributing
  • Good places to start:
    • docs fixes and examples
    • compiler diagnostics and error messages
    • small stdlib improvements

Features and Enhancements

  • Language: Typed functions, variables, and control flow (if/for/while)
  • Language: Modules and imports (including relative imports and Rust interop)
  • Language: Enums and exhaustive pattern matching with match
  • Language: Error handling with Result/Option and the ? operator
  • Language: Strings and formatting (including f-strings)
  • Language: Collections and iteration (including list/dict comprehensions)
  • Language/runtime: Reusable semantic core helpers shared by compiler and runtime (#15)
  • Language/runtime: Evolved incan_semantics into incan_core (#20)
  • Language/runtime: Python-style exceptions modeled as typed errors (#21)
  • Models: Keyword-only construction, defaults, and reflection helpers
  • Models: Field aliases and metadata for schema-safe mapping (RFC 021, #98)
  • Classes: Behavior-first types with methods, mut self, and inheritance (extends)
  • Traits/derives: Trait composition (with ...) and derives for common behavior (serialization, validation, etc.)
  • Derives: @derive(Validate) for validated construction (#49)
  • Derives: @derive(...) on enums now parsed, stored in AST, and used during lowering (#101)
  • Derives: Automatic Serialize/Deserialize propagation from models to referenced enums and newtypes (#103, #115)
  • Enums: Optional docstrings inside enum bodies (#102)
  • Web: Multi-path parameters, Json[T]/Query[T] extractors in generated route wrappers (#95)
  • Web: Html response wrapper with IntoResponse impl (#108)
  • Web: Web route wrappers work for nested modules via module_path_segments (#107)
  • Web: Web feature flags detected across dependency modules (#105)
  • Web: SurfaceTypeId registry extended with web types: App, Response, Html, Json, Query (#114)
  • Codegen: Optimize while True to loop in emitted Rust (#8)
  • Codegen: Cross-module enum variant access emits Type::Variant instead of Type.Variant (#110)
  • Codegen: Newtype tuple fields emitted as pub for cross-module construction (#104)
  • Codegen: List.append emits .clone() for non-Copy element types
  • Codegen: Associated function calls emit correctly in dependency modules (#112)
  • Compiler: Dependency module typechecking with check_with_imports_allow_private (#111)
  • Compiler: Targeted parser diagnostics for invalid enum body patterns (#113)
  • Tooling: Centralized INCAN_VERSION and version-agnostic codegen snapshots (#14)
  • Tooling: incan --help / incan --version are script-friendly (no banner/ANSI by default) (#34)
  • Tooling: incan test --fail-on-empty (non-zero when no tests are discovered) (#36)
  • Tooling: incan run executes from project root so relative paths work as expected (#109)
  • Tooling: Axum extractor import collisions resolved by qualifying imports (#100)
  • Docs: Restructured docs using the Divio system (#27)
  • Docs: MkDocs syntax highlighting (including incan fenced code blocks) (#37)
  • Docs: Generated language reference "Since" column populated (#39)
  • Docs: Enum documentation updated with derives, docstrings, and common pitfalls
  • Docs: Serialization reference expanded with enum and newtype sections
  • DX: Closed-set vocabulary registries and drift guardrails (#88)
  • DX: Remove TitleCase heuristic for associated-function emission (#52)
  • DX: Align docs/examples for cross-module imports and codegen status (#41)
  • DX: Benchmark metadata drift fixes (#40)
  • DX: Simplified lexer frontend (#2)
  • Testing: Test harness improvements (#24)

Bugfixes

  • Web: Fully qualified extractor types across modules (#106)
  • Codegen/IR: Internal module imports in multi-file projects use correct crate::/super:: prefixes (#90, #91)
  • Parser: Fat-arrow inline match arms now support return statement (#92, #96)
  • Lowering/codegen: None literal now correctly lowers to Option::None instead of unit () (#93, #97)
  • Typechecker/traits: Trait conformance checks are signature-aware, respect @requires field types, and include inherited members (#45, #46, #47, #48)
  • Typechecker/traits: Models can implement traits (#42)
  • Typechecker/newtypes: Direct newtype construction is disallowed (#44)
  • Typechecker/constructors: Field defaults are applied in model/class constructors (#43)
  • Typechecker/match: Improved match exhaustiveness behavior for None patterns (#13)
  • Codegen: Index expressions cast to usize automatically where needed (#9)
  • Codegen: list.append(x) emits the correct Rust method (#7)
  • Codegen: Default visibility is private (no longer pub everywhere) (#6)
  • Codegen: Avoid unnecessary mut function parameters (#5)
  • Codegen: Mixed int/float arithmetic compiles correctly (#4)
  • Tooling: import this prints "One obvious way" once (#33)
  • Tooling/formatter: incan fmt --diff output is actionable for newline-only changes (#32)
  • Tooling/CLI: incan build --help output directory default matches actual output path (#31)
  • Examples/web: examples/web/hello_web.incn compiles (#30)
  • Tooling/test runner: Assertion codegen mismatch fixed (assert_eq(...) vs assert_eq!(...)) (#29)

Known limitations (0.1)

Incan is still evolving. A few things you may run into:

  • Some compiler/language features described in RFCs may be partially implemented.
  • Rust interop is available, but crate support is gated by a "known-good" list (see: Rust interop).
  • Web route handlers and their request models must be declared pub for cross-module wrapper generation (#117).
  • Multi-line parenthesized imports are not yet supported; use multiple single-line imports as a workaround (#116).

Breaking changes

  • This is a 0.x release line; minor releases may introduce new language/tooling features.
  • Patch releases must not introduce new language features (see: Stability policy).

RFCs implemented

  • Incan Core Language RFC (Phase 1): RFC 000
  • Const Bindings: RFC 008
  • Model Field Metadata and Aliases: RFC 021