Types ===== Symbolic provides a numeric hierarchy built on arbitrary-precision arithmetic, a Unicode string type, ordered and unordered collection types, and an optional gradual type-annotation system. ---- Numeric Types ------------- All numeric types derive from ``Number``, which provides arithmetic, comparison, trigonometric, and algebraic operations uniformly across the hierarchy. Integer ~~~~~~ Arbitrary-precision integers. Division of two integers returns a ``Fraction``, not a truncated integer: .. code-block:: symbolic a = 42 b = -17 c = 10 ^ 100 # arbitrarily large d = 0xFF # hexadecimal literal e = 0b1010_1111 # binary literal with separator print(a + b) # 25 print(10 / 3) # 10/3 (Fraction, not 3) print(10 // 3) # 3 (floor division returns Integer) Float ~~~~ Arbitrary-precision floating-point numbers backed by ``mpmath.mpf``. The working precision defaults to 15 significant digits and adapts to the precision of the literal: .. code-block:: symbolic x = 3.14159265358979 y = 6.022e23 z = 1.5e-10 # Precision-controlled block @$precision 50 { result = x ^ 2; } Fraction ~~~~~~~ Exact rational numbers. Created automatically by integer division and maintained in lowest terms: .. code-block:: symbolic r = 10 / 3 # 10/3 s = 1 / 2 + 1/3 # 5/6 print(r.numerator) # 10 print(r.denominator) # 3 Complex ~~~~~~ Arbitrary-precision complex numbers using ``mpmath.mpc``. The imaginary unit is ``i``: .. code-block:: symbolic z1 = 3 + 4i z2 = 2.5 - 1.7i z3 = 1i # pure imaginary print(|z1|) # 5.0 — magnitude using pipe-absolute syntax print(z1*) # 3-4i — complex conjugate (postfix complement) print(z1.real) # 3 print(z1.imag) # 4 Numeric Operations (shared) ~~~~~~~~~~~~~~~~~~~~~~~~~~ All ``Number`` subtypes support the following methods: .. list-table:: :widths: 30 70 :header-rows: 1 * - Method - Description * - ``.to_int()`` - Convert to ``Integer`` (truncates) * - ``.to_float()`` - Convert to ``Float`` * - ``.to_complex()`` - Convert to ``Complex`` * - ``.sqrt()`` - Square root (returns ``Complex`` when input is negative) * - ``.cbrt()`` - Cube root * - ``.sin()``, ``.cos()``, ``.tan()`` - Trigonometric functions (radians) * - ``.asin()``, ``.acos()``, ``.atan()`` - Inverse trigonometric functions * - ``.exp()`` - e\ :sup:`x` * - ``.log(base?)`` - Natural log, or log to specified base * - ``.simplify()`` - Return a simplified symbolic form Uncertainty Propagation ~~~~~~~~~~~~~~~~~~~~~~ Numeric values can carry an uncertainty. Arithmetic on uncertain values automatically propagates error in quadrature: .. code-block:: symbolic # Not yet user-facing syntax — set via .set_uncertainty() x = Float(9.81) x.set_uncertainty(0.02) print(x.format()) # "9.81 ± 0.02" ---- Boolean ------- The ``Boolean`` type wraps ``true`` and ``false``. Booleans behave as integers (``true`` = 1, ``false`` = 0) in arithmetic contexts: .. code-block:: symbolic a = true b = false print(a and b) # false print(a or b) # true print(!a) # false print(a + 1) # 2 ---- String ------ Strings are UTF-8 Unicode sequences. The ``String`` type extends Python's ``str`` and provides functional methods: .. code-block:: symbolic s = "Hello, World!" print(s.length) # 13 print(s.upper()) # "HELLO, WORLD!" print(s.reverse()) # "!dlroW ,olleH" print(s.contains("World"))# true print(s.split(", ")) # ["Hello", "World!"] print(s[0..5]) # "Hello" # Functional transformations digits = "a1b2c3" nums = digits.filter((c) -> c >= "0" and c <= "9") print(nums) # "123" # Palindrome check print("racecar".is_palindrome()) # true ---- Collections ----------- List ~~~ Ordered, mutable, heterogeneous sequences: .. code-block:: symbolic nums = [1, 2, 3, 4, 5] nums.append(6) nums.reverse() print(nums) # [6, 5, 4, 3, 2, 1] # Functional pipeline — lazy evaluation, collect to materialize result = nums .filter((x) -> x > 2) .map((x) -> x ^ 2) .to_list() # Reduce total = nums.reduce((a, b) -> a + b) # Slicing sub = nums[1..3] # [5, 4] # Fill constructor zeros = [].fill(0, 10) # [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] Tuple ~~~~ Ordered, immutable sequences. A trailing comma distinguishes a single-element tuple from a parenthesized expression: .. code-block:: symbolic t = (1, "hello", 3.14) (x, y, z) = t # destructuring assignment singleton = (42,) # single-element tuple empty = () Dictionary ~~~~~~~~~ Key-value maps with functional accessors: .. code-block:: symbolic d = {"name": "Alice", "score": 97} print(d["name"]) # "Alice" print(d.get("age", 0)) # 0 (default) d["rank"] = 1 # Functional transforms upper_keys = d.map_keys((k) -> k.upper()) high = d.filter_items((k, v) -> v > 50) Set ~~ Unordered collections of unique elements: .. code-block:: symbolic s1 = {1, 2, 3} s2 = {2, 3, 4} print(s1.union(s2)) # {1, 2, 3, 4} print(s1.intersection(s2)) # {2, 3} print(s1.difference(s2)) # {1} ---- Type Annotations ---------------- Type annotations are optional. When present, they are written after a colon on function parameters and with an arrow for return types. Annotations are evaluated at definition time; the runtime does not enforce them by default unless contract clauses are present. .. code-block:: symbolic fn greet(name: String) -> String { return f"Hello, {name}!"; } fn divide(a: Integer, b: Integer) -> Fraction requires b != 0 { return a / b; } Union types use ``||``: .. code-block:: symbolic fn process(value: Integer || Float || Complex) -> Float || Complex { return value.sqrt(); } Generic parameters use angle brackets: .. code-block:: symbolic fn identity(x: T) -> T { return x; } ---- Constants --------- The ``const`` modifier prevents reassignment. ``const`` values are also implicitly ``final`` (cannot be shadowed in a nested scope): .. code-block:: symbolic const MAX_RETRIES = 5 const BASE_URL = "https://api.example.com" MAX_RETRIES = 6 # compile error: assignment to constant ---- Null and Optional Values ------------------------- Symbolic does not have a dedicated null literal. The null-coalesce operator ``??`` and optional-chaining operator ``?.`` support nullable patterns: .. code-block:: symbolic value = lookup("key") ?? "default" length = user?.profile?.bio?.length ?? 0 .. seealso:: :doc:`functions` — Type annotations on parameters and return types. :doc:`pattern_matching` — Type patterns in ``match`` expressions.