# QforMortals3/Functions 101

## 1.10 Functions 101

All built-in q operators are functions. The main differences between q’s functions and the ones we mortals can write are:

- The built-ins are written and optimized in one of the underlying languages k or C.
- All q functions can be used with infix notation—i.e., as operators—whereas ours must be used in prefix form.

Functions in q correspond to “lambda expressions” or “anonymous functions” in other languages. This means that a function is a first class value just like a long or float value—i.e., it acquires a name only once it is assigned to a variable.

Conceptually, a q function is a sequence of steps that produces an output result from an input value. Since q is not purely functional, these rules can interact with the world by reaching outside the context of the function. Such actions are called side effects and should be carefully controlled.

Function definition is delimited by matching curly braces ‘{‘ and ‘}’. Immediately after the opening brace, the formal parameters are names enclosed in square brackets ‘[‘ and ‘]’ and separated by semi- colons. These parameters presumably appear in the body of the function, which follows the formal parameters and is a succession of expressions sequenced by semi-colons.

Following is a simple function that returns the square of its input. On the next line we assign the same function to the variable sq. The whitespace is optional.

q){[x] x*x} _ q)sq:{[x] x*x} _

Here is a function that takes two input values and returns the sum of their squares.

q){[x;y] a:x*x; b:y*y; a+b} _ q)pyth:{x;y] a:x*x; b:y*y; a+b} _

To apply a function to arguments, follow it (or its name, if it has been assigned to a variable) by a list of values enclosed in square brackets and separated by semi-colons. This causes the argument expression to be evaluated first, then the expressions in the body of the function to be evaluated sequentially by substituting each resulting argument for every occurrence of the corresponding formal parameter. Normally the value of the final expression is returned as the output value of the function.

Here are the previous functions applied to arguments.

q){[x] x*x}[5] 25 q)sq[5] _ q){x;y] a:x*x; b:y*y; a+b}[3;4] 25 q)pyth[3;4] _

The variables a and b appearing in the body of the last function above are local—i.e., they are created and exist only for the duration of an application.

It is common in mathematics to use function parameters x, y, or z. If you are content with these names (in the belief that descriptive names provide no useful information to the poor soul reading your code), you can omit their declaration and q will understand that you mean the implicit parameters x, y, and z in that order.

q){x*x}[5] 25 q){a:x*x; b:y*y; a+b}[3;4] 25

This is about as pithy as it gets for function definition and application. Well, not quite. In q, as in most functional languages, we don’t need no stinkin’ brackets for application of a monadic function—i.e., with one parameter. Simply separate the function from its argument by whitespace. This is called function juxtaposition.

q){x*x} 5 _ q)f:{x*x} q)f 5 _

If you are new to functional programming this may take some getting used to, but the reduction of punctuation “noise” in your code is worth it.

Prev: Lists 101, Next: Functions on Lists 101

Reprinted with the author's permission from: q for Mortals Version 3, An Introduction to Q Programming by Jeffry A. Borror.

The book is available on Amazon. In the United Kingdom, it is available at Amazon UK.

©2015 Jeffry A. Borror/ q4m LLC