# Function definitions

## Functions

You can declare a new function using a **function** statement.

```typescript
// Example: create a function which takes a number 'n' as argument
// and returns n squared.

function square(n: number) {
    return n * n;
}

return square(4);
```

If you omit the argument type for a function, it is assigned the type **primitive**.

The return type of a function is inferred from its body. It is also possible to specify it explicitly:

```typescript
// Example: a function with an explicit return type.
function square(n: number) : number {
    return n * n;
}

return square(3);
```

All functions must return some value. Functions with explicitly declared return types can call themselves recursively.

For short function that immediately returns a value, you can omit the curly braces and the return keyword and instead use the **lambda arrow** (`=>`) syntax:

```typescript
// Example: a couple of functions declared using the lambda arrow syntax

function square(n: number) => n * n;

function abs(n: number) =>
    case when n < 0 then n * -1
         else n
         end;
```

## Self functions

The first argument of a function may be decorated with the **self** keyword, turning the function into a *self function*. When calling a self function, the first argument may be supplied using dot notation:

```typescript
function multiply(self n: number, m: number) : number {
    return n * m;
}

return 3.multiply(2); // the first argument is supplied by the left side of the dot.
```

## Lambda expressions

A lambda expression is a terse syntax for creating function values. A lambda expression is written using an argument list followed by a **lambda arrow** (`=>`) and a single return expression.

```typescript
// Example: declare a function using a lambda expression.
let add = (x, y) => x + y;
return add(2, 3);
```

For single-argument lambda expressions, the parantheses around the argument list may be omitted:

```typescript
// Example: a single-argument lambda expression.
let square = x => x * 2;
return square(3);
```

Typically used in conjunction with the [Seq](/flow-connect/reference/reference/flowscript/walkthrough/seq-module.md) module, lambda expressions provide the benefit of inferring their argument types from the context:

```typescript
// Example: get a list of user names using the Seq.map function
// together with a lambda expression

open Seq;

let users = [
    {id: 0, name: "Gustava"},
    {id: 1, name: "Farid"}
];

return users.map(u => u.name); // here, 'u' gets its type from its surroundings.
```

## Advanced: Variadic functions

A **variadic function** is a convenience allowing you to pass a sequence argument as individual arguments.  A variadic argument is marked by three periods (...) before the argument name.

```typescript
// Define a "maximum" function which takes any number of arguments.
function maximum(...xs: number*) {
    let started = false;
    let result = 0;
    for x in xs {
        if not started or x > result {
            set result = x;
            set started = true;
        }
    }
    return isNull(result, 0);
}

return maximum(10, 3, 5, 11)
```

## Advanced: Generic functions

A *generic* function leaves some of its constituent types – argument types or return type – purposely undefined, replacing them with *type variables.* This allows the function to operate on different kinds of values while retaining type safety.

In the following example, the function **second** is defined with one type variable called **T**, declared in the angle brackets after the function name. This makes the function return **number?** when called on a list of numbers, **text?** when called on a list of texts, etc.

```typescript
// Example: create a generic function which returns the second element
// of a sequence (or null if there are less than two elements).

function second<T>(self xs: T*): T? {
    return xs.skip(1).firstOrNull();
}

let secondNumber = [1, 2, 3].second(); // has type 'number?'
let secondText = ["hello", "world"].second(); // has type 'text?'
```

Usually, the type variables of a function can be inferred from usage (as in the example above). Sometimes, however, it cannot — and then you have to specify the type variables yourself. This is known as *specialization.*

```typescript
// Make a function which deserializes JSON if the input is non-empty
function deserializeIfNotEmpty<T>(data: text?): T? {
    if data is null or data = "" {
        return null;
    }
    return JSON.deserialize<T>(data);
}

// Type variable T cannot be inferred from usage here.
return deserializeIfNotEmpty<MyType>(null);
```

## Advanced: Function composition using the >> operator

Composition is a terse way of creating a new function from a pair of functions. The resulting function takes the same arguments as the left-hand side and, calls it with those arguments, and passes the result as a single argument to right-hand side function, returning its result.

In other words, for functions `f` and `g`, the composition `f >> g` is equivalent to the lambda expression  `x => g(f(x))` .

```typescript
// Example: Create a function by composing two other functions.

// First, make a little utility function which tells us whether a number if even.
function isEven(n: number) => n mod 2 == 0;

// Now compose the built-in `count` function with `isEven` to 
// create a new function which takes a sequence and tells us whether it
// has an even number of elements.
let hasEvenNumberOfElements = count >> isEven;

return hasEvenNumberOfElements([1, 2, 3]);

// Equivalent definition without using composition:
//   function hasEvenNumberOfElements(s: unknown*) => isEven(count(s))
```

## Advanced: Partial function calls using the \_ operator

It is possible to *partially call* a function. A partial call is a way to define a new function from an existing one, "fixing" some of the parameters to set values while leaving others for later. The resulting function only requires the "leftover" arguments.

```typescript
// Example 1: Create a function which removes spaces from a text
// by partially calling the built-in `replace` function:

let removeSpaces = replace(_, " ", "")
return removeSpaces("hello world") // returns "helloworld"
```

```typescript
// Example 2: Use a partial call in conjunction with composition
// to create a function that turns "hello world" into "HELLO_WORLD"
// (aka Upper Snake Case).

let toUpperSnakeCase = replace(_, " ", "_") >> upper;
return toUpperSnakeCase("hello world");
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.novacura.com/flow-connect/reference/reference/flowscript/walkthrough/function-definitions.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
