Korora: A tiny & fast type system for Nix in Nix

Yesterday I made a tiny type system for Nix called Kororā (named after the little penguin).

Notable features:

  • Primitive types (string, int, etc)
  • Polymorphic types (union, attrsOf, etc)
  • Struct types

The main goal is to be as performant as possible.
It’s fast enough that you can stick it in hot paths without too much performance overhead, like in meta type checks.

This is achieved through precomputing as much as possible when types are created, and through ensuring no hot paths return array-ish types like lists, attrsets or strings.

If you’ve previously used Yants you will find the APIs very similar.
Check it out at GitHub - adisbladis/korora: A tiny & fast type system for Nix in Nix

12 Likes

This is super cool!

I’m curious, what’s the main use case for this, as opposed to something like the nixpkgs type system?

I’m curious, what’s the main use case for this, as opposed to something like the nixpkgs type system?

The “nixpkgs type system” should really be called the “NixOS type system” because it is inherently linked to the module system, and with that comes the semantics of the module system.
See the linked PR regarding meta checks. Value merging makes sense for NixOS, but for other use cases the cost is too high.

Korora should be similarly fast as if you’ve written type assertions by hand using the builtins.is* functions.

1 Like

can someone ELI5 here? I mean I get what this is but what command do I enter on the cli (nix-build? nix run?) to see the “Basic Usage” example in action?

{ korora }:
let
  t = korora.string;

  value = 1;
...

I’m sorry for asking such a basic question but I’m interested. Maybe me even asking means it’s not something I should be using or worry about but nevertheless…

If you want to just play around I recommend using the repl:

$ nix repl '<nixpkgs>'
warning: future versions of Nix will require using `--file` to load a file
Welcome to Nix 2.18.1. Type :? for help.

Loading installable ''...
Added 19947 variables.
nix-repl> korora = import (builtins.fetchGit "https://github.com/adisbladis/korora.git") { inherit lib; }

nix-repl> t = korora.string

nix-repl> t.check 1234
error:
       … while calling the 'throw' builtin

         at /nix/store/n5jj2abpas1ihg5l26cysyl8rak7pa21-source/default.nix:101:50:

          100|       inherit name verify;
          101|       check = v: if verify v == null then v else throw (verify v);
             |                                                  ^
          102|     };

       error: Expected type 'string' but value '1234' is of type 'int'
1 Like

Thanks @adisbladis I was missing the forest for the trees and this works great. Many thanks