Back to Defining Functions

Functions · Defining Functions · Practice Question

Write a Recursive Function

Sign in to track your progress

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
/ 720

Explanation

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.