Skip to content

v0.3.0

Latest

Choose a tag to compare

@dblock dblock released this 26 Sep 21:01
· 6 commits to master since this release
d7971c2

[0.3.0] - 2026-09-26

Added

  • Interactive REPL: running calc/excalc with no expression while stdin is a terminal now starts a read-eval-print loop (variables persist across lines within the session, Tab-completes function names, and shows/advances through argument-name hints inside a call's parentheses), with help for usage, about for version/author/license info, vars to list assigned variables, and exit/quit/Ctrl-D to leave, instead of just printing usage.
  • User-defined functions: name(params) := expr defines a function (e.g. f(x) := x^2 + 1), visible to later statements the same way a variable assignment is, listed alongside variables by the REPL's vars command (showing the actual definition, e.g. f(x) = x ^ 2 + 1, not a placeholder). Functions can call themselves or each other; arguments are evaluated in the caller's scope (proper lexical scoping, no accidental self-shadowing). There's no fixed call-count limit; each nested call checks actual remaining stack space and fails gracefully with function call recursion limit exceeded once it's running low, rather than crashing with a native stack overflow. Function names can't collide with built-ins or pi/e, and definitions are session-only, matching variable persistence.
  • Conditionals: cond ? then : else (ternary operator) and its exact equivalent if(cond, then, else) — both short-circuit, evaluating only the taken branch, which lets self-recursive user-defined functions actually terminate at a computed base case instead of always recursing, e.g. fact(n) := n < 2 ? 1 : n * fact(n - 1).
  • Digit-group separators: number literals may use , or _ as a thousands separator (e.g. 1,234 or 1_234_567); a group must be exactly 3 digits, so short argument lists like sum(1,2) still parse as 2 arguments, not a single grouped number. Whichever separator is used first in an expression is echoed back in the printed result, e.g. 1,000 + 1 prints 1,001.
  • Currency symbols: number literals may be prefixed with $, £, €, or ¥ (e.g. $100), which is purely cosmetic and ignored for math. Whichever currency symbol is used first in an expression is echoed back in the printed result, e.g. $1 + 10 prints $11; math across different currency symbols isn't tracked or rejected.
  • REPL command history now persists across sessions, saved to ~/.excalc_history by default (%USERPROFILE%\.excalc_history on Windows if $HOME isn't set); override the location with --history-file <path> or the EXCALC_HISTORY_FILE environment variable, or disable persistence entirely with --no-history.
  • New general/numeric-analysis functions: nthroot(x, n) (general n-th root) and isqrt(n) (integer square root).
  • Combinatorics extras: stirling1(n, k)/stirling2(n, k) (Stirling numbers of the first/second kind), derangement(n), and bell(n) (Bell numbers).
  • New statistics functions: skewness (population skewness) and kurtosis (population excess kurtosis).
  • Unit conversion functions: c2f/f2c (temperature), km2mi/mi2km (distance), kg2lb/lb2kg (mass), m2ft/ft2m (distance).
  • Probability distribution functions: binomialpdf/binomialcdf (binomial), poissonpdf/poissoncdf (Poisson), normalpdf/normalcdf (normal, reusing the existing erf), and zscore (standard score).
  • Geometry functions: distance/manhattan/dot (n-dimensional, splitting a single argument list in half between two points/vectors) and norm (n-dimensional vector magnitude), plus dimension-free shape formulas triarea (Heron's formula), circlearea, circumference, spherevol, spherearea.
  • New number theory functions: carmichael(n) (Carmichael function), aliquot(n) (sum of proper divisors), amicable?(n), coprime?(a, b), order(a, n) (multiplicative order), jacobi(a, n) (Jacobi symbol).
  • Root-finding functions bisect(expr, var, a, b, tolerance) (bisection method) and secant(expr, var, x0, x1, tolerance) (secant method), sharing the same expression-and-bare-variable calling convention as the numeric-integration functions.
  • New sequence/figurate-number functions: lucas(n) (Lucas numbers, sibling to fib), triangular(n), pentagonal(n), hexagonal(n).
  • Bit manipulation functions: popcount(n), bitlen(n), bitreverse(n, width).
  • New general/rounding functions: roundto(x, n) (round to n decimal places), floordiv(a, b) and mod2(a, b) (floored division/modulo, complementing //mod's truncated-towards-zero convention).
  • Combinatorics functions: factorial(n) (named equivalent of postfix !), perm(n, r), catalan(n), multinomial(n, k1, k2, ...).
  • atan2(y, x): two-argument arctangent, using the sign of both arguments to determine the correct quadrant.
  • excalc/calc read the expression from stdin when no argument is given and stdin is not a TTY, e.g. echo "2 + 2" | calc.
  • --help and usage output now credit the author.
  • Windows MSI installer: renamed the default install directory from excalc to ExCalc; added an optional (on by default) "MCP Server Registration" feature that shells out to copilot mcp add and claude mcp add to register excalc-mcp with GitHub Copilot CLI and Claude Code CLI, if either is found on the machine (src/bin/excalc-mcp-setup.rs, run as a deferred, impersonated, best-effort custom action).
  • New standard math/general functions: log2, cbrt, hypot, sign, clamp, lerp.
  • New statistics functions: median, mode, variance, stddev, percentile, covariance, correlation.
  • New number theory functions: primorial, digitsum, digitalroot, palindrome?, nextprime.
  • Base conversion: hex, oct, bin functions to format a non-negative integer as text, and 0x/0o/0b-prefixed literals to parse hex/octal/binary numbers back into ordinary numeric values. First feature to introduce a non-numeric result type (evaluate_value, returning a Value enum of Number/Text); evaluate remains f64-only for backward compatibility and errors if the result is text.