お金と単位
帳簿の額は、どれもいちばん小さい単位で数えた整数で、一つの移動は一つの単位で動きます。単位には、お金、キログラムのような量、名前を付けた数え方があり、ritsu のほかの言語は、帳簿の単位を自分の型の一つとして見ます。たとえば米ドルの帳簿は、規則が渡すセント単位の額を受け取り、税込でお金を持つ帳簿は、税込の額しか受け取りません。
いちばん小さい単位
unit 個 は個数を一つずつ、unit 円 は 1 円ずつ数えます。unit USD scale 2 は 1 セントずつ数え、帳簿に書く数(境界や移動の額)を小数 2 桁で書きます。境界の 12.50 は 1250 セントです。chobo doc も、chobo check が挙げる境界も、額をこの形で見せます。シナリオに書く額、chobo run が出す額、クライアントに渡す額は、整数のままです。額は 0 から 2⁶³ − 1(PostgreSQL や MySQL の bigint に入る範囲)まで、境界は −(2⁶³ − 1) から 2⁶³ − 1 までです。単位で書けない数があると、帳簿はエラーで止まります。
エラー[E011]: 数.book:6:12: 単位 `個` には小数を書けません(`0.5`)
6 | at least 0.5 refused as 在庫切れ
エラー[E011]: 数.book:9:11: `10.505` の小数は 3 桁ですが、単位 `USD` で書けるのは 2 桁までです
9 | at most 10.505 refused as 上限超え
エラー[E011]: 数.book:11:12: `-9223372036854775808` は書ける範囲を超えています。いちばん小さい単位で数えて、−(2⁶³ − 1) から 2⁶³ − 1 までです
11 | at least -9223372036854775808 refused as 枠超え
エラー[E011]: 数.book:17:8: 移動の額に負の数は書けません。向きを変えるなら from と to を入れ替えてください
17 | move -1 from 在庫(sku) to 客
一つの移動に、一つの単位
移動は、同じ単位の勘定から勘定へ、その単位の額を動かします。chobo は換算をしないので、単位をまたぐ移動はエラーになり、診断がそれぞれの側の単位を言います。
エラー[E010]: 単位.book:12:3: この移動の単位が合いません。元の勘定 `在庫` は `個`、先の勘定 `客` は `円`、額の `数` は `個` です。別の単位へ替えるなら、単位ごとに外の勘定を置き、二つの移動で書いてください
12 | move 数 from 在庫(sku) to 客
両替は、単位ごとに一つずつの二つの移動にし、それぞれ帳簿の外の勘定を通して書きます。二つの額は、どちらも呼ぶ側が計算します。単位は名前だけで見分けるので、ホールの席と倉庫の品を分けておきたいなら、unit 個 の横に unit 席 を宣言します。
税込と税抜
通貨の名前の単位はお金の単位で、最後に税込か税抜か(incl_tax、excl_tax)を書けます。
帳簿の中では何も変わりません。額の数え方も境界も同じで、ビルドが書くコードも、書かないときと同じです。この区別が効くのは、規則やワークフローから帳簿に額が入ってくるところで、そこでは渡す側も同じ区別を言わなければなりません。税込の単位は税込の額を、税抜の単位は税抜の額を、区別を書かない単位は区別の無い額を受け取ります。こうして、一つの勘定に税込の額と税抜の額が混ざらないようにしています。お金でない単位には、どちらも書けません。
エラー[E014]: 税区分.book:4:8: 単位 `個` はお金の単位ではないので、`incl_tax` を書けません
4 | unit 個 incl_tax
ヒント: `incl_tax` を外してください。税込か税抜かを書けるのは、通貨の名前の単位(円と JPY は scale 0、ほかの通貨は scale 0 か 2)だけです
ほかの言語から見た単位
帳簿は自分の単位を、rulec が書くのと同じ単位として、ritsu のほかの言語に渡します。
| 帳簿の単位 | rulec と dandori から見た型 |
|---|---|
通貨の名前(円、JPY、ISO 4217 のコード、銭、USDc)で scale 0 |
そのお金。money[円]、税込か税抜を書けば money[円, incl_tax] |
円 と JPY のほかの通貨の名前で scale 2 |
その 100 分の 1 の単位。unit USD scale 2 は money[USDc] |
質量、長さ、面積、体積、時間の単位(g、kg、L、h)で scale 0 |
その単位。たとえば mass[kg] |
それ以外(個、席、pt、scale 2 の円、℃、℉、dB) |
名前を付けた数え方。同じ名前の単位とだけ同じになる |
円の 100 分の 1 は 銭 なので、scale 2 の円は、chobo の中だけの数え方になります。個 と 席 は互いに別の単位で、kg は規則と同じキログラムです。温度と音の大きさは足し引きしないので、勘定のあいだを動きません。unit ℃ は ℃ という名前の数え方で、規則の temperature[℃] は、その単位の額になりません。℃ と ℉ は、ほかの言語と同じく、単位の名前を書く所(unit ℃、: ℃)に書け、名前の中には書けません。
dandori のワークフローが帳簿の操作を呼ぶところでは、タスクの額の型が、この表のとおりの帳簿の単位になります。たとえば日本語の版の返金の例では、額 が money[円] です。在庫の引当の例の 数 は数え方なので、int です。帳簿に違う型を渡すタスクは dandori の E016 になり、違う単位や違う税区分の規則の出力をそのタスクに渡すと dandori の E003 になります。どちらも、帳簿と規則とワークフローを一緒に読む ritsu check が出します。ritsu check は、ほかに二つのことも確かめます。規則が返しうる額が、chobo の受け取る 0 以上に収まるか(ritsu の E203)と、その額で振替が拒否されうる理由を、タスクが処理しているかです(ほかの言語と組み合わせる)。
ritsu gen がプロジェクトから書くパッケージでは、クライアントは、お金と量の額を、パッケージの単位の型で受け取ります。規則が返すのと同じ型です。日本語の版の返金の例の 額 はそこでは units.Yen で、手で書いたコードが違う単位や違う税区分の規則の額を渡すと、そのコードの言語の型の検査が止めます(ワークフローを通さずに規則と帳簿を使う)。数え方の単位の額と残高は、パッケージの中でも素の整数です。
帳簿は計算しない
振替は額を渡されて動きます。額を決めるために残高を読むことも、何かを足し合わせることもしません。手数料、率、端数の丸めは、呼ぶ側か、呼ぶ側が使う rulec の規則の仕事です。「手数料は代金の 10%」は勘定の境界ではありません。マーケットプレイスの例は、店の取り分と手数料を二つの額として受け取ります。二つを足すと買い手が払った額になり、どちらも呼ぶ前に計算しておきます。chobo が決めるのは、振替を通すか、通さないならどの境界の理由で拒否するかだけです。だから、拒否されうる理由を、何も走らせる前に全部並べられます。