Libraries and Using
Cambrian offers two complementary ways to reuse pure helpers: named
library blocks and using … for T method-call sugar.
library Name { … }
A library is a named scope of pure fn, const, and type items only. Bodies
may not touch entity state, msg::*, or temporal references — the same purity
envelope as a free pure fn. Like any pure fn, library functions have no
where clause; put preconditions on the calling route.
library FeeMath {
const BPS: U256 = 10000
pure fn fee(amount: U256, rate_bps: U256) -> U256 {
amount * rate_bps / BPS
}
pure fn net(amount: U256, rate_bps: U256) -> U256 {
amount - fee(amount, rate_bps)
}
}
using FeeMath for U256;
entity Vault {
routes {
deposit(amount: U256) => []
}
m_balance: U256 {
in deposit(amount) => m_balance + amount.net(30)
}
m_fees: U256 {
in deposit(amount) => m_fees + FeeMath.fee(amount, 30)
}
}
Call library functions with a qualifier (FeeMath.fee(amount, 30)), or as
methods attached via using (amount.net(30), below).
using Lib for T
using FeeMath for U256; in the example above attaches every suitable
function from the library as a method on U256, so amount.net(30) means
FeeMath.net(amount, 30).
recv.fn(args) rewrites to Lib.fn(recv, args) (or the free pure fn form)
before codegen. Chained receiver calls such as amount.net(30).net(10) work
when each step’s return type matches the next receiver, and a chain may
also start from a qualified call (FeeMath.fee(a, b).net(10)).
using { fn1, fn2 } for T
Attach selected free pure fns without a library wrapper:
pure fn double(x: U256) -> U256 { x * 2 }
pure fn triple(x: U256) -> U256 { x * 3 }
using { double, triple } for U256;
entity Foo {
routes {
bump() => []
}
m_n: U256 {
in bump() => m_n.double().triple()
}
}
Rules of thumb
- The first parameter of each attached function must match the
fortype. - When the
fortype isVec,HashMap, orOption, method names must not collide with that type’s built-in methods (len,push,insert,exists, …). - Libraries and free
pure fns may live in imported.camfiles. See Program Structure and the Contract Standard Library.
Lowering
On EVM, each Cambrian library becomes a Solidity library with
internal pure (or equivalent) functions. Call sites use LibName.fn(args).
Free pure fns outside a library remain top-level Solidity helpers.
On Lean, a library is flattened into ordinary pure functions named
Lib_fn (a library const becomes a zero-argument function), and every
qualified or using call is rewritten to call them.