Constants
Lithe has no constant declaration. A pure function with no parameters is a named constant, and the compiler folds it to a literal. That covers every use of Solidity's constant: numbers, hashes, and the length of a fixed list.
constants.lithe
(* A constant is a pure function of no arguments. It compiles to the literal. *)
import "std/address";
import "std/crypto";
import "std/int";
import "std/uint";
storage is record {
feeBps : uint;
admins : list(address, maxAdmins());
}
pure function maxFeeBps() : uint is
1_000
pure function denominator() : uint is
10_000
(* The hash of a literal is a constant too. *)
pure function pauserRole() : bytes32 is
Crypto.keccak256("PAUSER_ROLE")
(* A named constant can be a fixed list's length. *)
pure function maxAdmins() : uint is
3
error FeeTooHigh of uint;
external function setFee(const feeBps : uint)
raises FeeTooHigh
is {
assert(feeBps <= maxFeeBps(), FeeTooHigh(feeBps));
storage.feeBps := feeBps;
}
external view function feeOn(const amount : uint) : uint is
amount * storage.feeBps / denominator()
(* Built-in constants take their width from context. *)
external pure function limits() : (uint, uint16, int, address) is
(Uint.max, Uint.max, Int.max, Address.zero)1_000uses_as a digit separator.Uint.maxistype(uint256).max, or the maximum of whatever width the context expects. Herelimitsreturns it both as auintand as auint16.Crypto.keccak256("PAUSER_ROLE")compiles to the 32-byte hash, so a role id or an EIP-712 typehash is written as its preimage, not pasted in.- A fixed list's length can be a named constant,
M.n()from a module, or arithmetic over those:list(address, maxAdmins()),list(uint, maxAdmins() * 2). - Arithmetic on constants is checked when the contract compiles:
maxFeeBps() * Uint.maxis a compile error, not a panic at run time.

