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.
26 lines
906 B
Plaintext
26 lines
906 B
Plaintext
!import "prelude" !Local
|
|
|
|
-- Custom contract combinators built directly on matchResult.
|
|
myAndC = (c1 c2 value rest :
|
|
matchResult
|
|
(msg _ : contractErr msg rest)
|
|
(v _ : c2 v rest)
|
|
(c1 value rest))
|
|
|
|
-- Plain predicates lifted into contracts with a diagnostic message.
|
|
natural? = guardC "natural" (n : gte? n 0)
|
|
nonZero? = guardC "non-zero" (n : not? (isZero? n))
|
|
|
|
-- Phantom annotations let point-free definitions carry their own contracts.
|
|
-- The base library now uses the same syntax, so head/tail/div etc. are
|
|
-- guarded by default.
|
|
myHead @(nonEmptyListOf anyC) =@anyC head
|
|
myTail @(listOf anyC) =@(listOf anyC) tail
|
|
myDiv @natural? @(myAndC natural? nonZero?) =@natural? div
|
|
|
|
-- The `check` helper applies a contract to any value and returns the
|
|
-- checked value (or the diagnostic message on failure).
|
|
checkedSuccessor = check natural? (add 1 2)
|
|
|
|
main = pair checkedSuccessor (myDiv 10 2)
|