diff --git a/README.md b/README.md index 3be0f8eb..8cc6ad72 100644 --- a/README.md +++ b/README.md @@ -45,81 +45,24 @@ competitors if your project requires: ## Documentation -- [Design](./docs/design.md), -- [Compiler](./docs/compiler.md), -- [Codegen](./docs/codegen.md), -- [Comparison matrix](./docs/comparison-matrix.md), -- [User feedback](.docs/feedback) +Visit [LambdaBuffers Github Pages](https://mlabs-haskell.github.io/lambda-buffers). -## Getting started +## Acknowledgements -### Installing Nix +This project was graciously funded by the Cardano Treasury in [Catalyst Fund 9](https://cardano.ideascale.com/c/idea/421376). -This repository relies heavily on the [Nix Package -Manager](https://nixos.org/download.html) for both development and package -distribution. +Authors: -To install run the following command: +- [Drazen Popovic](https://github.com/bladyjoker) +- [Vlad Posmangiu Luchian](https://github.com/cstml) +- [Sean Hunter](https://github.com/gnumonik) -```sh -sh <(curl -L https://nixos.org/nix/install) --daemon -``` +Contributors: -and follow the instructions. - -```sh -$ nix --version -nix (Nix) 2.8.0 -``` - -> NOTE: The repository should work with Nix version greater or equal to 2.8.0. - -Make sure to enable [Nix Flakes](https://nixos.wiki/wiki/Flakes#Enable_flakes) -and IFD by editing either `~/.config/nix/nix.conf` or `/etc/nix/nix.conf` on -your machine and add the following configuration entries: - -```yaml -experimental-features = nix-command flakes -allow-import-from-derivation = true -``` - -Optionally, to improve build speed, it is possible to set up a binary caches -maintained by IOHK and Plutonomicon by setting additional configuration entries: - -```yaml -substituters = https://cache.nixos.org https://iohk.cachix.org https://cache.iog.io https://public-plutonomicon.cachix.org -trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ= iohk.cachix.org-1:DpRUyj7h7V830dp/i6Nti+NEO2/nhblbov/8MW7Rqoo= public-plutonomicon.cachix.org-1:3AKJMhCLn32gri1drGuaZmFrmnue+KkKrhhubQk/CWc= -``` - -### Building and development - -To facilitate seamlessly moving between directories and associated Nix -development shells we use [direnv](https://direnv.net) and -[nix-direnv](https://github.com/nix-community/nix-direnv): - -To install both using `nixpkgs`: - -```sh -nix profile install nixpkgs#direnv -nix profile install nixpkgs#nix-direnv -``` - -Your shell and editors should pick up on the `.envrc` files in different -directories and prepare the environment accordingly. Use `direnv allow` to -enable the direnv environment and `direnv reload` to reload it when necessary. - -Additionally, throughout the repository one can use: - -```sh -$ pre-commit run --all -cabal-fmt............................................(no files to check)Skipped -fourmolu.................................................................Passed -hlint....................................................................Passed -markdownlint.............................................................Passed -nix-linter...............................................................Passed -nixpkgs-fmt..............................................................Passed -shellcheck...........................................(no files to check)Skipped -typos....................................................................Passed -``` - -To run all the code quality tooling specified in the [pre-commit-check config file](./pre-commit.nix) +- [George Flerovsky](https://github.com/GeorgeFlerovsky) +- [Andrea Ciceri](https://github.com/aciceri) +- [Julia Chatain](https://juliachatain.com) +- [Andrea Vezzosi](https://github.com/saizan) +- [Magnus Viernickel](https://github.com/MangoIV) +- [Rajdeep Chase Maity](https://github.com/TotallyNotChase) +- [Ramiro Garay](https://github.com/rmgaray) diff --git a/lambda-buffers-proto/.envrc b/api/.envrc similarity index 100% rename from lambda-buffers-proto/.envrc rename to api/.envrc diff --git a/api/build.nix b/api/build.nix new file mode 100644 index 00000000..8d8e7ee6 --- /dev/null +++ b/api/build.nix @@ -0,0 +1,50 @@ +{ pkgs, pbnix-lib, commonTools, shellHook }: +rec { + devShell = pkgs.mkShell { + name = "protos-env"; + buildInputs = [ + pkgs.protobuf + pkgs.haskellPackages.proto-lens-protoc + pkgs.protoc-gen-doc + ] ++ builtins.attrValues commonTools; + + inherit shellHook; + }; + + packages = { + lambda-buffers-lang-hs-pb = pbnix-lib.haskellProto { + inherit pkgs; + src = ./.; + proto = "lang.proto"; + cabalPackageName = "lambda-buffers-lang-pb"; + }; + + lambda-buffers-compiler-hs-pb = pbnix-lib.haskellProto { + inherit pkgs; + src = ./.; + proto = "compiler.proto"; + cabalBuildDepends = [ packages.lambda-buffers-lang-hs-pb ]; + cabalPackageName = "lambda-buffers-compiler-pb"; + }; + + lambda-buffers-codegen-hs-pb = pbnix-lib.haskellProto { + inherit pkgs; + src = ./.; + proto = "codegen.proto"; + cabalBuildDepends = [ packages.lambda-buffers-lang-hs-pb ]; + cabalPackageName = "lambda-buffers-codegen-pb"; + }; + + lambda-buffers-api-docs = pkgs.stdenv.mkDerivation { + src = ./.; + name = "lambdabuffers-api-docs"; + buildInputs = [ + pkgs.protobuf + ]; + buildPhase = '' + mkdir $out; + protoc --plugin=${pkgs.protoc-gen-doc}/bin/protoc-gen-doc lang.proto compiler.proto codegen.proto --doc_out=$out --doc_opt=markdown,api.md; + ''; + }; + }; +} diff --git a/lambda-buffers-proto/codegen.proto b/api/codegen.proto similarity index 97% rename from lambda-buffers-proto/codegen.proto rename to api/codegen.proto index 3b07ef7f..3b2a8f48 100644 --- a/lambda-buffers-proto/codegen.proto +++ b/api/codegen.proto @@ -1,6 +1,6 @@ syntax = "proto3"; -package lambdabuffers; +package lambdabuffers.codegen; import "lang.proto"; diff --git a/lambda-buffers-proto/compiler.proto b/api/compiler.proto similarity index 99% rename from lambda-buffers-proto/compiler.proto rename to api/compiler.proto index da6ea1c9..65e79f17 100644 --- a/lambda-buffers-proto/compiler.proto +++ b/api/compiler.proto @@ -1,6 +1,6 @@ syntax = "proto3"; -package lambdabuffers; +package lambdabuffers.compiler; import "lang.proto"; diff --git a/lambda-buffers-proto/examples/tys.textproto b/api/examples/tys.textproto similarity index 100% rename from lambda-buffers-proto/examples/tys.textproto rename to api/examples/tys.textproto diff --git a/lambda-buffers-proto/lang.proto b/api/lang.proto similarity index 100% rename from lambda-buffers-proto/lang.proto rename to api/lang.proto diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index e782a39b..58a4b6ab 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -1,8 +1,12 @@ # Summary +- [Introduction](introduction.md) +- [Getting started](getting-started.md) +- [LambdaBuffers to Haskell](haskell.md) +- [LambdaBuffers to Purescript](purescript.md) - [Design](design.md) +- [API](api.md) - [Compiler](compiler.md) -- [Compiler API](compiler-api.md) - [Codegen](codegen.md) - [Command line interface](command-line-interface.md) - [Comparison matrix](comparison-matrix.md) diff --git a/docs/build.nix b/docs/build.nix index 678af849..8d073d99 100644 --- a/docs/build.nix +++ b/docs/build.nix @@ -1,8 +1,21 @@ -{ pkgs, commonTools, shellHook }: -pkgs.mkShell { - name = "docs-env"; +{ inputs, lib, ... }: { + perSystem = { pkgs, system, inputs', config, ... }: + { + devShells.dev-docs = pkgs.mkShell { + name = "docs-env"; + packages = [ pkgs.mdbook ]; + shellHook = config.pre-commit.installationScript; + }; - packages = [ commonTools.markdownlint-cli commonTools.typos pkgs.mdbook ]; + packages.lambda-buffers-book = pkgs.stdenv.mkDerivation { + src = ./.; + name = "lambda-buffers-book"; + buildInputs = [ pkgs.mdbook ]; + buildPhase = '' + cp ${config.packages.lambda-buffers-api-docs}/api.md api.md; + mdbook build . --dest-dir $out + ''; + }; - inherit shellHook; + }; } diff --git a/docs/compiler-api.md b/docs/compiler-api.md deleted file mode 100644 index 6b81a3c2..00000000 --- a/docs/compiler-api.md +++ /dev/null @@ -1,1460 +0,0 @@ -# Protocol Documentation - - -## Table of Contents - -- [compiler.proto](#compiler-proto) - - [ClassConstraint](#lambdabuffers-compiler-ClassConstraint) - - [ClassDef](#lambdabuffers-compiler-ClassDef) - - [ClassName](#lambdabuffers-compiler-ClassName) - - [CompilerError](#lambdabuffers-compiler-CompilerError) - - [CompilerInput](#lambdabuffers-compiler-CompilerInput) - - [CompilerOutput](#lambdabuffers-compiler-CompilerOutput) - - [CompilerResult](#lambdabuffers-compiler-CompilerResult) - - [ConstrName](#lambdabuffers-compiler-ConstrName) - - [Constraint](#lambdabuffers-compiler-Constraint) - - [Derive](#lambdabuffers-compiler-Derive) - - [FieldName](#lambdabuffers-compiler-FieldName) - - [InstanceClause](#lambdabuffers-compiler-InstanceClause) - - [InternalError](#lambdabuffers-compiler-InternalError) - - [Kind](#lambdabuffers-compiler-Kind) - - [Kind.KindArrow](#lambdabuffers-compiler-Kind-KindArrow) - - [KindCheckError](#lambdabuffers-compiler-KindCheckError) - - [KindCheckError.CyclicKindError](#lambdabuffers-compiler-KindCheckError-CyclicKindError) - - [KindCheckError.InconsistentTypeError](#lambdabuffers-compiler-KindCheckError-InconsistentTypeError) - - [KindCheckError.UnboundTyRefError](#lambdabuffers-compiler-KindCheckError-UnboundTyRefError) - - [KindCheckError.UnboundTyVarError](#lambdabuffers-compiler-KindCheckError-UnboundTyVarError) - - [KindCheckError.UnificationError](#lambdabuffers-compiler-KindCheckError-UnificationError) - - [Module](#lambdabuffers-compiler-Module) - - [ModuleName](#lambdabuffers-compiler-ModuleName) - - [ModuleNamePart](#lambdabuffers-compiler-ModuleNamePart) - - [NamingError](#lambdabuffers-compiler-NamingError) - - [Opaque](#lambdabuffers-compiler-Opaque) - - [Product](#lambdabuffers-compiler-Product) - - [ProtoParseError](#lambdabuffers-compiler-ProtoParseError) - - [ProtoParseError.MultipleClassDefError](#lambdabuffers-compiler-ProtoParseError-MultipleClassDefError) - - [ProtoParseError.MultipleConstructorError](#lambdabuffers-compiler-ProtoParseError-MultipleConstructorError) - - [ProtoParseError.MultipleFieldError](#lambdabuffers-compiler-ProtoParseError-MultipleFieldError) - - [ProtoParseError.MultipleImportError](#lambdabuffers-compiler-ProtoParseError-MultipleImportError) - - [ProtoParseError.MultipleModuleError](#lambdabuffers-compiler-ProtoParseError-MultipleModuleError) - - [ProtoParseError.MultipleTyArgError](#lambdabuffers-compiler-ProtoParseError-MultipleTyArgError) - - [ProtoParseError.MultipleTyDefError](#lambdabuffers-compiler-ProtoParseError-MultipleTyDefError) - - [ProtoParseError.OneOfNotSetError](#lambdabuffers-compiler-ProtoParseError-OneOfNotSetError) - - [ProtoParseError.UnknownEnumError](#lambdabuffers-compiler-ProtoParseError-UnknownEnumError) - - [Record](#lambdabuffers-compiler-Record) - - [Record.Field](#lambdabuffers-compiler-Record-Field) - - [SourceInfo](#lambdabuffers-compiler-SourceInfo) - - [SourcePosition](#lambdabuffers-compiler-SourcePosition) - - [Sum](#lambdabuffers-compiler-Sum) - - [Sum.Constructor](#lambdabuffers-compiler-Sum-Constructor) - - [Ty](#lambdabuffers-compiler-Ty) - - [TyAbs](#lambdabuffers-compiler-TyAbs) - - [TyApp](#lambdabuffers-compiler-TyApp) - - [TyArg](#lambdabuffers-compiler-TyArg) - - [TyBody](#lambdabuffers-compiler-TyBody) - - [TyClassCheckError](#lambdabuffers-compiler-TyClassCheckError) - - [TyClassCheckError.DeriveOpaqueError](#lambdabuffers-compiler-TyClassCheckError-DeriveOpaqueError) - - [TyClassCheckError.ImportNotFoundError](#lambdabuffers-compiler-TyClassCheckError-ImportNotFoundError) - - [TyClassCheckError.MissingRuleError](#lambdabuffers-compiler-TyClassCheckError-MissingRuleError) - - [TyClassCheckError.OverlappingRulesError](#lambdabuffers-compiler-TyClassCheckError-OverlappingRulesError) - - [TyClassCheckError.OverlappingRulesError.QHead](#lambdabuffers-compiler-TyClassCheckError-OverlappingRulesError-QHead) - - [TyClassCheckError.SuperclassCycleError](#lambdabuffers-compiler-TyClassCheckError-SuperclassCycleError) - - [TyClassCheckError.UnboundClassRefError](#lambdabuffers-compiler-TyClassCheckError-UnboundClassRefError) - - [TyClassRef](#lambdabuffers-compiler-TyClassRef) - - [TyClassRef.Foreign](#lambdabuffers-compiler-TyClassRef-Foreign) - - [TyClassRef.Local](#lambdabuffers-compiler-TyClassRef-Local) - - [TyDef](#lambdabuffers-compiler-TyDef) - - [TyName](#lambdabuffers-compiler-TyName) - - [TyRef](#lambdabuffers-compiler-TyRef) - - [TyRef.Foreign](#lambdabuffers-compiler-TyRef-Foreign) - - [TyRef.Local](#lambdabuffers-compiler-TyRef-Local) - - [TyVar](#lambdabuffers-compiler-TyVar) - - [Tys](#lambdabuffers-compiler-Tys) - - [VarName](#lambdabuffers-compiler-VarName) - - - [Kind.KindRef](#lambdabuffers-compiler-Kind-KindRef) - -- [Scalar Value Types](#scalar-value-types) - - - - -
- -## compiler.proto - - - - - -### ClassConstraint -Class constraints - -A special constraint type denoting the constraints that occur on the rhs of -class definitions. Only used to specify super class constraints in a -`ClassDef`. - -Not to be confused with `Constraint` which denote type class rules. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| class_ref | [TyClassRef](#lambdabuffers-compiler-TyClassRef) | | Type class reference. | -| args | [TyVar](#lambdabuffers-compiler-TyVar) | repeated | Type variables quantified over `ClassDef` arguments. | - - - - - - - - -### ClassDef -Type class definition - -LambdaBuffers use type classes to talk about the various 'meanings' or -'semantics' we want to associate with the types in LambdaBuffers schemata. - -For instance, most types can have `Eq` semantics, meaning they can be -compared for equality. Other can have `Ord` semantics, meaning they can be -ordered. - -Using type classes and instance declarations, much like in Haskell, users can -specify the 'meaning' of each type they declare. For example, serialization -in LambdaBuffers is just another type class, it's treated the same as any -other type class. Concretely, if we wish to provide JSON serialization for -LambdaBuffers types, we declare such a type class and provide desired -semantic rules: - -```lbf -module Foo - -class JSON a - -sum Foo a b = Bar a | Baz b - -derive JSON (Foo a b) -``` - -Note that for each type class introduced, the Codegen machinery must be -updated to support said type class. In other words, it doesn't come for free -and for each new type class, a Codegen support must be implemented for any -`InstanceClause` declared by the user. Once all the `InstanceClause`s have an -implementation provided, all the `Derive`d implementation come for free. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| class_name | [ClassName](#lambdabuffers-compiler-ClassName) | | Type class name. | -| class_args | [TyArg](#lambdabuffers-compiler-TyArg) | repeated | Type class arguments. Class with no arguments is a trivial class. Compiler MAY report an error. TODO(bladyjoker): MultipleClassArgError. | -| supers | [ClassConstraint](#lambdabuffers-compiler-ClassConstraint) | repeated | Superclass constraints. | -| documentation | [string](#string) | | Documentation elaborating on the type class. | -| source_info | [SourceInfo](#lambdabuffers-compiler-SourceInfo) | | Source information. | - - - - - - - - -### ClassName -Type class name - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| name | [string](#string) | | Name ::= [A-Z]+[A-Za-z0-9_]* | -| source_info | [SourceInfo](#lambdabuffers-compiler-SourceInfo) | | Source information. | - - - - - - - - -### CompilerError -Compiler Error - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| proto_parse_errors | [ProtoParseError](#lambdabuffers-compiler-ProtoParseError) | repeated | Errors occurred during proto parsing. | -| naming_errors | [NamingError](#lambdabuffers-compiler-NamingError) | repeated | Errors occurred during naming checking. | -| kind_check_errors | [KindCheckError](#lambdabuffers-compiler-KindCheckError) | repeated | Errors occurred during kind checking. | -| ty_class_check_errors | [TyClassCheckError](#lambdabuffers-compiler-TyClassCheckError) | repeated | Errors occurred during type class checking. | -| internal_errors | [InternalError](#lambdabuffers-compiler-InternalError) | repeated | Errors internal to the compiler implementation. | - - - - - - - - -### CompilerInput -Compiler Input - -Compiler Input is a fully self contained list of modules, the entire -compilation closure needed by the Compiler to perform its task. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| modules | [Module](#lambdabuffers-compiler-Module) | repeated | Modules to compile. Duplicate modules MUST be reported with `ProtoParseError.MultipleModuleError`. | - - - - - - - - -### CompilerOutput -Output of the Compiler. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| compiler_error | [CompilerError](#lambdabuffers-compiler-CompilerError) | | | -| compiler_result | [CompilerResult](#lambdabuffers-compiler-CompilerResult) | | | - - - - - - - - -### CompilerResult -Compiler Result ~ a successful Compilation Output. - - - - - - - - -### ConstrName -Sum type constructor name - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| name | [string](#string) | | Name ::= [A-Z]+[A-Za-z0-9_]* | -| source_info | [SourceInfo](#lambdabuffers-compiler-SourceInfo) | | Source information. | - - - - - - - - -### Constraint -Constraint term - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| class_ref | [TyClassRef](#lambdabuffers-compiler-TyClassRef) | | Name of the type class. | -| args | [Ty](#lambdabuffers-compiler-Ty) | repeated | Constraint arguments. Constraint with no arguments is a trivial constraint. Compiler MAY report an error. | -| source_info | [SourceInfo](#lambdabuffers-compiler-SourceInfo) | | Source information. | - - - - - - - - -### Derive -Derive statement - -Derive statements enable user to specify 'semantic' rules for their types much -like `InstanceClause`s do. However, the Codegen will be able to derive an -implementation for any such constraint. - -```lbf -module Prelude - -class Eq a - -sum Maybe a = Just a | Nothing - -derive Eq (Maybe a) -``` - -The rule installed for the derive statement is: - -```prolog -eq(maybe(A)) :- eq(just(A) | Nothing). -``` - -The rule relates the desired `Ty` term to its (lambda calculus) -'evaluated' form. - -> Currently, there's only support for deriving type class rules and -implementations for `Ty` terms of `Kind.KIND_REF_TYPE`. That means, -type classes like Ord and Eq... - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| constraint | [Constraint](#lambdabuffers-compiler-Constraint) | | Constraint to derive. | - - - - - - - - -### FieldName -Record type field name - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| name | [string](#string) | | Name ::= [a-z]+[A-Za-z0-9_]* | -| source_info | [SourceInfo](#lambdabuffers-compiler-SourceInfo) | | Source information. | - - - - - - - - -### InstanceClause -Instance clause - -Instance clauses enable users to specify ad-hoc 'semantic' rules for their -types. Each such instance must be supported explicitly in the Codegen by -providing runtime implementations. - -This rule form is used when declaring 'opaque' implementations on `Opaque` -types. - -```lbf -module Prelude - -class Eq a - -opaque Maybe a - -instance Eq a => Eq (Maybe a) -``` - -The rule installed for the clause is: - -```prolog -eq(maybe(A)) :- eq(A). -``` - -The instance clause is verbatim added to the rule set. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| head | [Constraint](#lambdabuffers-compiler-Constraint) | | Head of the clause that holds only when the `body` holds. Type variables introduced in the head of the rule become available in the scope of the body of the rule. | -| constraints | [Constraint](#lambdabuffers-compiler-Constraint) | repeated | Instance (rule) body, conjunction of constraints. | -| source_info | [SourceInfo](#lambdabuffers-compiler-SourceInfo) | | Source information. | - - - - - - - - -### InternalError -Errors internal to the implementation. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| msg | [string](#string) | | Error message. | -| source_info | [SourceInfo](#lambdabuffers-compiler-SourceInfo) | | Source information if meaningful. | - - - - - - - - -### Kind -Kinds - -A type of a type is called a 'kind'. -In Lambda Buffers, all type terms, namely TyArg, TyVar, TyRef, TyApp and TyAbs, -are either of kind `Type` or `Type -> Type` and `Type -> Type -> Type` -etc. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| kind_ref | [Kind.KindRef](#lambdabuffers-compiler-Kind-KindRef) | | | -| kind_arrow | [Kind.KindArrow](#lambdabuffers-compiler-Kind-KindArrow) | | | - - - - - - - - -### Kind.KindArrow -A kind arrow. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| left | [Kind](#lambdabuffers-compiler-Kind) | | | -| right | [Kind](#lambdabuffers-compiler-Kind) | | | - - - - - - - - -### KindCheckError -Kind checking errors. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| unbound_ty_ref_error | [KindCheckError.UnboundTyRefError](#lambdabuffers-compiler-KindCheckError-UnboundTyRefError) | | | -| unbound_ty_var_error | [KindCheckError.UnboundTyVarError](#lambdabuffers-compiler-KindCheckError-UnboundTyVarError) | | | -| unification_error | [KindCheckError.UnificationError](#lambdabuffers-compiler-KindCheckError-UnificationError) | | | -| cyclic_kind_error | [KindCheckError.CyclicKindError](#lambdabuffers-compiler-KindCheckError-CyclicKindError) | | | -| inconsistent_type_error | [KindCheckError.InconsistentTypeError](#lambdabuffers-compiler-KindCheckError-InconsistentTypeError) | | | - - - - - - - - -### KindCheckError.CyclicKindError -A cyclic kind was encountered. Infinite kinds like this are not acceptable, -and we do not support them. We could not construct infinite kind in ty_def. - -As the implementation currently stands such an error is (most likely) not -representable - therefore not reachable. Such an error would usually occur -for a term like: λa. a a - in which case the inference would try to unify -two kinds of the form: m and m -> n - because m appears in both terms - -the cyclic unification error would be thrown. - -In the case of LambdaBuffers - such an error is not (currently) achievable -as the kind of the variable is given by the context - (i.e. λa : m . a a, -where m is a kind) therefore the unification would fail with Unification -Error. Nevertheless - future features might require it. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| ty_def | [TyDef](#lambdabuffers-compiler-TyDef) | | | -| module_name | [ModuleName](#lambdabuffers-compiler-ModuleName) | | | - - - - - - - - -### KindCheckError.InconsistentTypeError -The actual_kind differs from the expected_kind. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| module_name | [ModuleName](#lambdabuffers-compiler-ModuleName) | | | -| ty_def | [TyDef](#lambdabuffers-compiler-TyDef) | | | -| actual_kind | [Kind](#lambdabuffers-compiler-Kind) | | | -| expected_kind | [Kind](#lambdabuffers-compiler-Kind) | | | - - - - - - - - -### KindCheckError.UnboundTyRefError -Unbound type reference ty_ref detected in term ty_def. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| module_name | [ModuleName](#lambdabuffers-compiler-ModuleName) | | | -| ty_def | [TyDef](#lambdabuffers-compiler-TyDef) | | | -| ty_ref | [TyRef](#lambdabuffers-compiler-TyRef) | | | - - - - - - - - -### KindCheckError.UnboundTyVarError -Unbound variable ty_var detected in term ty_def. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| module_name | [ModuleName](#lambdabuffers-compiler-ModuleName) | | | -| ty_def | [TyDef](#lambdabuffers-compiler-TyDef) | | | -| ty_var | [TyVar](#lambdabuffers-compiler-TyVar) | | | - - - - - - - - -### KindCheckError.UnificationError -In ty_def an error has occurred when trying to unify kind ty_kind_lhs -with ty_kind_rhs. - -FIXME(cstml): Add source of constraint to the error such that user can see -where the constraint was generated - therefore where the error precisely -is. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| module_name | [ModuleName](#lambdabuffers-compiler-ModuleName) | | | -| ty_def | [TyDef](#lambdabuffers-compiler-TyDef) | | | -| ty_kind_lhs | [Kind](#lambdabuffers-compiler-Kind) | | | -| ty_kind_rhs | [Kind](#lambdabuffers-compiler-Kind) | | | - - - - - - - - -### Module -Module - -A module encapsulates type, class and instance definitions. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| module_name | [ModuleName](#lambdabuffers-compiler-ModuleName) | | Module name. | -| type_defs | [TyDef](#lambdabuffers-compiler-TyDef) | repeated | Type definitions. Duplicate type definitions MUST be reported with `ProtoParseError.MultipleTyDefError`. | -| class_defs | [ClassDef](#lambdabuffers-compiler-ClassDef) | repeated | Type class definitions. Duplicate class definitions MUST be reported with `ProtoParseError.MultipleClassDefError`. | -| instances | [InstanceClause](#lambdabuffers-compiler-InstanceClause) | repeated | Type class instance clauses. | -| derives | [Derive](#lambdabuffers-compiler-Derive) | repeated | Type class derive statements. | -| imports | [ModuleName](#lambdabuffers-compiler-ModuleName) | repeated | Imported modules the Compiler consults when searching for type class rules. TODO(bladyjoker): Rename to ruleImports. Duplicate imports MUST be reported with `ProtoParseError.MultipleImportError`. | -| source_info | [SourceInfo](#lambdabuffers-compiler-SourceInfo) | | Source information. | - - - - - - - - -### ModuleName -Module name - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| parts | [ModuleNamePart](#lambdabuffers-compiler-ModuleNamePart) | repeated | Parts of the module name denoting a hierarchichal namespace. | -| source_info | [SourceInfo](#lambdabuffers-compiler-SourceInfo) | | Source information. | - - - - - - - - -### ModuleNamePart -Module name part - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| name | [string](#string) | | Name ::= [A-Z]+[A-Za-z0-9_]* | -| source_info | [SourceInfo](#lambdabuffers-compiler-SourceInfo) | | Source information. | - - - - - - - - -### NamingError -Naming error message - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| module_name_err | [ModuleNamePart](#lambdabuffers-compiler-ModuleNamePart) | | | -| ty_name_err | [TyName](#lambdabuffers-compiler-TyName) | | | -| var_name_err | [VarName](#lambdabuffers-compiler-VarName) | | | -| constr_name_err | [ConstrName](#lambdabuffers-compiler-ConstrName) | | | -| field_name_err | [FieldName](#lambdabuffers-compiler-FieldName) | | | -| class_name_err | [ClassName](#lambdabuffers-compiler-ClassName) | | | - - - - - - - - -### Opaque -Opaque type. - -A type that has an `Opaque` body represents a 'built-in' or a 'primitive' type -that's handled by the semantics 'under the hood'. It's called 'opaque' to denote -the fact that the Compiler has no knowledge of its structure, and relies that -the necessary knowledge is implemented elsewhere. The Codegen modules for any -target language have to be able to handle such types specifically and map to -existing value level representations and corresponding types. - -Codegen modules would have to implement support for such defined types, for -example: -- In Python `Set a` would map to `set()` from the standard library, -- In Haskell `Set a` would map to `containers`.Data.Set.Set type. - -Every `Opaque` type has to be considered deliberately for each language -environment targeted by Codegen modules. - -TODO(bladyjoker): Consider attaching explicit Kind terms to Opaques. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| source_info | [SourceInfo](#lambdabuffers-compiler-SourceInfo) | | Source information. | - - - - - - - - -### Product -A product type term. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| fields | [Ty](#lambdabuffers-compiler-Ty) | repeated | Fields in a products are types. | -| source_info | [SourceInfo](#lambdabuffers-compiler-SourceInfo) | | Source information. | - - - - - - - - -### ProtoParseError -All errors that occur because of Google Protocol Buffer's inability to -enforce certain invariants. -Some of invariance: -- using Proto `map` restricts users to `string` keys which impacts - API documentation, which is why `repeated` fields are used throughout, -- using Proto 'oneof' means users have to check if such a field is - set or report an error otherwise. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| multiple_module_error | [ProtoParseError.MultipleModuleError](#lambdabuffers-compiler-ProtoParseError-MultipleModuleError) | | | -| multiple_tydef_error | [ProtoParseError.MultipleTyDefError](#lambdabuffers-compiler-ProtoParseError-MultipleTyDefError) | | | -| multiple_classdef_error | [ProtoParseError.MultipleClassDefError](#lambdabuffers-compiler-ProtoParseError-MultipleClassDefError) | | | -| multiple_tyarg_error | [ProtoParseError.MultipleTyArgError](#lambdabuffers-compiler-ProtoParseError-MultipleTyArgError) | | | -| multiple_constructor_error | [ProtoParseError.MultipleConstructorError](#lambdabuffers-compiler-ProtoParseError-MultipleConstructorError) | | | -| multiple_field_error | [ProtoParseError.MultipleFieldError](#lambdabuffers-compiler-ProtoParseError-MultipleFieldError) | | | -| multiple_import_error | [ProtoParseError.MultipleImportError](#lambdabuffers-compiler-ProtoParseError-MultipleImportError) | | | -| one_of_not_set_error | [ProtoParseError.OneOfNotSetError](#lambdabuffers-compiler-ProtoParseError-OneOfNotSetError) | | | -| unknown_enum_error | [ProtoParseError.UnknownEnumError](#lambdabuffers-compiler-ProtoParseError-UnknownEnumError) | | | - - - - - - - - -### ProtoParseError.MultipleClassDefError -Multiple ClassDefs with the same ClassName were found in ModuleName. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| module_name | [ModuleName](#lambdabuffers-compiler-ModuleName) | | Module in which the error was found. | -| class_defs | [ClassDef](#lambdabuffers-compiler-ClassDef) | repeated | Conflicting class definitions. | - - - - - - - - -### ProtoParseError.MultipleConstructorError -Multiple Sum Constructors with the same ConstrName were found in -ModuleName.TyDef. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| module_name | [ModuleName](#lambdabuffers-compiler-ModuleName) | | Module in which the error was found. | -| ty_def | [TyDef](#lambdabuffers-compiler-TyDef) | | Type definition in which the error was found. | -| constructors | [Sum.Constructor](#lambdabuffers-compiler-Sum-Constructor) | repeated | Conflicting constructors. | - - - - - - - - -### ProtoParseError.MultipleFieldError -Multiple Record Fields with the same FieldName were found in -ModuleName.TyDef. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| module_name | [ModuleName](#lambdabuffers-compiler-ModuleName) | | Module in which the error was found. | -| ty_def | [TyDef](#lambdabuffers-compiler-TyDef) | | Type definition in which the error was found. | -| fields | [Record.Field](#lambdabuffers-compiler-Record-Field) | repeated | Conflicting record fields. | - - - - - - - - -### ProtoParseError.MultipleImportError - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| module_name | [ModuleName](#lambdabuffers-compiler-ModuleName) | | Module in which the error was found. | -| imports | [ModuleName](#lambdabuffers-compiler-ModuleName) | repeated | Conflicting module imports. | - - - - - - - - -### ProtoParseError.MultipleModuleError -Multiple Modules with the same ModuleName were found. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| modules | [Module](#lambdabuffers-compiler-Module) | repeated | Conflicting type definitions. | - - - - - - - - -### ProtoParseError.MultipleTyArgError -Multiple TyArgs with the same ArgName were found in ModuleName.TyDef. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| module_name | [ModuleName](#lambdabuffers-compiler-ModuleName) | | Module in which the error was found. | -| ty_def | [TyDef](#lambdabuffers-compiler-TyDef) | | Type definition in which the error was found. | -| ty_args | [TyArg](#lambdabuffers-compiler-TyArg) | repeated | Conflicting type abstraction arguments. | - - - - - - - - -### ProtoParseError.MultipleTyDefError -Multiple TyDefs with the same TyName were found in ModuleName. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| module_name | [ModuleName](#lambdabuffers-compiler-ModuleName) | | Module in which the error was found. | -| ty_defs | [TyDef](#lambdabuffers-compiler-TyDef) | repeated | Conflicting type definitions. | - - - - - - - - -### ProtoParseError.OneOfNotSetError -Proto `oneof` field is not set. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| message_name | [string](#string) | | Proto message name in which the `oneof` field is not set. | -| field_name | [string](#string) | | The `oneof` field that is not set. | - - - - - - - - -### ProtoParseError.UnknownEnumError -Proto `enum` field is unknown. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| enum_name | [string](#string) | | Proto `enum` name. | -| got_tag | [string](#string) | | The unknown tag for the `enum`. | - - - - - - - - -### Record -A record type term. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| fields | [Record.Field](#lambdabuffers-compiler-Record-Field) | repeated | Record fields. | -| source_info | [SourceInfo](#lambdabuffers-compiler-SourceInfo) | | Source information. | - - - - - - - - -### Record.Field -Field in a record type. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| field_name | [FieldName](#lambdabuffers-compiler-FieldName) | | Record field name. | -| field_ty | [Ty](#lambdabuffers-compiler-Ty) | | Field type. | - - - - - - - - -### SourceInfo -Frontend Source information - -Frontends are advised to include *Source* information to denote how their -Source* content maps to the *Compiler Input*. It's essential when reporting -Compiler* errors back to the Frontend. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| file | [string](#string) | | A filename denoting the Source file. | -| pos_from | [SourcePosition](#lambdabuffers-compiler-SourcePosition) | | Starting position in Source. | -| pos_to | [SourcePosition](#lambdabuffers-compiler-SourcePosition) | | End position in Source. | - - - - - - - - -### SourcePosition -Position in Source - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| column | [int32](#int32) | | Column index in the Source. | -| row | [int32](#int32) | | Row index in the Source. | - - - - - - - - -### Sum -A sum type term. - -A type defined as a Sum type is just like a Haskell algebraic data type and -represents a sum of products. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| constructors | [Sum.Constructor](#lambdabuffers-compiler-Sum-Constructor) | repeated | Sum type constructors. Empty `constructors` means `void` and means that the type can't be constructed. Compiler MAY report an error. Duplicate constructors MUST be reported with `ProtoParseError.MultipleConstructorError`. | -| source_info | [SourceInfo](#lambdabuffers-compiler-SourceInfo) | | Source information. | - - - - - - - - -### Sum.Constructor -Constructor of a Sum type is a Product type term. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| constr_name | [ConstrName](#lambdabuffers-compiler-ConstrName) | | Constructor name. | -| product | [Product](#lambdabuffers-compiler-Product) | | Product type term. | - - - - - - - - -### Ty -Type term - -A type term that ocurrs in bodies of type definitions (message TyDef): - -```lbf -sum Maybe a = Just a | Nothing - -sum Either a b = Left a | Right b - -sum SomeType a = Foo a (Maybe a) | Bar (Either (Maybe a) (SomeType a)) -``` - -or in instance declarations: - -```lbf -instance Eq (Maybe a) - -instance Eq (SomeType Int) - -instance (Eq (Maybe a), Eq (SomeType a)) Eq (Either (Maybe a) (SomeType a)) -``` - -Check out [examples](examples/tys.textproto). - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| ty_var | [TyVar](#lambdabuffers-compiler-TyVar) | | A type variable. | -| ty_app | [TyApp](#lambdabuffers-compiler-TyApp) | | A type application. | -| ty_ref | [TyRef](#lambdabuffers-compiler-TyRef) | | A type reference. | - - - - - - - - -### TyAbs -Type abstraction - -A type term that introduces type abstractions (ie. type functions). This -type term can only be introduced in the context of a -[type definition](@ref TyDef). - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| ty_args | [TyArg](#lambdabuffers-compiler-TyArg) | repeated | List of type variables. No type arguments means `delay` or `const ty_body`, meaning `TyAbs [] ty_body = ty_body`. Duplicate type arguments MUST be reported with `ProtoParseError.MultipleTyArgError`. | -| ty_body | [TyBody](#lambdabuffers-compiler-TyBody) | | Type body. | -| source_info | [SourceInfo](#lambdabuffers-compiler-SourceInfo) | | Source information. | - - - - - - - - -### TyApp -Type application - -A type term that applies a type abstraction to a list of arguments. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| ty_func | [Ty](#lambdabuffers-compiler-Ty) | | Type function. TODO(bladyjoker): Rename to ty_abs? | -| ty_args | [Ty](#lambdabuffers-compiler-Ty) | repeated | Arguments to apply. No arguments to apply means `force`, meaning `TyApp ty_func [] = ty_func`` | -| source_info | [SourceInfo](#lambdabuffers-compiler-SourceInfo) | | Source information. | - - - - - - - - -### TyArg -Type arguments - -Arguments in type abstractions. - -Type arguments and therefore type variables have kinds, the Compiler only -accepts `Type` kinded type arguments ans therefore type variables. - -However, to allow for future evolution if ever necessary, we attach the Kind -term to type arguments, even though the Compiler will reject any TyArg that's -not of kind `Type`. - -Note, this effectively means that lambda Buffers doesn't support higher-kinded -types (ie. HKT). - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| arg_name | [VarName](#lambdabuffers-compiler-VarName) | | Argument name corresponds to variable names. | -| arg_kind | [Kind](#lambdabuffers-compiler-Kind) | | Argument kind. | -| source_info | [SourceInfo](#lambdabuffers-compiler-SourceInfo) | | Source information. | - - - - - - - - -### TyBody -Type body. - -Lambda Buffers type bodies type terms that can only be specified in the -`TyAbs` context. It's a built-in type term that can only occur enclosed -within a `TyAbs` term which introduces `TyVar`s in the scope of the term. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| opaque | [Opaque](#lambdabuffers-compiler-Opaque) | | | -| sum | [Sum](#lambdabuffers-compiler-Sum) | | | -| product | [Product](#lambdabuffers-compiler-Product) | | | -| record | [Record](#lambdabuffers-compiler-Record) | | | - - - - - - - - -### TyClassCheckError -Type class checking errors. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| unbound_class_ref_err | [TyClassCheckError.UnboundClassRefError](#lambdabuffers-compiler-TyClassCheckError-UnboundClassRefError) | | | -| superclass_cycle_err | [TyClassCheckError.SuperclassCycleError](#lambdabuffers-compiler-TyClassCheckError-SuperclassCycleError) | | | -| import_not_found_err | [TyClassCheckError.ImportNotFoundError](#lambdabuffers-compiler-TyClassCheckError-ImportNotFoundError) | | | -| derive_opaque_err | [TyClassCheckError.DeriveOpaqueError](#lambdabuffers-compiler-TyClassCheckError-DeriveOpaqueError) | | | -| missing_rule_err | [TyClassCheckError.MissingRuleError](#lambdabuffers-compiler-TyClassCheckError-MissingRuleError) | | | -| overlapping_rules_err | [TyClassCheckError.OverlappingRulesError](#lambdabuffers-compiler-TyClassCheckError-OverlappingRulesError) | | | - - - - - - - - -### TyClassCheckError.DeriveOpaqueError -In `module_name` it wasn't possible to solve `constraint` because a -`sub_constraint` has been derived on an `Opaque` type. `Opaque` type can -only have an `InstanceClause` declared for them. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| module_name | [ModuleName](#lambdabuffers-compiler-ModuleName) | | | -| constraint | [Constraint](#lambdabuffers-compiler-Constraint) | | | -| sub_constraint | [Constraint](#lambdabuffers-compiler-Constraint) | | | - - - - - - - - -### TyClassCheckError.ImportNotFoundError -Import `missing` wasn't found in `module_name` - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| module_name | [ModuleName](#lambdabuffers-compiler-ModuleName) | | | -| missing | [ModuleName](#lambdabuffers-compiler-ModuleName) | | | - - - - - - - - -### TyClassCheckError.MissingRuleError -In `module_name` while trying to solve `constraint` it wasn't possible to -find a rule (`Derive` or `InstanceClause`) for `sub_constraint`. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| module_name | [ModuleName](#lambdabuffers-compiler-ModuleName) | | | -| constraint | [Constraint](#lambdabuffers-compiler-Constraint) | | | -| sub_constraint | [Constraint](#lambdabuffers-compiler-Constraint) | | | - - - - - - - - -### TyClassCheckError.OverlappingRulesError -In `module_name` while trying to solve `constraint` `overlaps` (`Derive` -or `InstanceClause`) were found that could be used to solve the -`sub_constraint`. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| module_name | [ModuleName](#lambdabuffers-compiler-ModuleName) | | | -| constraint | [Constraint](#lambdabuffers-compiler-Constraint) | | | -| sub_constraint | [Constraint](#lambdabuffers-compiler-Constraint) | | | -| overlaps | [TyClassCheckError.OverlappingRulesError.QHead](#lambdabuffers-compiler-TyClassCheckError-OverlappingRulesError-QHead) | repeated | | - - - - - - - - -### TyClassCheckError.OverlappingRulesError.QHead -NOTE(bladyjoker): This should rather be oneof `Derive` and -`InstanceClause`. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| module_name | [ModuleName](#lambdabuffers-compiler-ModuleName) | | | -| head | [Constraint](#lambdabuffers-compiler-Constraint) | | | - - - - - - - - -### TyClassCheckError.SuperclassCycleError -Superclass cycle `cycled_class_refs` was detected when checking a -class definition for `class_name` in module `module_name`. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| module_name | [ModuleName](#lambdabuffers-compiler-ModuleName) | | | -| class_name | [ClassName](#lambdabuffers-compiler-ClassName) | | | -| cycled_class_refs | [TyClassRef](#lambdabuffers-compiler-TyClassRef) | repeated | | - - - - - - - - -### TyClassCheckError.UnboundClassRefError -Unbound `class_ref` detected in `module_name`. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| module_name | [ModuleName](#lambdabuffers-compiler-ModuleName) | | | -| class_ref | [TyClassRef](#lambdabuffers-compiler-TyClassRef) | | | - - - - - - - - -### TyClassRef -Type class references - -It is necessary to know whether a type class is defined locally or in a -foreign module when referring to it in a constraint, this allows users (and -requires the frontend) to explicitly communicate that information. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| local_class_ref | [TyClassRef.Local](#lambdabuffers-compiler-TyClassRef-Local) | | | -| foreign_class_ref | [TyClassRef.Foreign](#lambdabuffers-compiler-TyClassRef-Foreign) | | | - - - - - - - - -### TyClassRef.Foreign -Foreign class reference. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| class_name | [ClassName](#lambdabuffers-compiler-ClassName) | | Foreign module class name. | -| module_name | [ModuleName](#lambdabuffers-compiler-ModuleName) | | Foreign module name. | -| source_info | [SourceInfo](#lambdabuffers-compiler-SourceInfo) | | Source information. | - - - - - - - - -### TyClassRef.Local -Local type reference. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| class_name | [ClassName](#lambdabuffers-compiler-ClassName) | | Local module class name. | -| source_info | [SourceInfo](#lambdabuffers-compiler-SourceInfo) | | Source information. | - - - - - - - - -### TyDef -Type definition - -A type definition consists of a type name and its associated type term. - -One way to look at it is that a type definition introduces a named 'type -abstraction' in the module scope. Concretely, `Either` can be considered a type -lambda of kind `Type -> Type -> Type`. - -In fact, type definitions are the only way to introduce such types. - -Once introduced in the module scope, type definitions are referred to using -[TyRef](@ref TyRef) term. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| ty_name | [TyName](#lambdabuffers-compiler-TyName) | | Type name. | -| ty_abs | [TyAbs](#lambdabuffers-compiler-TyAbs) | | Type term. | -| source_info | [SourceInfo](#lambdabuffers-compiler-SourceInfo) | | Source information. | - - - - - - - - -### TyName -Type name - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| name | [string](#string) | | Name ::= [A-Z]+[A-Za-z0-9_]* | -| source_info | [SourceInfo](#lambdabuffers-compiler-SourceInfo) | | Source information. | - - - - - - - - -### TyRef -Type reference - -A type term that denotes a reference to a type available that's declared -locally or in foreign modules. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| local_ty_ref | [TyRef.Local](#lambdabuffers-compiler-TyRef-Local) | | | -| foreign_ty_ref | [TyRef.Foreign](#lambdabuffers-compiler-TyRef-Foreign) | | | - - - - - - - - -### TyRef.Foreign -Foreign type reference. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| ty_name | [TyName](#lambdabuffers-compiler-TyName) | | Foreign module type name. | -| module_name | [ModuleName](#lambdabuffers-compiler-ModuleName) | | Foreign module name. | -| source_info | [SourceInfo](#lambdabuffers-compiler-SourceInfo) | | Source information. | - - - - - - - - -### TyRef.Local -Local type reference. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| ty_name | [TyName](#lambdabuffers-compiler-TyName) | | Local module type name. | -| source_info | [SourceInfo](#lambdabuffers-compiler-SourceInfo) | | Source information. | - - - - - - - - -### TyVar -Type variable - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| var_name | [VarName](#lambdabuffers-compiler-VarName) | | Variable name. | - - - - - - - - -### Tys -A list of type terms useful for debugging - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| ties | [Ty](#lambdabuffers-compiler-Ty) | repeated | | - - - - - - - - -### VarName -Type variable name - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| name | [string](#string) | | Name ::= [a-z]+ | -| source_info | [SourceInfo](#lambdabuffers-compiler-SourceInfo) | | Source information. | - - - - - - - - - - -### Kind.KindRef -A built-in kind. - -| Name | Number | Description | -| ---- | ------ | ----------- | -| KIND_REF_UNSPECIFIED | 0 | Unspecified kind SHOULD be inferred by the Compiler. | -| KIND_REF_TYPE | 1 | A `Type` kind (also know as `*` in Haskell) built-in. | - - - - - - - - - - -## Scalar Value Types - -| .proto Type | Notes | C++ | Java | Python | Go | C# | PHP | Ruby | -| ----------- | ----- | --- | ---- | ------ | -- | -- | --- | ---- | -| double | | double | double | float | float64 | double | float | Float | -| float | | float | float | float | float32 | float | float | Float | -| int32 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) | -| int64 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead. | int64 | long | int/long | int64 | long | integer/string | Bignum | -| uint32 | Uses variable-length encoding. | uint32 | int | int/long | uint32 | uint | integer | Bignum or Fixnum (as required) | -| uint64 | Uses variable-length encoding. | uint64 | long | int/long | uint64 | ulong | integer/string | Bignum or Fixnum (as required) | -| sint32 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) | -| sint64 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s. | int64 | long | int/long | int64 | long | integer/string | Bignum | -| fixed32 | Always four bytes. More efficient than uint32 if values are often greater than 2^28. | uint32 | int | int | uint32 | uint | integer | Bignum or Fixnum (as required) | -| fixed64 | Always eight bytes. More efficient than uint64 if values are often greater than 2^56. | uint64 | long | int/long | uint64 | ulong | integer/string | Bignum | -| sfixed32 | Always four bytes. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) | -| sfixed64 | Always eight bytes. | int64 | long | int/long | int64 | long | integer/string | Bignum | -| bool | | bool | boolean | boolean | bool | bool | boolean | TrueClass/FalseClass | -| string | A string must always contain UTF-8 encoded or 7-bit ASCII text. | string | String | str/unicode | string | string | string | String (UTF-8) | -| bytes | May contain any arbitrary sequence of bytes. | string | ByteString | str | []byte | ByteString | string | String (ASCII-8BIT) | - - diff --git a/docs/examples/Document.lbf b/docs/examples/Document.lbf new file mode 100644 index 00000000..8393ed08 --- /dev/null +++ b/docs/examples/Document.lbf @@ -0,0 +1,48 @@ +module Document + +-- Author +sum Author = Ivan | Jovan | Savo + +-- Reviewer +sum Reviewer = Bob | Alice + +-- Document +record Document a = { + author : Author, + reviewers : List Reviewer, + content : Chapter a + } + +-- Chapter +record Chapter a = { + content : a, + subChapters : List (Chapter a) + } + +-- Some actual content +sum RichContent = Image Image String | Gif Gif String | Text String + +sum Image = FunnyImage | BoringImage + +sum Gif = FunnyGif | InspiringGif + +-- Rich document + +prod RichDocument = (Document RichContent) + +-- # Some basic types + +-- ## We need a list type +sum List a = Nil | Cons a (List a) + +-- ## We need a Char type that is either a letter, number or punctuation +sum Char = Letter Letter | Number Number | Punctuation Punctuation + +sum Letter = A | B | C + +sum Number = Num0 | Num1 | Num2 + +sum Punctuation = Dot | Question + +-- ## String +prod String = (List Char) \ No newline at end of file diff --git a/docs/getting-started.md b/docs/getting-started.md new file mode 100644 index 00000000..3958b98f --- /dev/null +++ b/docs/getting-started.md @@ -0,0 +1,72 @@ +# Getting started + +## Installing Nix + +This repository relies heavily on the [Nix Package +Manager](https://nixos.org/download.html) for both development and package +distribution. + +To install run the following command: + +```sh +sh <(curl -L https://nixos.org/nix/install) --daemon +``` + +and follow the instructions. + +```sh +$ nix --version +nix (Nix) 2.8.0 +``` + +> NOTE: The repository should work with Nix version greater or equal to 2.8.0. + +Make sure to enable [Nix Flakes](https://nixos.wiki/wiki/Flakes#Enable_flakes) +and IFD by editing either `~/.config/nix/nix.conf` or `/etc/nix/nix.conf` on +your machine and add the following configuration entries: + +```yaml +experimental-features = nix-command flakes +allow-import-from-derivation = true +``` + +Optionally, to improve build speed, it is possible to set up a binary caches +maintained by IOHK and Plutonomicon by setting additional configuration entries: + +```yaml +substituters = https://cache.nixos.org https://iohk.cachix.org https://cache.iog.io https://public-plutonomicon.cachix.org +trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ= iohk.cachix.org-1:DpRUyj7h7V830dp/i6Nti+NEO2/nhblbov/8MW7Rqoo= public-plutonomicon.cachix.org-1:3AKJMhCLn32gri1drGuaZmFrmnue+KkKrhhubQk/CWc= +``` + +## Building and development + +To facilitate seamlessly moving between directories and associated Nix +development shells we use [direnv](https://direnv.net) and +[nix-direnv](https://github.com/nix-community/nix-direnv): + +To install both using `nixpkgs`: + +```sh +nix profile install nixpkgs#direnv +nix profile install nixpkgs#nix-direnv +``` + +Your shell and editors should pick up on the `.envrc` files in different +directories and prepare the environment accordingly. Use `direnv allow` to +enable the direnv environment and `direnv reload` to reload it when necessary. + +Additionally, throughout the repository one can use: + +```sh +$ pre-commit run --all +cabal-fmt............................................(no files to check)Skipped +fourmolu.................................................................Passed +hlint....................................................................Passed +markdownlint.............................................................Passed +nix-linter...............................................................Passed +nixpkgs-fmt..............................................................Passed +shellcheck...........................................(no files to check)Skipped +typos....................................................................Passed +``` + +To run all the code quality tooling specified in the [pre-commit-check config file](../pre-commit.nix) diff --git a/docs/haskell.md b/docs/haskell.md new file mode 100644 index 00000000..b8a4f643 --- /dev/null +++ b/docs/haskell.md @@ -0,0 +1,198 @@ +# LambdaBuffers to Haskell + +Let's take a look at how LambdaBuffers modules map into Haskell modules and how +LambdaBuffers type definitions map into Haskell type definitions. + +Note that in this chapter we work with a 'pure' LambdaBuffers module, no +`opaque`s or type clasess, to demonstrate how pure type definition mapping +works. + +We'll use the `lbf-to-haskell` CLI tool which is just a convenient wrapper over +the raw `lbf` CLI. We can get this tool by either loading the LambdaBuffers Nix +environment that comes packaged with all the CLI tools: + +```shell +$ nix develop github:mlabs-haskell/lambda-buffers#lb +$ lb