# function: naming a reusable job [Syntax and values](README.md) ```text function add(a, b): return a + b say add(2, 3) ``` Parameters are comma-separated identifiers. Empty parameter lists and trailing commas are allowed. See [Section 11](../../../pliro-syntax.en.md#11-functions) for function semantics. ## Declaration and call ```pliro # language: en function factorial(number): if number <= 1: return 1 return number * factorial(number - 1) say factorial(5) ``` Functions have a fixed number of positional parameters. User-function arity is checked when the callee can be resolved statically and again at runtime for a dynamic call. Pliro currently has no default, named, optional, variadic, typed, or destructured parameters. Arguments are passed as values. Lists and maps retain the collection-sharing behavior described in [Section 9.6](../../../pliro-syntax.en.md#96-collection-sharing), so a function can update an existing element of a collection supplied by its caller. ## Return value `return expression` returns a value. Bare `return` and function fallthrough return `none`: ```text function announce(message): say message return ``` ## Closures and nested functions User functions close over their lexical environment: ```pliro # language: en function makeCounter(start): let value = start function next(): set value = value + 1 return value return next let counter = makeCounter(10) say counter() say counter() ``` Functions are first-class runtime values: they can be stored, passed, returned, and called. There is no anonymous-function or lambda syntax. ## Recursion limits Direct recursion is supported. Runtimes enforce a bounded maximum user-function call depth and produce a structured runtime error instead of overflowing the host stack. Session runtimes make this bound configurable; the current generated native runtime fixes it at 256. ## Related entries [Syntax and values](README.md) · [Built-ins](../builtins/README.md) · [Programming guides](../guides/README.md)