xllify

Built-in Globals

Globals available in every Lua function you write. These are not Excel functions themselves but primitives that make writing functions easier and faster. See also: standard library Excel functions.

xllify.* built-ins 8 functions

Fast native primitives on the xllify global. Call these inside your function code for parsing, matching, and text processing. They run in C++ and are significantly faster than equivalent pure-Lua implementations.

xllify.json_parse

Parse a JSON string into a native Lua table

Parameter Type Description
json_string string A valid JSON string to parse

Returns: table | nil, error - Parsed Lua table, or nil and an error message on failure

Examples
xllify.json_parse('{"name": "Alice", "age": 30}') → {name = "Alice", age = 30}
xllify.json_parse('[1, 2, 3]') → {1, 2, 3}
xllify.json_parse('invalid') → nil, "error message"

xllify.levenshtein_distance

Calculate the Levenshtein edit distance between two strings

Parameter Type Description
a string First string
b string Second string

Returns: number - The minimum number of single-character edits (insertions, deletions, substitutions) to transform a into b

Examples
xllify.levenshtein_distance("kitten", "sitting") → 3
xllify.levenshtein_distance("hello", "hello") → 0
xllify.levenshtein_distance("abc", "") → 3

xllify.strip_html

Remove HTML tags and decode common HTML entities from a string

Parameter Type Description
text string HTML string to strip

Returns: string - Plain text with HTML tags removed and common entities decoded

Examples
xllify.strip_html("<b>Hello</b> <i>world</i>") → "Hello world"
xllify.strip_html("Price: &amp;pound;5 &amp;gt; &amp;pound;3") → "Price: £5 > £3"
xllify.strip_html("No tags here") → "No tags here"

xllify.spell_number

Convert a number to English words (handles up to trillions, negatives, and decimals)

Parameter Type Description
n number Number to spell out

Returns: string - The number spelled out in English words

Examples
xllify.spell_number(42) → "forty-two"
xllify.spell_number(-7) → "negative seven"
xllify.spell_number(1000000) → "one million"

xllify.json_stringify

Convert a Lua value (table, string, number, boolean, nil) to a JSON string

Parameter Type Description
value any A Lua value to convert to JSON

Returns: string - JSON string representation of the value

Examples
xllify.json_stringify({name = "Alice", age = 30}) → "{\"age\":30,\"name\":\"Alice\"}"
xllify.json_stringify({1, 2, 3}) → "[1,2,3]"
xllify.json_stringify("hello") → "\"hello\""

xllify.ensure_matrix

Normalise a scalar or range parameter to always be a 2D table of rows. Use at the top of any function with dimensionality = "matrix" that might receive a single cell instead of a range.

Parameter Type Description
v any A scalar value, 1D table, or 2D table of rows

Returns: table - Always a 2D table of rows

Examples
xllify.ensure_matrix(42) → {{42}}
xllify.ensure_matrix({1, 2, 3}) → {{1, 2, 3}}
xllify.ensure_matrix({{1, 2}, {3, 4}}) → {{1, 2}, {3, 4}}

xllify.flatten_range

Flatten a matrix range (2D table of rows) to a 1D array of numbers, skipping any non-numeric cells. Handles scalars, 1D arrays, and 2D matrices uniformly.

Parameter Type Description
m any A scalar, 1D table, or 2D matrix of rows

Returns: table - 1D array containing only the numeric values from the input

Examples
xllify.flatten_range({{1, 2}, {3, 4}}) → {1, 2, 3, 4}
xllify.flatten_range({{10}, {"N/A"}, {30}}) → {10, 30}
xllify.flatten_range(42) → {42}

xllify.criteria_pred

Returns a predicate function for an Excel-style criteria string. Supports "odd", "even", comparison operators (>, >=, <, <=, =, <>, !=), and falls back to strict equality for plain values. Composes naturally with functional.filter.

Parameter Type Description
criteria any An Excel-style criteria string: "odd", "even", ">5", ">=10", "<>3", or a plain value for equality

Returns: function - A predicate function(v) → boolean

Examples
xllify.criteria_pred(">5")(7) → true
xllify.criteria_pred("odd")(3) → true
xllify.criteria_pred("<>10")(10) → false
functional.filter({1,2,3,4,5,6}, xllify.criteria_pred("even")) → {2, 4, 6}

functional.* globals 38 functions

Higher-order primitives available on the functional global in every Lua state. No require needed.

functional.map

Transform every element of a table using a function. The function receives the value and index.

Parameter Type Description
t table Input array-style table
f function Function called as f(value, index), must return the new value

Returns: table - New table of the same length with each element replaced by f(v, i)

Examples
functional.map({1, 2, 3}, function(x) return x * 2 end) → {2, 4, 6}
functional.map({"a", "b", "c"}, function(v, i) return i .. ":" .. v end) → {"1:a", "2:b", "3:c"}

functional.filter

Keep only the elements of a table for which a predicate function returns true.

Parameter Type Description
t table Input array-style table
f function Predicate function called as f(value), return true to keep the element

Returns: table - New table containing only the elements for which f returned true

Examples
functional.filter({1, 2, 3, 4, 5}, function(x) return x % 2 == 0 end) → {2, 4}
functional.filter({10, -3, 7, -1, 4}, function(x) return x > 0 end) → {10, 7, 4}

functional.fold

Left fold: reduce a table to a single value by repeatedly applying a function, starting from an explicit seed accumulator.

Parameter Type Description
t table Input array-style table
f function Combiner function called as f(accumulator, value)
acc any Initial accumulator value (seed)

Returns: any - Final accumulated value

Examples
functional.fold({1, 2, 3, 4, 5}, function(acc, x) return acc + x end, 0) → 15
functional.fold({"b", "c", "d"}, function(acc, x) return acc .. x end, "a") → "abcd"

functional.reduce

Reduce a table to a single value using the first element as the seed. Errors on an empty table. Use functional.fold when you need an explicit starting value.

Parameter Type Description
t table Input array-style table (must be non-empty)
f function Combiner function called as f(accumulator, value)

Returns: any - Final accumulated value

Examples
functional.reduce({1, 2, 3, 4, 5}, function(acc, x) return acc + x end) → 15
functional.reduce({3, 1, 4, 1, 5}, function(acc, x) return math.max(acc, x) end) → 5

functional.zip

Combine two tables element-wise. With a function, produces f(a[i], b[i]). Without a function, produces pairs as {a[i], b[i]}. Length is capped at the shorter table.

Parameter Type Description
a table First input table
b table Second input table
f function Optional combining function called as f(a[i], b[i])

Returns: table - Combined table, length equal to math.min(#a, #b)

Examples
functional.zip({1, 2, 3}, {4, 5, 6}, function(a, b) return a + b end) → {5, 7, 9}
functional.zip({"Alice", "Bob"}, {95, 82}) → {{"Alice", 95}, {"Bob", 82}}

functional.flatten

Recursively flatten nested tables up to a given depth. Depth defaults to 1.

Parameter Type Description
t table Input table, possibly nested
depth number How many levels to flatten (default 1)

Returns: table - Flattened table

Examples
functional.flatten({{1, 2}, {3, 4}, {5}}) → {1, 2, 3, 4, 5}
functional.flatten({{{1, 2}}, {{3}}}, 2) → {1, 2, 3}
functional.flatten({{10}, {20}, {30}}) → {10, 20, 30} -- useful for matrix ranges

functional.flat_map

Map a function over a table then flatten the result by one level. Equivalent to functional.flatten(functional.map(t, f), 1).

Parameter Type Description
t table Input array-style table
f function Function that returns a table for each element

Returns: table - Mapped and flattened result

Examples
functional.flat_map({{1, 2}, {3}}, function(row) return row end) → {1, 2, 3}
functional.flat_map({1, 2, 3}, function(x) return {x, x * x} end) → {1, 1, 2, 4, 3, 9}

functional.compose

Right-to-left function composition. Returns a new function that applies its arguments in reverse order: compose(f, g, h)(x) = f(g(h(x))).

Parameter Type Description
... function Two or more functions to compose (all must be functions)

Returns: function - A new function that applies the arguments right-to-left

Examples
local f = functional.compose(functional.double, functional.inc, functional.square) f(3) → double(inc(square(3))) = double(inc(9)) = double(10) = 20

functional.pipe

Left-to-right function composition. Returns a new function that applies its arguments in order: pipe(f, g, h)(x) = h(g(f(x))). The order you read matches the order of execution.

Parameter Type Description
... function Two or more functions to chain (all must be functions)

Returns: function - A new function that applies the arguments left-to-right

Examples
local f = functional.pipe(functional.double, functional.inc, functional.square) f(3) → square(inc(double(3))) = square(inc(6)) = square(7) = 49

functional.partial

Bind the leading arguments of a function, returning a new function that takes the remaining arguments.

Parameter Type Description
f function Function to partially apply
... any Arguments to bind to the leading parameters of f

Returns: function - A new function that prepends the bound arguments before any new arguments

Examples
local function multiply(x, y) return x * y end local double = functional.partial(multiply, 2) double(5) → 10
local function add(a, b) return a + b end local addTen = functional.partial(add, 10) functional.map({1, 2, 3}, addTen) → {11, 12, 13}

functional.identity

Returns its argument unchanged. Useful as a no-op placeholder in compose or pipe chains.

Parameter Type Description
x any Any value

Returns: any - The same value passed in

Examples
functional.identity(42) → 42
functional.identity("hello") → "hello"

functional.const

Returns a function that always returns the given value, ignoring its argument. Useful for providing fixed values in map or compose chains.

Parameter Type Description
v any The value to always return

Returns: function - A function that ignores its argument and always returns v

Examples
local always5 = functional.const(5) always5(99) → 5
functional.map({1, 2, 3}, functional.const(0)) → {0, 0, 0}

functional.double

Multiply a number by 2.

Parameter Type Description
x number Input number

Returns: number - x * 2

Examples
functional.double(5) → 10
functional.map({1, 2, 3}, functional.double) → {2, 4, 6}

functional.square

Square a number.

Parameter Type Description
x number Input number

Returns: number - x * x

Examples
functional.square(4) → 16
functional.map({1, 2, 3, 4}, functional.square) → {1, 4, 9, 16}

functional.negate

Negate a number.

Parameter Type Description
x number Input number

Returns: number - -x

Examples
functional.negate(7) → -7
functional.map({1, -2, 3}, functional.negate) → {-1, 2, -3}

functional.abs

Absolute value of a number. Alias for math.abs.

Parameter Type Description
x number Input number

Returns: number - math.abs(x)

Examples
functional.abs(-5) → 5
functional.map({-3, 1, -4, 1, -5}, functional.abs) → {3, 1, 4, 1, 5}

functional.inc

Increment a number by 1.

Parameter Type Description
x number Input number

Returns: number - x + 1

Examples
functional.inc(4) → 5
functional.map({0, 1, 2}, functional.inc) → {1, 2, 3}

functional.dec

Decrement a number by 1.

Parameter Type Description
x number Input number

Returns: number - x - 1

Examples
functional.dec(4) → 3
functional.map({1, 2, 3}, functional.dec) → {0, 1, 2}

functional.half

Divide a number by 2.

Parameter Type Description
x number Input number

Returns: number - x / 2

Examples
functional.half(10) → 5
functional.map({2, 4, 6}, functional.half) → {1, 2, 3}

functional.sqrt

Square root of a number. Alias for math.sqrt.

Parameter Type Description
x number Input number

Returns: number - math.sqrt(x)

Examples
functional.sqrt(9) → 3
functional.map({4, 9, 16}, functional.sqrt) → {2, 3, 4}

functional.floor

Floor a number. Alias for math.floor.

Parameter Type Description
x number Input number

Returns: number - math.floor(x)

Examples
functional.floor(3.7) → 3
functional.map({1.1, 2.9, 3.5}, functional.floor) → {1, 2, 3}

functional.ceil

Ceiling of a number. Alias for math.ceil.

Parameter Type Description
x number Input number

Returns: number - math.ceil(x)

Examples
functional.ceil(3.2) → 4
functional.map({1.1, 2.9, 3.5}, functional.ceil) → {2, 3, 4}

functional.round

Round a number to the nearest integer.

Parameter Type Description
x number Input number

Returns: number - math.floor(x + 0.5)

Examples
functional.round(3.4) → 3
functional.round(3.5) → 4
functional.map({1.1, 2.6, 3.5}, functional.round) → {1, 3, 4}

functional.add

Returns a function that adds n to its argument. Arithmetic combinator.

Parameter Type Description
n number Value to add

Returns: function - function(x) return x + n end

Examples
functional.map({1, 2, 3}, functional.add(10)) → {11, 12, 13}
functional.add(5)(3) → 8

functional.sub

Returns a function that subtracts n from its argument. Arithmetic combinator.

Parameter Type Description
n number Value to subtract

Returns: function - function(x) return x - n end

Examples
functional.map({10, 20, 30}, functional.sub(5)) → {5, 15, 25}

functional.mul

Returns a function that multiplies its argument by n. Arithmetic combinator.

Parameter Type Description
n number Multiplier

Returns: function - function(x) return x * n end

Examples
functional.map({1, 2, 3}, functional.mul(3)) → {3, 6, 9}
functional.mul(2)(5) → 10

functional.div

Returns a function that divides its argument by n. Arithmetic combinator.

Parameter Type Description
n number Divisor

Returns: function - function(x) return x / n end

Examples
functional.map({10, 20, 30}, functional.div(10)) → {1, 2, 3}

functional.pow

Returns a function that raises its argument to the power n. Arithmetic combinator.

Parameter Type Description
n number Exponent

Returns: function - function(x) return x ^ n end

Examples
functional.map({1, 2, 3, 4}, functional.pow(2)) → {1, 4, 9, 16}
functional.map({1, 2, 3}, functional.pow(3)) → {1, 8, 27}

functional.mod

Returns a function that computes its argument modulo n. Arithmetic combinator.

Parameter Type Description
n number Modulus

Returns: function - function(x) return x % n end

Examples
functional.map({1, 2, 3, 4, 5}, functional.mod(2)) → {1, 0, 1, 0, 1}
functional.filter({1,2,3,4,5,6}, function(x) return functional.mod(2)(x) == 0 end) → {2, 4, 6}

functional.every

Returns true if the predicate f returns true for every element in the table. Returns true for an empty table (vacuously true).

Parameter Type Description
t table Input array-style table
f function Predicate function called as f(value)

Returns: boolean - true if f(v) is true for all elements, false otherwise

Examples
functional.every({2, 4, 6}, function(x) return x % 2 == 0 end) → true
functional.every({2, 3, 6}, function(x) return x % 2 == 0 end) → false
functional.every({}, function(x) return false end) → true

functional.some

Returns the first element for which the predicate f returns true, or nil if none match.

Parameter Type Description
t table Input array-style table
f function Predicate function called as f(value)

Returns: any | nil - The first matching value, or nil if no element matches

Examples
functional.some({1, 2, 3}, function(x) return x > 2 end) → 3
functional.some({1, 2, 3}, function(x) return x > 10 end) → nil
functional.some({"apple", "banana"}, function(s) return s:sub(1,1) == "b" end) → "banana"

functional.none

Returns true if the predicate f returns false for every element in the table. Complement of functional.some. Returns true for an empty table.

Parameter Type Description
t table Input array-style table
f function Predicate function called as f(value)

Returns: boolean - true if f(v) is false for all elements, false otherwise

Examples
functional.none({1, 3, 5}, function(x) return x % 2 == 0 end) → true
functional.none({1, 2, 3}, function(x) return x % 2 == 0 end) → false

functional.group_by

Partition a table into subtables keyed by the result of calling f on each element. Each key maps to an array of all elements that produced that key.

Parameter Type Description
t table Input array-style table
f function Key function called as f(value), must return a string or number

Returns: table - A table mapping each key to an array of matching elements

Examples
functional.group_by({1,2,3,4,5,6}, function(x) return x % 2 == 0 and "even" or "odd" end) → {even = {2, 4, 6}, odd = {1, 3, 5}}
functional.group_by({"apple","avocado","banana"}, function(s) return s:sub(1,1) end) → {a = {"apple", "avocado"}, b = {"banana"}}

functional.frequencies

Count the number of occurrences of each distinct value in a table. Returns a table mapping each value to its count.

Parameter Type Description
t table Input array-style table

Returns: table - Maps each distinct value to the number of times it appears

Examples
functional.frequencies({"a", "b", "a", "c", "b", "a"}) → {a = 3, b = 2, c = 1}
functional.frequencies({1, 2, 1, 1, 3}) → {[1] = 3, [2] = 1, [3] = 1}

functional.take_while

Return elements from the front of a table while the predicate returns true. Stops at the first false result.

Parameter Type Description
t table Input array-style table
f function Predicate function called as f(value)

Returns: table - All leading elements for which f returned true

Examples
functional.take_while({1, 2, 3, 4, 5}, function(x) return x < 4 end) → {1, 2, 3}
functional.take_while({10, 20, 5, 30}, function(x) return x >= 10 end) → {10, 20}

functional.drop_while

Skip elements from the front of a table while the predicate returns true, then return the remainder.

Parameter Type Description
t table Input array-style table
f function Predicate function called as f(value)

Returns: table - The table with all leading elements removed for which f returned true

Examples
functional.drop_while({1, 2, 3, 4, 5}, function(x) return x < 3 end) → {3, 4, 5}
functional.drop_while({0, 0, 1, 2, 0}, function(x) return x == 0 end) → {1, 2, 0}

functional.juxt

Apply multiple functions to the same value and return a table of results. juxt(f, g, h)(x) → {f(x), g(x), h(x)}. Useful for building rows from a single value.

Parameter Type Description
... function Two or more functions to apply

Returns: function - A function that returns a table of results, one per input function

Examples
local f = functional.juxt(functional.identity, functional.square, functional.double) f(3) → {3, 9, 6}
functional.map({1, 2, 3}, functional.juxt(functional.identity, functional.square)) → {{1, 1}, {2, 4}, {3, 9}}

functional.distinct

Return a new table with duplicate values removed, preserving insertion order.

Parameter Type Description
t table Input array-style table

Returns: table - New table with duplicates removed, first occurrence of each value preserved

Examples
functional.distinct({1, 2, 1, 3, 2, 4}) → {1, 2, 3, 4}
functional.distinct({"a", "b", "a", "c"}) → {"a", "b", "c"}