---
title: "Functions and Custom Pins · RUAL Documentation"
description: "Declare a function with arguments and returns in Blueprint Language, call it, also from another blueprint, and see its signature as custom pins on the canvas."
canonical: https://docs.rual.nl/engine/functions
language: en
---

[Cluster](https://docs.rual.nl/cluster)

[Blocks](https://docs.rual.nl/block-types)

[Interfaces](https://docs.rual.nl/interfaces)

[Blueprints](https://docs.rual.nl/blueprints)

[Blueprint Language](https://docs.rual.nl/engine)

[Tutorials](https://docs.rual.nl/tutorials)

[Home automation](https://docs.rual.nl/home-automation)

[Examples](https://docs.rual.nl/examples)

[Reference](https://docs.rual.nl/reference)

[Architecture](https://docs.rual.nl/architecture)

[Troubleshooting](https://docs.rual.nl/troubleshooting)

Other

# Functions and Custom Pins

A function is a flow that other flows call by name, with named parameters and returns. This page shows how to declare one in Blueprint Language, how to call it, also from another blueprint, and how its parameters and returns appear on the canvas as custom pins.

## A function and a call

`add-vat` takes one number and returns one; `quote` is a route handler that reads `amount` from the request body, calls `add-vat` and replies with its `total`:

```
blueprint "Pricing"

fn add-vat(arg amount: number) -> (total: number) {
  function_return(total: number_times(amount, 1.21))
}

fn quote(connection, body) {
  let {amount} = body
  priced = call add-vat(amount: amount)
  reply 200 {total: priced.total}
}
```

| Source | On the canvas |
| --- | --- |
| `fn add-vat(...)` | A [`trigger_custom_function`](https://docs.rual.nl/block-types/globals/trigger_custom_function) named `add-vat`; the body runs from its `flow` output. |
| `arg amount: number` | An argument: an input `amount` on every call, and an output `amount` on the function's first block that the body reads (here into [`number_times`](https://docs.rual.nl/block-types/math/number_times)). |
| `-> (total: number)` | A return: an input `total` on every [`function_return`](https://docs.rual.nl/block-types/function%20execution/function_return) in the body, and an output `total` on every call. |
| `fn quote(connection, body)` | Context parameters: the values a route hands its handler. |
| `priced = call add-vat(amount: amount)` | A [`function_custom_execute`](https://docs.rual.nl/block-types/function%20execution/function_custom_execute) that runs `add-vat`, with its `amount` input wired to `amount`. |
| `priced.total` | The call's `total` output. |

Once stored, an export prints the same two functions with its own names: a call is named after the function it calls, and a field that is read once is written inline as `body.amount`.

```
blueprint "Pricing"

fn add-vat(arg amount: number) -> (total: number) {
  function_return(total: number_times(amount, 1.21))
}

fn quote(connection, body) {
  add_vat = call add-vat(amount: body.amount)
  reply 200 {total: add_vat.total}
}
```

## Declaring a function

A function is `fn name(parameters) -> (returns) { body }`. The returns are optional, and so is `pub` in front: it marks a function public, for functions that other blueprints call.

### Parameters

| Kind | Written as | What it is |
| --- | --- | --- |
| Context parameter | `connection`, `params`, `query`, `body`, `file` | A value the starter hands the function: a route passes `connection`, `params`, `query` and `body`, and a file route also `file`. |
| Argument | `arg amount: number` | A value each caller passes by name. |
| Optional argument | `arg limit?: number` | An argument a caller may leave out. |

A type is a pin type: `value`, `number`, `condition`, `object`, `array`, `date` and so on. Arguments and returns are `value` unless you say otherwise, and context parameters are `object`, except `connection` (`httpconnection`), `file` (`file`) and `index` (`number`). Write a type only where it differs; an export does the same.

```
fn find-orders(connection, arg customer_guid, arg limit?: number) -> (orders: array, count?: number) {
  …
}
```

### Returns

`-> (total: number)` declares what the function returns, and `function_return(total: ...)` in the body sets the values the caller receives. A trailing `?` marks a return optional. A function with several exits has a `function_return` on each of them:

```
fn score(arg a: number, arg b: number) -> (ok: condition, total: number, label) {
  let sum = number_plus(a, b)
  guard sum > 10 else {
    function_return(ok: false, total: sum, label: "LOW")
  }
  guard number_times(a, b) < 1000 else {
    function_return(ok: false, total: sum, label: "HUGE")
  }
  function_return(ok: true, total: number_times(sum, 2), label: "HIGH")
}
```

Make every path reach a `function_return`: a path that ends without one gives the caller no returned values. A return whose name is a reserved word, such as `true`, is written in backticks, both in the declaration and in `function_return`:

```
let currentdate = now()

fn is-this-year() -> (`true`: condition) {
  function_return(`true`: condition_date_equals_this_year(currentdate))
}
```

## Calling a function

`x = call name(param: expression, ...)` runs the function, passes each argument by name and names the call, so `x.total` reads the return called `total`. A call waits until the function has finished before the flow goes on; to run a function in the background instead, put it on the [queue](https://docs.rual.nl/blueprints/queue).

When the function is declared in the same file, a call's arguments are checked against its parameters. Here the argument on line 9 of `pricing.blueprint` is misspelled:

```
9:25: call add-vat has no parameter "amout"; did you mean amount?
```

## Calling a function in another blueprint

A call names the function it runs, and the function may be declared in another blueprint. Mark it `pub` in its own blueprint:

```
blueprint "Access checks"

pub fn is-staff-request(connection) -> (valid: condition) {
  …
}
```

and call it by that name, exactly as you would call a function in the same file:

```
fn create-order(connection, params, query, body) {
  is_staff_request = call is-staff-request(connection: connection)
  guard is_staff_request.valid else {
    reply 403
  }
  …
```

- **The name is the link.** Function names may contain `-` and `.`, so a namespace such as `billing.add-vat` keeps many functions apart (see [namespaces](https://docs.rual.nl/blueprints/tips-and-tricks#blueprint-namespace)).

- **Check the arguments yourself.** A compile cannot see the declaration of a function in another blueprint, so it does not check a call's argument names against it. Export that blueprint to read its `fn` line.

- **An unknown name is a warning.** A call whose name matches no function is reported at its line, and has nothing to run.

## Custom pins: the signature on the canvas

Most blocks have a fixed set of pins. A function's blocks do not: their pins come from the function's parameters and returns. These are its **custom pins**, and in source you write them once, on the `fn` line.

| Block | Custom pins it shows |
| --- | --- |
| The function's [`trigger_custom_function`](https://docs.rual.nl/block-types/globals/trigger_custom_function) | An output per parameter, which the body reads like any other output. |
| Every [`function_return`](https://docs.rual.nl/block-types/function%20execution/function_return) in the body | An input per return. |
| Every call, [`function_custom_execute`](https://docs.rual.nl/block-types/function%20execution/function_custom_execute) | An input per argument and an output per return. |

A call passes and reads these pins by name. When you rename a parameter or a return, update the calls that pass or read it as well, in this blueprint and in the blueprints that call the function.

- [Blueprint Language Syntax](https://docs.rual.nl/engine/blueprint-language): The rest of the language: statements, expressions, block and storage calls, the lock, positions and checks.

- [Best Practices](https://docs.rual.nl/blueprints/best-practices): When to split logic into functions, and how to share them between blueprints.

## Frequently asked

**How do I declare a function with parameters and returns in Blueprint Language?**

Write fn name(arg amount: number, arg limit?: number) -> (total: number) { ... } and end every path with function_return(total: ...). arg marks a value callers pass by name, a trailing ? makes it optional, and types default to value. A route handler takes the context parameters connection, params, query and body instead.

**How do I call a function in another blueprint in RUAL?**

Mark the function pub in its own blueprint, then call it by name, for example x = call is-staff-request(connection: connection), and read its returns as x.valid. A compile cannot check the arguments of a function declared in another blueprint, so match them to its fn line.

**Does a RUAL function call wait for the function to finish?**

Yes. A call runs the function and waits for it before the flow continues, then sets the returned values on its outputs. To run a function without waiting, put it on the queue with function_custom_execute_from_queue.

Was this page helpful? [Tell us what to improve](https://docs.rual.nl/support) · RUAL Docs is an integral component of the [RUAL ecosystem](https://rual.nl)
