Anonymous Function (fn)#
Defines a function. A function consists of a list of parameters and a list of expression. The value of the last expression is returned as the result of the function. All other expression are only evaluated for side effects. If no expression is given, the function returns nil.
Functions can define multiple arities. When calling such a function, the clause matching the number of provided arguments is chosen. Variadic clauses are supported for at most one arity and must be the one with the most parameters. If no arity matches, a readable compile-time or runtime error is thrown.
Function also introduces a new lexical scope that is not accessible outside the function.
# Function with no arguments that returns nil
# The identity function
# A function that returns 3
# A function that returns the sum of a and b
Function can also be defined as variadic function with an infinite amount of arguments using the & separator.
# A variadic function that counts the arguments
# A variadic function with extra arguments ignored
There is a shorter form to define an anonymous function. This omits the parameter list and names parameters based on their position.
$is used for a single parameter$1,$2,$3, etc are used for multiple parameters$&is used for the remaining variadic parameters
| # Same as (fn [x] (+ 6 x))
| # Same as (fn [a b] (+ a b))
| # Same as (fn [& xs] (sum xs))
PHP Coming from PHP? ›
The short-form anonymous function syntax | is similar to PHP's arrow functions:
Clojure Coming from Clojure? ›
The short-form | syntax is inspired by Clojure's #() reader macro, but uses different parameter names ($ instead of %).
Global functions#
Global functions can be defined using defn. Like anonymous functions, they may provide multiple arities. The most specific clause based on the number of arguments is chosen at call time. A single variadic clause is allowed and must declare the maximum number of arguments.
Each global function can take an optional doc comment and attribute map.
Private functions#
Private functions are not exported from the namespace and cannot be accessed from other namespaces. You can create private functions in two ways:
- Using the
{:private true}attribute map - Using the
defn-shorthand
Both approaches are equivalent, but defn- provides a more concise syntax for defining private functions.
Recursion#
Similar to loop, functions can be made recursive using recur. The recur special form enables tail-call optimization, preventing stack overflow errors.
# Recursive factorial (regular recursion - can stack overflow)
# => 120
# Tail-recursive factorial using recur with loop
# => 120
# Recursive sum (can stack overflow on large collections)
# => 15
# Tail-recursive sum using recur (safe for large collections)
# => 15
# Using recur directly in function (also tail-call optimized)
# (countdown 5) # Prints: 5, 4, 3, 2, 1, then returns "Done!"
PHP Coming from PHP? ›
recur is compiled to a PHP while loop, preventing "Maximum function nesting level" errors that would occur with regular recursive calls in PHP.
Key difference: Regular recursion builds up a call stack, while recur reuses the same stack frame (tail-call optimization).
Clojure Coming from Clojure? ›
recur works exactly like Clojure's recur—it provides tail-call optimization by compiling to a loop.
Apply functions#
Calls the function with the given arguments. The last argument must be a list of values, which are passed as separate arguments, rather than a single list. Apply returns the result of the calling function.
# Evaluates to 6
# Evaluates to 6
# BAD! Last element must be a list
Passing by reference#
Sometimes it is required that a variable should pass to a function by reference. This can be done by applying the :reference metadata to the symbol.
Support for references is very limited in Phel. Currently, it only works for function arguments (except destructuring).
PHP Coming from PHP? ›
This is equivalent to PHP's & reference operator:
Note: Use references sparingly. Phel's immutable data structures are usually a better choice than mutating PHP arrays.