Lambda notation
The lambda notation is how you define a function.
A lambda function is defined by an optional function signature^{1} followed by zero or more expressions, separated by semicolons; all embraced by curly brackets.
{[arg1;arg2] a:arg1*arg1; b:arg2+acos 1; a%b}
Semicolons are separators
Avoid the mistake of thinking of semicolons as terminators. Expressions do not have terminators.
Semicolons in a lambda separate its expressions; they are part of its structure.
The last semicolon in a lambda precedes its last expression. Evaluating its last expression gives the lambda’s result. If the last expression is empty, the lambda’s result is the general null.
q)(::)~{x;} 42
1b
Result
When the lambda is evaluated, its expressions are evaluated sequentially from left to right.
The result of evaluating the lambda is the result of evaluating the last expression.
If the last expression is empty, the result is the general null ::
.
Every lambda returns a result
The general null ::
does not have a visible representation on the console.
But it is returned and can be assigned.
q)q:{}[]
q)q ~ (::)
1b
q)(::) ~ {`Global set x;}[42]
1b
q)Global
42
Function rank
In computer science, the number of arguments a function expects is known variously as its valence or arity; in q, it is known as its rank^{2}. A lambda can have a rank in the range 1–8.
q)til[3;4] / oops, til has rank 1
'rank
[0] til[3;4]
^
The rank of a lambda is determined by the number of arguments specified in its signature; or, if no signature is specified, by references in its definition to the default arguments x
, y
, and z
.
{[a;b;c] a+b*c} / rank 3
{x+y*z} / rank 3
{z*z} / rank 3
{y*y} / rank 2
{acos[1]*x*x} / rank 1
{[r]acos[1]*r*r} / rank 1
There is no such thing as a nullary lambda.
The minimum rank of a lambda is 1.
q)(::) ~ {}[] / rank 0?
1b
q)(::) ~ {}[3] / no, rank 1
1b
q)(::) ~ {}[3;4] / no, not 2: 1
'rank
[0] (::) ~ {}[3;4]
^
If you evaluate a unary lambda on an empty argument list, the argument value is the general null.
q)(::) ~ {x}[42]
0b
q)(::) ~ {x}[::]
1b
q)(::) ~ {x}[]
1b
In the edge case {}[]
both argument and result are the general null ::
.
The rank of a lambda is fixed.
Signal
A good use case for if
is in testing a lambda’s argument/s and signalling an error.
foo:{[x]
if[x<0;'`type]; / signal type error
a:..;
}
If foo
above receives a negative number it signals a type error to the expression that called it.
Explicit return
In a similar use case no error is signalled but computation can be cut short with the explicit return.
goo:{[x]
if[x<0;:0]; / return zero
a:..;
}
Exercises
No peeking.
Attempt each exercise before looking at its answer.
The exercises clarify your thinking. Reading answers does not.

What is the rank of
{[z]x+y+z}
?Answer
The signature of
{[z]x+y*z}
specifies a single argumentz
. The references tox
andy
must resolve from external names. So the lambda has rank 1.Default argument names
It is a terrible idea to use
x
,y
, orz
as anything other than the names of (respectively) the first, second, and third arguments.And if you are using them as argument names, use tham as defaults: a function signature has no information to add.

Several operators are overloaded by rank; which is to say that they are variadic and their semantics are determined by the number of arguments to which they are applied. What scope does lambda notation provide for doing this?
Answer
The lambda notation fixes the rank of a lambda in the range 1–8. But a unary lambda can be applied with bracket syntax to an empty argument, in which case the value of its argument is the general null
::
, for which the lambda can test to see if it has been called with one or zero arguments.Of course the same can be done with any designated value, such as zero,q){x~(::)}[] 1b
1
, or an empty list. The general null is just less likely to result from the computation of an argument value. 
A lambda with an empty final expression returns a general null. Is it better to assign it than to let it print? Explain.
Answer
Every q expression returns a result. If the final expression of a lambda is empty, its result is the general null
::
.The general null has no display form, so nothing is written to stdout. Nothing is gained by assigning the result if it is always the general null.

What do the expressions
if[3]
,do[3]
andwhile[3]
do?Answer
Nothing, respectively once, three times, and forever.

All q expressions return a result. Pick a control word and explore whether it is actually a function of some kind.
Answer
Above, all the errors are the same error: the parser won’t acceptq)if[3] / OK q)(if) / noun syntax? 'if q)3 if/() / derive a function? 'if q)type(if) / has data type? 'if q)@[if;3] / arg to Apply At? 'if q)if / display a definition? 'if
if
in the attempted syntactic role – it’s not a function.