Functions · Defining Functions · Practice Question
Write a Recursive Function
Question
Write a recursive function factorial that computes n! (the product of all integers from 1 to n). Then rewrite it as an anonymous function using .z.s for self-reference, and show a third solution that uses a q iterator instead of recursion.
Solution
/ Named recursion
factorial:{$[x <= 1; 1; x * factorial[x-1]]}
factorial[6]
/ 720
/ Anonymous recursion using .z.s
{$[x <= 1; 1; x * .z.s[x-1]]}[6]
/ 720
/ Non-recursive using over
(*/) 1+til 6
/ 720Explanation
Named recursion — factorial simply calls itself by name inside the body. The base case (x <= 1) is checked first; without it the function would keep calling itself and eventually crash.
.z.s is q's built-in self-reference. It always points to the function currently executing, even when that function has no name. This makes anonymous recursion possible:
{$[x <= 1; 1; x * .z.s[x-1]]}[6]Read .z.s[x-1] as "call myself with x-1." You would use this when you want a recursive lambda that you pass directly to another function without assigning a name first.
The iterator approach is the most natural q solution for this particular problem. (*/) 1+til 6 generates the list 1 2 3 4 5 6 and then collapses it by multiplying everything together using the over (/) iterator. No explicit recursion, no base case to worry about, and it runs faster because it avoids the overhead of repeated function calls.
In general, q programmers reach for iterators (+/, */, max/, min/, etc.) whenever a problem is fundamentally about combining elements of a list. Recursion is best saved for situations where the structure of the data is genuinely recursive — trees, nested configurations, anything where you don't know the depth in advance.