{ pkgs }: let lib = pkgs.lib; types = { Module = "Module"; Class = "Class"; DataType = "DataType"; Repo = "Repo"; RepoAdapter = "RepoAdapter"; Function = "Function"; Binding = "Binding"; FunctionType = "FunctionType"; }; addType = arg: ty: arg // { __artinixType = ty; }; needsName = arg: arg // { __artinixName = null; }; addName = name: arg: if arg ? __artinixName && arg.__artinixName == null then arg // { __artinixName = name; } else arg; addNames = lib.mapAttrs addName; moduleExtension = final: prev: (addType (addNames prev) types.Module); classExtension = final: prev: (addType (needsName prev) types.Class); repoExtension = class: repoType: final: prev: (addType (needsName (repoType class prev)) types.Repo); dataTypeExtension = final: prev: (addType (needsName prev) types.DataType) // { __functor = self: class: attrs: attrs // { __artinixRepoType = self; __artinixClass = class; }; }; adapterExtension = final: prev: (addType (needsName prev) types.RepoAdapter); functionExtension = functy: final: prev: (addType (needsName (functy prev)) types.Function); bindingExtension = class: final: prev: (addType (needsName prev) types.Binding) // { __artinixClass = class; }; functionTypeExtension = typeCons: final: prev: (addType prev types.FunctionType) // { __functor = self: args: (typeCons args) // { __artinixFunctionType = self; }; }; constructor = extension: mod: (lib.makeExtensible mod).extend extension; in rec { mkModule = constructor moduleExtension; mkClass = constructor classExtension; mkDataType = constructor dataTypeExtension; mkRepo = cls: repoty: constructor (repoExtension cls repoty); mkAdapter = constructor adapterExtension; mkFuncType = typeCons: constructor (functionTypeExtension typeCons); mkFunc = functy: constructor (functionExtension functy); mkBinding = cls: constructor (bindingExtension cls); mkView = cls: functy: args: mkBinding cls { func = mkFunc functy (builtins.removeAttrs args ["inputs" "outputs"]); inherit (args) inputs outputs; }; mkRuntime = ({nativeFunctionTypes, nativeDataFormats, linker}: ); mkProgram = ({runtime, bindings, storageProviders}: ); }