Primitive Types¶
This document provides an overview of the primitive types used in plain text accounting specifications.
Overview¶
Plain text accounting systems build on a small set of primitive types. These types are format-agnostic and define the foundational data representations.
Type Catalog¶
| Type | Document | Description |
|---|---|---|
| Decimal | decimal.md | Exact decimal numbers for financial calculations |
| Date | date.md | Calendar dates for directive ordering |
| String | string.md | Text values for narrations, payees, metadata |
| Unicode | unicode.md | Character encoding and normalization |
Type Hierarchy¶
Value
├── Scalar
│ ├── Number
│ │ └── Decimal
│ ├── Date
│ ├── String
│ └── Boolean
└── Composite
├── Amount (Decimal + Commodity)
├── Position (Amount + optional Cost)
└── Posting (Account + Position + ...)
Common Properties¶
Immutability¶
All primitive values are immutable. Operations create new values rather than modifying existing ones:
# Good: create new value
new_amount = Amount(old_amount.number + 10, old_amount.commodity)
# Bad: mutation (not supported)
old_amount.number += 10 # Error
Equality¶
Each type defines equality semantics:
| Type | Equality Rule |
|---|---|
| Decimal | Numeric value equality (100 == 100.00) |
| Date | Same calendar day |
| String | Byte-for-byte equality after normalization |
| Boolean | Logical equality |
Ordering¶
Types that support ordering:
| Type | Ordering |
|---|---|
| Decimal | Numeric ordering |
| Date | Chronological ordering |
| String | Lexicographic (implementation-defined) |
| Boolean | FALSE < TRUE |
Serialization¶
All types have defined text representations:
| Type | Example |
|---|---|
| Decimal | 123.45 |
| Date | 2024-01-15 |
| String | "Hello World" |
| Boolean | TRUE / FALSE |
Type Coercion¶
Implicit Coercion¶
Limited implicit coercion is allowed:
| From | To | Rule |
|---|---|---|
| Integer | Decimal | Always allowed |
| Decimal | String | For display only |
Explicit Coercion¶
Other conversions require explicit operations:
# String to Decimal
decimal = parse_decimal("123.45")
# Date to String
string = date.isoformat()
Null Values¶
No Implicit Nulls¶
Types do not have implicit null values. Optional fields use explicit optionality:
# Optional payee
payee: Optional[String] # None or String
# Required narration
narration: String # Always present
Omission vs. Empty¶
| Concept | Representation |
|---|---|
| Omitted | Field not present |
| Empty string | "" |
| Zero | 0 or 0.00 |
Validation¶
Type Validation¶
Each type has validation rules:
| Type | Validation |
|---|---|
| Decimal | Finite, within precision limits |
| Date | Valid calendar date |
| String | Valid encoding, no control characters |
| Boolean | TRUE or FALSE only |
Error Messages¶
Type errors include the expected type:
ERROR: Invalid type
--> ledger.beancount:42:15
|
42 | quantity: "not a number"
| ^^^^^^^^^^^^^^
|
= expected: Decimal
= got: String
Implementation Notes¶
Memory Representation¶
Implementations SHOULD use efficient representations:
| Type | Suggested Implementation |
|---|---|
| Decimal | Fixed-point or arbitrary-precision decimal |
| Date | Integer (days since epoch) or struct |
| String | UTF-8 bytes with interning |
| Boolean | Single byte or bit |
Interning¶
Frequently-used strings (account names, commodities) SHOULD be interned for memory efficiency and fast comparison.