# `Ash.Query.Function`
[🔗](https://github.com/ash-project/ash/blob/v3.34.4/lib/ash/query/function/function.ex#L5)

A function is a predicate with an arguments list.

For more information on being a predicate, see `Ash.Filter.Predicate`. Most of the complexities
are there. A function must meet both behaviours.

# `arg`

```elixir
@type arg() :: any()
```

# `args`

```elixir
@callback args() :: [arg()] | :var_args
```

The number and types of arguments supported.

# `can_return_nil?`

```elixir
@callback can_return_nil?(func :: map()) :: boolean()
```

Whether or not the function return nil.

# `eager_evaluate?`

```elixir
@callback eager_evaluate?() :: boolean()
```

Whether or not the function can be evaluated eagerly. For example, `now()` cannot be.

# `evaluate`

```elixir
@callback evaluate(func :: map()) :: :unknown | {:known, term()} | {:error, term()}
```

Evaluate a function when all arguments are known valid values

# `evaluate_nil_inputs?`

```elixir
@callback evaluate_nil_inputs?() :: boolean()
```

If `true`, will be allowed to evaluate `nil` inputs.

If `false` (the default), any `nil` inputs will cause a `nil` return.

# `name`

```elixir
@callback name() :: atom()
```

The name of the function

# `new`

```elixir
@callback new([term()]) :: {:ok, term()} | {:error, String.t() | Exception.t()}
```

Instantiate a new function with the provided arguments

# `partial_evaluate`
*optional* 

```elixir
@callback partial_evaluate(func) :: {:ok, func} | {:error, term()} when func: map()
```

Evaluate a function when some or no arguments are known valid values

# `predicate?`

```elixir
@callback predicate?() :: boolean()
```

Whether or not the function is a predicate (takes a reference as the first argument, a value as the second, and returns a boolean)

# `private?`

```elixir
@callback private?() :: boolean()
```

Whether or not the function should be usable when parsing input.

# `returns`

```elixir
@callback returns() ::
  [
    Ash.Type.t()
    | {Ash.Type.t(), constraints :: Keyword.t()}
    | :same
    | {:array, :same}
    | {:referenced_type, via :: term()}
  ]
  | Ash.Type.t()
  | {Ash.Type.t(), constraints :: Keyword.t()}
  | :unknown
```

The return type for each corresponding set of args.

Besides a type, an entry may be `:same` (the arguments' type), `{:array, :same}`, or
`{:referenced_type, via}`: the type the arguments' type refers to under `via`, as its
`c:Ash.Type.referenced_types/1` describes it. `range_lower/1` returns
`{:referenced_type, {:inner_type_of, :range}}`, the type of its range's bounds.

# `compatible_expr_type?`

```elixir
@spec compatible_expr_type?(term(), term()) :: boolean()
```

Whether an expression's type is compatible with a declared argument type.

Vague declarations (`:any`, `:same` and their array forms) accept anything.
A concrete declaration matches when the expression's type, as resolved by
`Ash.Expr.determine_type/1`, is that type or acts as it: a NewType acts as
its `subtype_of`, and any type may name another via `c:Ash.Type.acts_as/1`
(an `:atom` acts as a `:string`, an embedded resource acts as a `:map`, and
so on), recursively. Functions should therefore declare the most general
type they accept: `datetime_add/3` declares `:datetime`, so any datetime
NewType such as `:utc_datetime_usec` is accepted. An expression whose type
cannot be determined is considered compatible, as there is no evidence
against it.

# `evaluate`

Evaluate the operator with provided inputs

# `new`

# `ordinal`

Attaches the appropriate suffix to refer to an ordinal number, e.g 1 -> "1st"

# `try_cast_arguments`

Casts `args` to a single declared signature, returning the cast list or `nil`.

With `exact?: true`, a value only fits a declared type if casting leaves it
unchanged, so signatures are matched on the type the value already has.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
