Contracts now live directly on definitions via @ / =@ annotations and
travel automatically with exported values.
- Remove !export from lexer/parser/AST/evaluator/manifest/resolver and CLI.
- Simplify workspace module export logic: export all top-level local
definitions by default.
- Update Frontend.ContractDesugar:
- Named binder annotations (x@nat?) expand to per-argument withContract.
- Phantom annotations (@nat?) expand to a local raw helper plus a wrapper,
keeping fixed points shared and only depending on withContract.
- Merge lib/guardedBase.tri into lib/base.tri and annotate partial/sensitive
base functions: head, tail, last, add, sub, mul, div, mod, pow, min,
max, length, sum, product.
- Add check contract helper to lib/base.tri.
- Update demos/contractBasics.tri and README to reflect @/=@-only design.
- Update test suite: remove guardedBase import, replace explicit !export
test with a test verifying that contract annotations on an exported
definition are enforced on import.
- Fix remaining base.tri definitions (div/mod/pow) to stay point-free.
101 lines
3.7 KiB
Markdown
101 lines
3.7 KiB
Markdown
# tricu
|
|
|
|
## Introduction
|
|
|
|
tricu (pronounced "tree-shoe") is an experimental programming language written in Haskell. It is fundamentally based on the application of [Triage Calculus](https://olydis.medium.com/a-visual-introduction-to-tree-calculus-2f4a34ceffc2), an extended form of [Tree Calculus](https://github.com/barry-jay-personal/typed_tree_calculus/blob/main/typed_program_analysis.pdf). I refer to this "family" of calculi as TC below.
|
|
|
|
tricu is the word for "tree" in Lojban: `(x1) is a tree of species/cultivar (x2)`.
|
|
|
|
In the `ext/` directory there are implementations of TC evaluators and tooling in other languages. Here be dragons; beware.
|
|
|
|
While my original implementation was hand-written, I have since fully embraced the slopmachine for this project. Nothing is stable or sacred. We will discover sanity at the end of the journey but we won't strive for it until then. The `main` branch will see my latest thoughts and experiments. Emphasis on "AUTHOR DISCLAIMS ALL WARRANTIES" from the LICENSE.
|
|
|
|
This README.md is 100% human written. No other .md file will be until stabilization.
|
|
|
|
## Acknowledgements
|
|
|
|
Tree Calculus was discovered by [Barry Jay](https://github.com/barry-jay-personal/blog). The addition of Triage rules were suggested by [Johannes Bader](https://johannes-bader.com/). Johannes is also the creator of [treecalcul.us](https://treecalcul.us) which has a great intuitive code playground using his language LambAda.
|
|
|
|
## REPL examples
|
|
|
|
```
|
|
tricu < -- Anything after `--` on a single line is a comment
|
|
tricu < id = (a : a) -- Lambda abstraction is eliminated to tree calculus terms
|
|
tricu < head (map (i : append i " world!") [("Hello, ")])
|
|
tricu > "Hello, world!"
|
|
tricu < id (head (map (i : append i " world!") [("Hello, ")]))
|
|
tricu > "Hello, world!"
|
|
|
|
tricu < -- Intensionality! We can inspect the structure of a function or data.
|
|
tricu < triage = (a b c : t (t a b) c)
|
|
tricu < test = triage "Leaf" (z : "Stem") (a b : "Fork")
|
|
tricu < test (t t)
|
|
tricu > "Stem"
|
|
|
|
tricu < -- We can even convert a term back to source code (/demos/toSource.tri)
|
|
tricu < toSource not?
|
|
tricu > "(t (t (t t) (t t t)) (t t (t t t)))"
|
|
tricu < -- or calculate its size (/demos/size.tri)
|
|
tricu < size not?
|
|
tricu > 12
|
|
```
|
|
|
|
## Installation and Use
|
|
|
|
You can easily build and run this project using [Nix](https://nixos.org/download/).
|
|
|
|
- Quick Start (REPL):
|
|
- `nix run git+https://git.eversole.co/James/tricu`
|
|
- Build executable in `./result/bin`:
|
|
- `nix build git+https://git.eversole.co/James/tricu`
|
|
|
|
`./result/bin/tricu --help`
|
|
|
|
## Usage
|
|
|
|
### CLI
|
|
|
|
Evaluate one or more files:
|
|
|
|
```sh
|
|
tricu eval program.tri
|
|
tricu eval --format decode program.tri
|
|
tricu eval --output result.txt program.tri
|
|
```
|
|
|
|
Contract annotations (`@` and `=@`) attach guards directly to definitions.
|
|
When a workspace module is built, those guarded definitions become the
|
|
exported values, so contracts travel with imports automatically.
|
|
|
|
Compile/import/export Arboricx bundles:
|
|
|
|
```sh
|
|
tricu arboricx compile --file program.tri --output program.arboricx
|
|
tricu arboricx import --file program.arboricx --module program
|
|
tricu arboricx export --module prelude --output prelude.arboricx
|
|
```
|
|
|
|
Inspect store aliases:
|
|
|
|
```sh
|
|
tricu store alias list --kind modules
|
|
tricu store alias get --kind modules prelude
|
|
```
|
|
|
|
### REPL
|
|
|
|
Running `tricu` with no subcommand starts the REPL. The REPL uses the same
|
|
filesystem content store and workspace module loader as the CLI.
|
|
|
|
Useful commands:
|
|
|
|
```text
|
|
!load FILE load/evaluate a .tri file without printing a result
|
|
!store [PATH] show or set the content-addressed store
|
|
!format decode set output format by name
|
|
!env list current in-memory bindings
|
|
```
|
|
|
|
`!load` supports filename tab completion. Normal REPL input also supports tab
|
|
completion for names currently in the REPL environment.
|