# `Expression.V2.Callbacks.Standard`

Callback functions to be used in Expressions.

This is the same idea as `Expression.Callbacks.Standard` but
it's in a rough shape, mostly to just prove that this all works.

# `abs`

Returns the absolute value of a number

## Example 1:

When used in the following Stack expression it returns a  value of type **Integer**: `1`.

```
> abs(-1)
1
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @abs(-1) ..."
"1"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @abs(-1) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", 1, " impact"] = result
    ["chat for ", 1, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "abs(-1)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert 1 = result
    1
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@abs(-1)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "1"

---

# `and_vargs`

Returns `true` if and only if all its arguments evaluate to `true`

## Example 1:

When used in the following Stack expression it returns a  value of type **Boolean**: `true` when used with the following context:

```elixir
%{"contact" => %{"age" => 32, "gender" => "F"}}
```

```
> contact.gender = "F" and contact.age >= 18
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @and(contact.gender = "F", contact.age >= 18) ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @and(contact.gender = \"F\", contact.age >= 18) impact",
    ...>   Expression.V2.Context.new(%{"contact" => %{"age" => 32, "gender" => "F"}}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "and(contact.gender = \"F\", contact.age >= 18)",
    ...>   Expression.V2.Context.new(%{"contact" => %{"age" => 32, "gender" => "F"}}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@and(contact.gender = \"F\", contact.age >= 18)",
    ...>   Expression.V2.Context.new(%{"contact" => %{"age" => 32, "gender" => "F"}}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 2:

When used in the following Stack expression it returns a  value of type **Boolean**: `false` when used with the following context:

```elixir
%{"contact" => %{"age" => 32, "gender" => "?"}}
```

```
> contact.gender = "F" and contact.age >= 18
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @and(contact.gender = "F", contact.age >= 18) ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @and(contact.gender = \"F\", contact.age >= 18) impact",
    ...>   Expression.V2.Context.new(%{"contact" => %{"age" => 32, "gender" => "?"}}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "and(contact.gender = \"F\", contact.age >= 18)",
    ...>   Expression.V2.Context.new(%{"contact" => %{"age" => 32, "gender" => "?"}}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@and(contact.gender = \"F\", contact.age >= 18)",
    ...>   Expression.V2.Context.new(%{"contact" => %{"age" => 32, "gender" => "?"}}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

# `append`

Appends an item or a list of items to a given list.

## Example 1:

When used in the following Stack expression it returns a  value of type **List with values String, String, String**: `["A", "B", "C"]`.

```
> append(["A", "B"], "C")
["A", "B", "C"]
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @append(["A", "B"], "C") ..."
"ABC"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @append([\"A\", \"B\"], \"C\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", ["A", "B", "C"], " impact"] = result
    ["chat for ", ["A", "B", "C"], " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "append([\"A\", \"B\"], \"C\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert ["A", "B", "C"] = result
    ["A", "B", "C"]
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@append([\"A\", \"B\"], \"C\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "ABC"

---

## Example 2:

When used in the following Stack expression it returns a  value of type **List with values String, String, String, String**: `["A", "B", "C", "B"]`.

```
> append(["A", "B"], ["C", "B"])
["A", "B", "C", "B"]
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @append(["A", "B"], ["C", "B"]) ..."
"ABCB"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @append([\"A\", \"B\"], [\"C\", \"B\"]) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", ["A", "B", "C", "B"], " impact"] = result
    ["chat for ", ["A", "B", "C", "B"], " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "append([\"A\", \"B\"], [\"C\", \"B\"])",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert ["A", "B", "C", "B"] = result
    ["A", "B", "C", "B"]
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@append([\"A\", \"B\"], [\"C\", \"B\"])",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "ABCB"

---

# `callback`

# `char`

Returns the character specified by a number

```
> "As easy as @char(65), @char(66), @char(67)"
"As easy as A, B, C"
```

## Example 1:

When used in the following Stack expression it returns a  value of type **String**: `"A"`.

```
> char(65)
"A"
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @char(65) ..."
"A"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @char(65) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", "A", " impact"] = result
    ["chat for ", "A", " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "char(65)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert "A" = result
    "A"
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@char(65)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "A"

---

# `clean`

Removes all non-printable characters from a text string

## Example 1:

When used in the following Stack expression it returns a  value of type **String**: `"ABC"` when used with the following context:

```elixir
%{"value" => <<65, 0, 66, 0, 67>>}
```

```
> clean(value)
"ABC"
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @clean(value) ..."
"ABC"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @clean(value) impact",
    ...>   Expression.V2.Context.new(%{"value" => <<65, 0, 66, 0, 67>>}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", "ABC", " impact"] = result
    ["chat for ", "ABC", " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "clean(value)",
    ...>   Expression.V2.Context.new(%{"value" => <<65, 0, 66, 0, 67>>}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert "ABC" = result
    "ABC"
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@clean(value)",
    ...>   Expression.V2.Context.new(%{"value" => <<65, 0, 66, 0, 67>>}, Expression.V2.Callbacks.Standard)
    ...> )
    "ABC"

---

# `code`

Returns a numeric code for the first character in a text string

```
> "The numeric code of A is @CODE(\"A\")"
"The numeric code of A is 65"
```

## Example 1:

When used in the following Stack expression it returns a  value of type **Integer**: `65`.

```
> code("A")
65
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @code("A") ..."
"65"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @code(\"A\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", 65, " impact"] = result
    ["chat for ", 65, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "code(\"A\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert 65 = result
    65
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@code(\"A\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "65"

---

# `concatenate_vargs`

Joins text strings into one text string

```
> "Your name is @CONCATENATE(contact.first_name, \" \", contact.last_name)"
"Your name is name surname"
```

## Example 1:

When used in the following Stack expression it returns a  value of type **String**: `"name surname"` when used with the following context:

```elixir
%{"contact" => %{"first_name" => "name", "last_name" => "surname"}}
```

```
> concatenate(contact.first_name, " ", contact.last_name)
"name surname"
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @concatenate(contact.first_name, " ", contact.last_name) ..."
"name surname"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @concatenate(contact.first_name, \" \", contact.last_name) impact",
    ...>   Expression.V2.Context.new(%{"contact" => %{"first_name" => "name", "last_name" => "surname"}}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", "name surname", " impact"] = result
    ["chat for ", "name surname", " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "concatenate(contact.first_name, \" \", contact.last_name)",
    ...>   Expression.V2.Context.new(%{"contact" => %{"first_name" => "name", "last_name" => "surname"}}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert "name surname" = result
    "name surname"
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@concatenate(contact.first_name, \" \", contact.last_name)",
    ...>   Expression.V2.Context.new(%{"contact" => %{"first_name" => "name", "last_name" => "surname"}}, Expression.V2.Callbacks.Standard)
    ...> )
    "name surname"

---

# `date`

Defines a new date value

## Example 1:

> Construct a date from year, month, and day integers

When used in the following Stack expression it returns a  value of type **Date**: `~D[2022-01-31]` when used with the following context:

```elixir
%{"day" => 31, "month" => 1, "year" => 2022}
```

```
> date(year, month, day)
~D[2022-01-31]
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @date(year, month, day) ..."
"2022-01-31"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @date(year, month, day) impact",
    ...>   Expression.V2.Context.new(%{"day" => 31, "month" => 1, "year" => 2022}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", ~D[2022-01-31], " impact"] = result
    ["chat for ", ~D[2022-01-31], " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "date(year, month, day)",
    ...>   Expression.V2.Context.new(%{"day" => 31, "month" => 1, "year" => 2022}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert ~D[2022-01-31] = result
    ~D[2022-01-31]
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@date(year, month, day)",
    ...>   Expression.V2.Context.new(%{"day" => 31, "month" => 1, "year" => 2022}, Expression.V2.Callbacks.Standard)
    ...> )
    "2022-01-31"

---

# `datetime_add`

Calculates a new datetime based on the offset and unit provided.

The unit can be any of the following values:

* "Y" for years
* "M" for months
* "W" for weeks
* "D" for days
* "h" for hours
* "m" for minutes
* "s" for seconds

Specifying a negative offset results in date calculations back in time.

## Example 1:

> Calculates a new datetime based on the offset and unit provided.

When used in the following Stack expression it returns a  value of type **DateTime**: `~U[2022-08-31 00:00:00Z]` when used with the following context:

```elixir
%{"datetime" => ~U[2022-07-31 00:00:00Z], "offset" => 1, "unit" => "M"}
```

```
> datetime_add(datetime, offset, unit)
~U[2022-08-31 00:00:00Z]
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @datetime_add(datetime, offset, unit) ..."
"2022-08-31T00:00:00Z"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @datetime_add(datetime, offset, unit) impact",
    ...>   Expression.V2.Context.new(%{"datetime" => ~U[2022-07-31 00:00:00Z], "offset" => 1, "unit" => "M"}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", ~U[2022-08-31 00:00:00Z], " impact"] = result
    ["chat for ", ~U[2022-08-31 00:00:00Z], " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "datetime_add(datetime, offset, unit)",
    ...>   Expression.V2.Context.new(%{"datetime" => ~U[2022-07-31 00:00:00Z], "offset" => 1, "unit" => "M"}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert ~U[2022-08-31 00:00:00Z] = result
    ~U[2022-08-31 00:00:00Z]
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@datetime_add(datetime, offset, unit)",
    ...>   Expression.V2.Context.new(%{"datetime" => ~U[2022-07-31 00:00:00Z], "offset" => 1, "unit" => "M"}, Expression.V2.Callbacks.Standard)
    ...> )
    "2022-08-31T00:00:00Z"

---

## Example 2:

> Leap year handling in a leap year.

When used in the following Stack expression it returns a  value of type **DateTime**: `~U[2020-02-29 00:00:00.000000Z]`.

```
> datetime_add(date(2020, 02, 28), 1, "D")
~U[2020-02-29 00:00:00.000000Z]
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @datetime_add(date(2020, 02, 28), 1, "D") ..."
"2020-02-29T00:00:00.000000Z"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @datetime_add(date(2020, 02, 28), 1, \"D\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", ~U[2020-02-29 00:00:00.000000Z], " impact"] = result
    ["chat for ", ~U[2020-02-29 00:00:00.000000Z], " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "datetime_add(date(2020, 02, 28), 1, \"D\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert ~U[2020-02-29 00:00:00.000000Z] = result
    ~U[2020-02-29 00:00:00.000000Z]
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@datetime_add(date(2020, 02, 28), 1, \"D\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "2020-02-29T00:00:00.000000Z"

---

## Example 3:

> Leap year handling outside of a leap year.

When used in the following Stack expression it returns a  value of type **DateTime**: `~U[2021-03-01 00:00:00.000000Z]`.

```
> datetime_add(date(2021, 02, 28), 1, "D")
~U[2021-03-01 00:00:00.000000Z]
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @datetime_add(date(2021, 02, 28), 1, "D") ..."
"2021-03-01T00:00:00.000000Z"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @datetime_add(date(2021, 02, 28), 1, \"D\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", ~U[2021-03-01 00:00:00.000000Z], " impact"] = result
    ["chat for ", ~U[2021-03-01 00:00:00.000000Z], " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "datetime_add(date(2021, 02, 28), 1, \"D\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert ~U[2021-03-01 00:00:00.000000Z] = result
    ~U[2021-03-01 00:00:00.000000Z]
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@datetime_add(date(2021, 02, 28), 1, \"D\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "2021-03-01T00:00:00.000000Z"

---

## Example 4:

> Negative offsets

When used in the following Stack expression it returns a  value of type **DateTime**: `~U[2020-02-28 00:00:00.000000Z]`.

```
> datetime_add(date(2020, 02, 29), -1, "D")
~U[2020-02-28 00:00:00.000000Z]
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @datetime_add(date(2020, 02, 29), -1, "D") ..."
"2020-02-28T00:00:00.000000Z"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @datetime_add(date(2020, 02, 29), -1, \"D\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", ~U[2020-02-28 00:00:00.000000Z], " impact"] = result
    ["chat for ", ~U[2020-02-28 00:00:00.000000Z], " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "datetime_add(date(2020, 02, 29), -1, \"D\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert ~U[2020-02-28 00:00:00.000000Z] = result
    ~U[2020-02-28 00:00:00.000000Z]
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@datetime_add(date(2020, 02, 29), -1, \"D\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "2020-02-28T00:00:00.000000Z"

---

# `datevalue`

Converts date stored in text to an actual date object and
formats it using `strftime` formatting.

It will fallback to "%Y-%m-%d %H:%M:%S" if no formatting is supplied

## Example 1:

> Convert a date from a piece of text to a formatted date string

When used in the following Stack expression it returns a complex **String** type of default value:
```elixir
"2022-01-01 00:00:00"
```
with the following fields:

* *date* of type **Date**
.

```
> datevalue("2022-01-01")
%{"__value__" => "2022-01-01 00:00:00", "date" => ~D[2022-01-01]}
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @datevalue("2022-01-01") ..."
"2022-01-01 00:00:00"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @datevalue(\"2022-01-01\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", %{"__value__" => "2022-01-01 00:00:00", "date" => ~D[2022-01-01]}, " impact"] = result
    ["chat for ", %{"__value__" => "2022-01-01 00:00:00", "date" => ~D[2022-01-01]}, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "datevalue(\"2022-01-01\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert %{"__value__" => "2022-01-01 00:00:00", "date" => ~D[2022-01-01]} = result
    %{"__value__" => "2022-01-01 00:00:00", "date" => ~D[2022-01-01]}
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@datevalue(\"2022-01-01\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "2022-01-01 00:00:00"

---

## Example 2:

> Convert a date from a piece of text and read the date field

When used in the following Stack expression it returns a  value of type **Date**: `~D[2022-01-02]`.

```
> datevalue("2022-01-02").date
~D[2022-01-02]
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @datevalue("2022-01-02").date ..."
"2022-01-02"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @datevalue(\"2022-01-02\").date impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", ~D[2022-01-02], " impact"] = result
    ["chat for ", ~D[2022-01-02], " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "datevalue(\"2022-01-02\").date",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert ~D[2022-01-02] = result
    ~D[2022-01-02]
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@datevalue(\"2022-01-02\").date",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "2022-01-02"

---

## Example 3:

> Convert a date value and read the date field

When used in the following Stack expression it returns a  value of type **Date**: `~D[2022-01-03]`.

```
> datevalue(date(2022, 1, 3)).date
~D[2022-01-03]
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @datevalue(date(2022, 1, 3)).date ..."
"2022-01-03"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @datevalue(date(2022, 1, 3)).date impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", ~D[2022-01-03], " impact"] = result
    ["chat for ", ~D[2022-01-03], " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "datevalue(date(2022, 1, 3)).date",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert ~D[2022-01-03] = result
    ~D[2022-01-03]
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@datevalue(date(2022, 1, 3)).date",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "2022-01-03"

---

# `day`

Returns only the day of the month of a date (1 to 31)

## Example 1:

> Getting today's day of the month

When used in the following Stack expression it returns a  value of type **Integer**: `10`.

```
> day(date(2022, 9, 10))
10
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @day(date(2022, 9, 10)) ..."
"10"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @day(date(2022, 9, 10)) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", 10, " impact"] = result
    ["chat for ", 10, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "day(date(2022, 9, 10))",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert 10 = result
    10
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@day(date(2022, 9, 10))",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "10"

---

## Example 2:

> Getting today's day of the month

When used in the following Stack expression it returns a  value of type **Integer**: `3`.

```
> day(now())
3
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @day(now()) ..."
"3"
```

    ..$> # Evaluate a string with expressions
    ..$> import ExUnit.Assertions
    ..$> result = Expression.V2.eval(
    ...>   "chat for @day(now()) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    ..$> assert ["chat for ", 3, " impact"] = result
    ["chat for ", 3, " impact"]
    ..$>
    ..$> # Evaluate a standalone expression block
    ..$> result = Expression.V2.eval_block(
    ...>   "day(now())",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    ..$>
    ..$> assert 3 = result
    3
    ..$>
    ..$> # Evaluate a string with expressions into a single string
    ..$> Expression.V2.eval_as_string(
    ...>   "@day(now())",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "3"

---

# `delete`

Deletes an element from a map by the given key.

## Example 1:

When used in the following Stack expression it returns a  value of type **Map**: `%{"age" => 32}` when used with the following context:

```elixir
%{"patient" => %{"age" => 32, "gender" => "?"}}
```

```
> delete(patient, "gender")
%{"age" => 32}
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @delete(patient, "gender") ..."
"%{"age" => 32}"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @delete(patient, \"gender\") impact",
    ...>   Expression.V2.Context.new(%{"patient" => %{"age" => 32, "gender" => "?"}}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", %{"age" => 32}, " impact"] = result
    ["chat for ", %{"age" => 32}, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "delete(patient, \"gender\")",
    ...>   Expression.V2.Context.new(%{"patient" => %{"age" => 32, "gender" => "?"}}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert %{"age" => 32} = result
    %{"age" => 32}
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@delete(patient, \"gender\")",
    ...>   Expression.V2.Context.new(%{"patient" => %{"age" => 32, "gender" => "?"}}, Expression.V2.Callbacks.Standard)
    ...> )
    "%{\"age\" => 32}"

---

# `edate`

Moves a date by the given number of months

## Example 1:

> Move the date in a date object by 1 month

When used in the following Stack expression it returns a  value of type **DateTime**: `~U[2022-02-01 00:00:00Z]` when used with the following context:

```elixir
%{"right_now" => ~U[2022-01-01 00:00:00Z]}
```

```
> edate(right_now, 1)
~U[2022-02-01 00:00:00Z]
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @edate(right_now, 1) ..."
"2022-02-01T00:00:00Z"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @edate(right_now, 1) impact",
    ...>   Expression.V2.Context.new(%{"right_now" => ~U[2022-01-01 00:00:00Z]}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", ~U[2022-02-01 00:00:00Z], " impact"] = result
    ["chat for ", ~U[2022-02-01 00:00:00Z], " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "edate(right_now, 1)",
    ...>   Expression.V2.Context.new(%{"right_now" => ~U[2022-01-01 00:00:00Z]}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert ~U[2022-02-01 00:00:00Z] = result
    ~U[2022-02-01 00:00:00Z]
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@edate(right_now, 1)",
    ...>   Expression.V2.Context.new(%{"right_now" => ~U[2022-01-01 00:00:00Z]}, Expression.V2.Callbacks.Standard)
    ...> )
    "2022-02-01T00:00:00Z"

---

## Example 2:

> Move the date store in a piece of text by 1 month

When used in the following Stack expression it returns a  value of type **Date**: `~D[2022-11-10]`.

```
> edate("2022-10-10", 1)
~D[2022-11-10]
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @edate("2022-10-10", 1) ..."
"2022-11-10"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @edate(\"2022-10-10\", 1) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", ~D[2022-11-10], " impact"] = result
    ["chat for ", ~D[2022-11-10], " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "edate(\"2022-10-10\", 1)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert ~D[2022-11-10] = result
    ~D[2022-11-10]
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@edate(\"2022-10-10\", 1)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "2022-11-10"

---

# `expression_docs`

Return a list of all functions annotated with @expression_docs

# `first_word`

Returns the first word in the given text - equivalent to WORD(text, 1)

## Example 1:

When used in the following Stack expression it returns a  value of type **String**: `"foo"`.

```
> first_word("foo bar baz")
"foo"
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @first_word("foo bar baz") ..."
"foo"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @first_word(\"foo bar baz\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", "foo", " impact"] = result
    ["chat for ", "foo", " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "first_word(\"foo bar baz\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert "foo" = result
    "foo"
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@first_word(\"foo bar baz\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "foo"

---

# `fixed`

Formats the given number in decimal format using a period and commas

```
> You have @fixed(contact.balance, 2) in your account
"You have 4.21 in your account"
```

## Example 1:

When used in the following Stack expression it returns a  value of type **String**: `"4.21"`.

```
> fixed(4.209922, 2, false)
"4.21"
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @fixed(4.209922, 2, false) ..."
"4.21"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @fixed(4.209922, 2, false) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", "4.21", " impact"] = result
    ["chat for ", "4.21", " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "fixed(4.209922, 2, false)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert "4.21" = result
    "4.21"
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@fixed(4.209922, 2, false)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "4.21"

---

## Example 2:

When used in the following Stack expression it returns a  value of type **String**: `"4,000.4242"`.

```
> fixed(4000.424242, 4, true)
"4,000.4242"
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @fixed(4000.424242, 4, true) ..."
"4,000.4242"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @fixed(4000.424242, 4, true) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", "4,000.4242", " impact"] = result
    ["chat for ", "4,000.4242", " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "fixed(4000.424242, 4, true)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert "4,000.4242" = result
    "4,000.4242"
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@fixed(4000.424242, 4, true)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "4,000.4242"

---

## Example 3:

When used in the following Stack expression it returns a  value of type **String**: `"3.80"`.

```
> fixed(3.7979, 2, false)
"3.80"
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @fixed(3.7979, 2, false) ..."
"3.80"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @fixed(3.7979, 2, false) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", "3.80", " impact"] = result
    ["chat for ", "3.80", " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "fixed(3.7979, 2, false)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert "3.80" = result
    "3.80"
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@fixed(3.7979, 2, false)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "3.80"

---

## Example 4:

When used in the following Stack expression it returns a  value of type **String**: `"3.80"`.

```
> fixed(3.7979, 2)
"3.80"
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @fixed(3.7979, 2) ..."
"3.80"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @fixed(3.7979, 2) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", "3.80", " impact"] = result
    ["chat for ", "3.80", " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "fixed(3.7979, 2)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert "3.80" = result
    "3.80"
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@fixed(3.7979, 2)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "3.80"

---

# `has_all_words`

Tests whether all the words are contained in text

The words can be in any order and may appear more than once.

## Example 1:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> has_all_words("the quick brown FOX", "the fox")
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_all_words("the quick brown FOX", "the fox") ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_all_words(\"the quick brown FOX\", \"the fox\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_all_words(\"the quick brown FOX\", \"the fox\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_all_words(\"the quick brown FOX\", \"the fox\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 2:

When used in the following Stack expression it returns a  value of type **Boolean**: `false`.

```
> has_all_words("the quick brown FOX", "red fox")
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_all_words("the quick brown FOX", "red fox") ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_all_words(\"the quick brown FOX\", \"red fox\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_all_words(\"the quick brown FOX\", \"red fox\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_all_words(\"the quick brown FOX\", \"red fox\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

# `has_any_word`

Tests whether any of the words are contained in the text

Only one of the words needs to match and it may appear more than once.

## Example 1:

When used in the following Stack expression it returns a complex **Boolean** type of default value:
```elixir
true
```
with the following fields:

* *match* of type **String**
.

```
> has_any_word("The Quick Brown Fox", "fox quick")
%{"__value__" => true, "match" => "Quick Fox"}
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_any_word("The Quick Brown Fox", "fox quick") ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_any_word(\"The Quick Brown Fox\", \"fox quick\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", %{"__value__" => true, "match" => "Quick Fox"}, " impact"] = result
    ["chat for ", %{"__value__" => true, "match" => "Quick Fox"}, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_any_word(\"The Quick Brown Fox\", \"fox quick\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert %{"__value__" => true, "match" => "Quick Fox"} = result
    %{"__value__" => true, "match" => "Quick Fox"}
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_any_word(\"The Quick Brown Fox\", \"fox quick\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 2:

When used in the following Stack expression it returns a complex **Boolean** type of default value:
```elixir
false
```
with the following fields:

* *match* of type **Null**
.

```
> has_any_word("The Quick Brown Fox", "yellow")
%{"__value__" => false, "match" => nil}
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_any_word("The Quick Brown Fox", "yellow") ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_any_word(\"The Quick Brown Fox\", \"yellow\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", %{"__value__" => false, "match" => nil}, " impact"] = result
    ["chat for ", %{"__value__" => false, "match" => nil}, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_any_word(\"The Quick Brown Fox\", \"yellow\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert %{"__value__" => false, "match" => nil} = result
    %{"__value__" => false, "match" => nil}
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_any_word(\"The Quick Brown Fox\", \"yellow\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

# `has_beginning`

Tests whether text starts with beginning

Both text values are trimmed of surrounding whitespace, but otherwise matching is
strict without any tokenization.

## Example 1:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> has_beginning("The Quick Brown", "the quick")
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_beginning("The Quick Brown", "the quick") ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_beginning(\"The Quick Brown\", \"the quick\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_beginning(\"The Quick Brown\", \"the quick\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_beginning(\"The Quick Brown\", \"the quick\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 2:

When used in the following Stack expression it returns a  value of type **Boolean**: `false`.

```
> has_beginning("The Quick Brown", "the    quick")
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_beginning("The Quick Brown", "the    quick") ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_beginning(\"The Quick Brown\", \"the    quick\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_beginning(\"The Quick Brown\", \"the    quick\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_beginning(\"The Quick Brown\", \"the    quick\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

## Example 3:

When used in the following Stack expression it returns a  value of type **Boolean**: `false`.

```
> has_beginning("The Quick Brown", "quick brown")
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_beginning("The Quick Brown", "quick brown") ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_beginning(\"The Quick Brown\", \"quick brown\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_beginning(\"The Quick Brown\", \"quick brown\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_beginning(\"The Quick Brown\", \"quick brown\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

# `has_date`

Tests whether `expression` contains a date formatted according to our environment

This is very naively implemented with a regular expression.

## Example 1:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> has_date("the date is 15/01/2017")
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_date("the date is 15/01/2017") ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_date(\"the date is 15/01/2017\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_date(\"the date is 15/01/2017\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_date(\"the date is 15/01/2017\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 2:

When used in the following Stack expression it returns a  value of type **Boolean**: `false`.

```
> has_date("there is no date here, just a year 2017")
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_date("there is no date here, just a year 2017") ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_date(\"there is no date here, just a year 2017\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_date(\"there is no date here, just a year 2017\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_date(\"there is no date here, just a year 2017\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

# `has_date_eq`

Tests whether `expression` is a date equal to `date_string`

## Example 1:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> has_date_eq("the date is 15/01/2017", "2017-01-15")
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_date_eq("the date is 15/01/2017", "2017-01-15") ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_date_eq(\"the date is 15/01/2017\", \"2017-01-15\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_date_eq(\"the date is 15/01/2017\", \"2017-01-15\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_date_eq(\"the date is 15/01/2017\", \"2017-01-15\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 2:

When used in the following Stack expression it returns a  value of type **Boolean**: `false`.

```
> has_date_eq("there is no date here, just a year 2017", "2017-01-15")
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_date_eq("there is no date here, just a year 2017", "2017-01-15") ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_date_eq(\"there is no date here, just a year 2017\", \"2017-01-15\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_date_eq(\"there is no date here, just a year 2017\", \"2017-01-15\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_date_eq(\"there is no date here, just a year 2017\", \"2017-01-15\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

# `has_date_gt`

Tests whether `expression` is a date after the date `date_string`

## Example 1:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> has_date_gt("the date is 15/01/2017", "2017-01-01")
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_date_gt("the date is 15/01/2017", "2017-01-01") ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_date_gt(\"the date is 15/01/2017\", \"2017-01-01\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_date_gt(\"the date is 15/01/2017\", \"2017-01-01\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_date_gt(\"the date is 15/01/2017\", \"2017-01-01\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 2:

When used in the following Stack expression it returns a  value of type **Boolean**: `false`.

```
> has_date_gt("the date is 15/01/2017", "2017-03-15")
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_date_gt("the date is 15/01/2017", "2017-03-15") ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_date_gt(\"the date is 15/01/2017\", \"2017-03-15\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_date_gt(\"the date is 15/01/2017\", \"2017-03-15\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_date_gt(\"the date is 15/01/2017\", \"2017-03-15\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

# `has_date_lt`

Tests whether `expression` contains a date before the date `date_string`

## Example 1:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> has_date_lt("the date is 15/01/2017", "2017-06-01")
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_date_lt("the date is 15/01/2017", "2017-06-01") ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_date_lt(\"the date is 15/01/2017\", \"2017-06-01\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_date_lt(\"the date is 15/01/2017\", \"2017-06-01\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_date_lt(\"the date is 15/01/2017\", \"2017-06-01\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 2:

When used in the following Stack expression it returns a  value of type **Boolean**: `false`.

```
> has_date_lt("the date is 15/01/2021", "2017-03-15")
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_date_lt("the date is 15/01/2021", "2017-03-15") ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_date_lt(\"the date is 15/01/2021\", \"2017-03-15\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_date_lt(\"the date is 15/01/2021\", \"2017-03-15\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_date_lt(\"the date is 15/01/2021\", \"2017-03-15\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

# `has_email`

Tests whether an email is contained in text

## Example 1:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> has_email("my email is foo1@bar.com, please respond")
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_email("my email is foo1@bar.com, please respond") ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_email(\"my email is foo1@bar.com, please respond\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_email(\"my email is foo1@bar.com, please respond\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_email(\"my email is foo1@bar.com, please respond\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 2:

When used in the following Stack expression it returns a  value of type **Boolean**: `false`.

```
> has_email("i'm not sharing my email")
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_email("i'm not sharing my email") ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_email(\"i'm not sharing my email\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_email(\"i'm not sharing my email\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_email(\"i'm not sharing my email\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

# `has_group`

Returns whether the contact is part of group with the passed in UUID

## Example 1:

When used in the following Stack expression it returns a  value of type **Boolean**: `true` when used with the following context:

```elixir
%{"contact" => %{"groups" => [%{"uuid" => "b7cf0d83-f1c9-411c-96fd-c511a4cfa86d"}]}}
```

```
> has_group(contact.groups, "b7cf0d83-f1c9-411c-96fd-c511a4cfa86d")
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_group(contact.groups, "b7cf0d83-f1c9-411c-96fd-c511a4cfa86d") ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_group(contact.groups, \"b7cf0d83-f1c9-411c-96fd-c511a4cfa86d\") impact",
    ...>   Expression.V2.Context.new(%{"contact" => %{"groups" => [%{"uuid" => "b7cf0d83-f1c9-411c-96fd-c511a4cfa86d"}]}}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_group(contact.groups, \"b7cf0d83-f1c9-411c-96fd-c511a4cfa86d\")",
    ...>   Expression.V2.Context.new(%{"contact" => %{"groups" => [%{"uuid" => "b7cf0d83-f1c9-411c-96fd-c511a4cfa86d"}]}}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_group(contact.groups, \"b7cf0d83-f1c9-411c-96fd-c511a4cfa86d\")",
    ...>   Expression.V2.Context.new(%{"contact" => %{"groups" => [%{"uuid" => "b7cf0d83-f1c9-411c-96fd-c511a4cfa86d"}]}}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 2:

When used in the following Stack expression it returns a  value of type **Boolean**: `false` when used with the following context:

```elixir
%{"contact" => %{"groups" => [%{"uuid" => "b7cf0d83-f1c9-411c-96fd-c511a4cfa86d"}]}}
```

```
> has_group(contact.groups, "00000000-0000-0000-0000-000000000000")
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_group(contact.groups, "00000000-0000-0000-0000-000000000000") ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_group(contact.groups, \"00000000-0000-0000-0000-000000000000\") impact",
    ...>   Expression.V2.Context.new(%{"contact" => %{"groups" => [%{"uuid" => "b7cf0d83-f1c9-411c-96fd-c511a4cfa86d"}]}}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_group(contact.groups, \"00000000-0000-0000-0000-000000000000\")",
    ...>   Expression.V2.Context.new(%{"contact" => %{"groups" => [%{"uuid" => "b7cf0d83-f1c9-411c-96fd-c511a4cfa86d"}]}}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_group(contact.groups, \"00000000-0000-0000-0000-000000000000\")",
    ...>   Expression.V2.Context.new(%{"contact" => %{"groups" => [%{"uuid" => "b7cf0d83-f1c9-411c-96fd-c511a4cfa86d"}]}}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

# `has_number`

Tests whether `expression` contains a number

## Example 1:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> has_number("the number is 42 and 5")
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_number("the number is 42 and 5") ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_number(\"the number is 42 and 5\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_number(\"the number is 42 and 5\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_number(\"the number is 42 and 5\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 2:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> has_number("العدد ٤٢")
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_number("العدد ٤٢") ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_number(\"العدد ٤٢\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_number(\"العدد ٤٢\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_number(\"العدد ٤٢\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 3:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> has_number("٠.٥")
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_number("٠.٥") ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_number(\"٠.٥\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_number(\"٠.٥\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_number(\"٠.٥\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 4:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> has_number("0.6")
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_number("0.6") ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_number(\"0.6\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_number(\"0.6\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_number(\"0.6\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 5:

When used in the following Stack expression it returns a  value of type **Boolean**: `false`.

```
> has_number("")
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_number("") ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_number(\"\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_number(\"\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_number(\"\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

## Example 6:

When used in the following Stack expression it returns a  value of type **Boolean**: `false` when used with the following context:

```elixir
%{"value" => nil}
```

```
> has_number(value)
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_number(value) ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_number(value) impact",
    ...>   Expression.V2.Context.new(%{"value" => nil}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_number(value)",
    ...>   Expression.V2.Context.new(%{"value" => nil}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_number(value)",
    ...>   Expression.V2.Context.new(%{"value" => nil}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

# `has_number_eq`

Tests whether `expression` contains a number equal to the value

## Example 1:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> has_number_eq("the number is 42", 42)
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_number_eq("the number is 42", 42) ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_number_eq(\"the number is 42\", 42) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_number_eq(\"the number is 42\", 42)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_number_eq(\"the number is 42\", 42)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 2:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> has_number_eq("the number is 42", 42.0)
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_number_eq("the number is 42", 42.0) ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_number_eq(\"the number is 42\", 42.0) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_number_eq(\"the number is 42\", 42.0)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_number_eq(\"the number is 42\", 42.0)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 3:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> has_number_eq("the number is 42", "42")
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_number_eq("the number is 42", "42") ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_number_eq(\"the number is 42\", \"42\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_number_eq(\"the number is 42\", \"42\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_number_eq(\"the number is 42\", \"42\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 4:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> has_number_eq("the number is 42.0", "42")
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_number_eq("the number is 42.0", "42") ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_number_eq(\"the number is 42.0\", \"42\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_number_eq(\"the number is 42.0\", \"42\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_number_eq(\"the number is 42.0\", \"42\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 5:

When used in the following Stack expression it returns a  value of type **Boolean**: `false`.

```
> has_number_eq("the number is 40", "42")
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_number_eq("the number is 40", "42") ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_number_eq(\"the number is 40\", \"42\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_number_eq(\"the number is 40\", \"42\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_number_eq(\"the number is 40\", \"42\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

## Example 6:

When used in the following Stack expression it returns a  value of type **Boolean**: `false`.

```
> has_number_eq("the number is 40", "foo")
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_number_eq("the number is 40", "foo") ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_number_eq(\"the number is 40\", \"foo\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_number_eq(\"the number is 40\", \"foo\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_number_eq(\"the number is 40\", \"foo\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

## Example 7:

When used in the following Stack expression it returns a  value of type **Boolean**: `false`.

```
> has_number_eq("four hundred", "foo")
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_number_eq("four hundred", "foo") ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_number_eq(\"four hundred\", \"foo\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_number_eq(\"four hundred\", \"foo\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_number_eq(\"four hundred\", \"foo\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

# `has_number_gt`

Tests whether `expression` contains a number greater than min

## Example 1:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> has_number_gt("the number is 42", 40)
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_number_gt("the number is 42", 40) ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_number_gt(\"the number is 42\", 40) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_number_gt(\"the number is 42\", 40)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_number_gt(\"the number is 42\", 40)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 2:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> has_number_gt("the number is 42", 40.0)
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_number_gt("the number is 42", 40.0) ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_number_gt(\"the number is 42\", 40.0) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_number_gt(\"the number is 42\", 40.0)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_number_gt(\"the number is 42\", 40.0)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 3:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> has_number_gt("the number is 42", "40")
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_number_gt("the number is 42", "40") ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_number_gt(\"the number is 42\", \"40\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_number_gt(\"the number is 42\", \"40\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_number_gt(\"the number is 42\", \"40\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 4:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> has_number_gt("the number is 42.0", "40")
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_number_gt("the number is 42.0", "40") ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_number_gt(\"the number is 42.0\", \"40\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_number_gt(\"the number is 42.0\", \"40\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_number_gt(\"the number is 42.0\", \"40\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 5:

When used in the following Stack expression it returns a  value of type **Boolean**: `false`.

```
> has_number_gt("the number is 40", "40")
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_number_gt("the number is 40", "40") ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_number_gt(\"the number is 40\", \"40\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_number_gt(\"the number is 40\", \"40\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_number_gt(\"the number is 40\", \"40\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

## Example 6:

When used in the following Stack expression it returns a  value of type **Boolean**: `false`.

```
> has_number_gt("the number is 40", "foo")
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_number_gt("the number is 40", "foo") ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_number_gt(\"the number is 40\", \"foo\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_number_gt(\"the number is 40\", \"foo\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_number_gt(\"the number is 40\", \"foo\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

## Example 7:

When used in the following Stack expression it returns a  value of type **Boolean**: `false`.

```
> has_number_gt("four hundred", "foo")
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_number_gt("four hundred", "foo") ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_number_gt(\"four hundred\", \"foo\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_number_gt(\"four hundred\", \"foo\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_number_gt(\"four hundred\", \"foo\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

# `has_number_gte`

Tests whether `expression` contains a number greater than or equal to min

## Example 1:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> has_number_gte("the number is 42", 42)
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_number_gte("the number is 42", 42) ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_number_gte(\"the number is 42\", 42) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_number_gte(\"the number is 42\", 42)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_number_gte(\"the number is 42\", 42)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 2:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> has_number_gte("the number is 42", 42.0)
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_number_gte("the number is 42", 42.0) ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_number_gte(\"the number is 42\", 42.0) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_number_gte(\"the number is 42\", 42.0)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_number_gte(\"the number is 42\", 42.0)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 3:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> has_number_gte("the number is 42", "42")
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_number_gte("the number is 42", "42") ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_number_gte(\"the number is 42\", \"42\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_number_gte(\"the number is 42\", \"42\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_number_gte(\"the number is 42\", \"42\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 4:

When used in the following Stack expression it returns a  value of type **Boolean**: `false`.

```
> has_number_gte("the number is 42.0", "45")
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_number_gte("the number is 42.0", "45") ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_number_gte(\"the number is 42.0\", \"45\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_number_gte(\"the number is 42.0\", \"45\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_number_gte(\"the number is 42.0\", \"45\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

## Example 5:

When used in the following Stack expression it returns a  value of type **Boolean**: `false`.

```
> has_number_gte("the number is 40", "45")
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_number_gte("the number is 40", "45") ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_number_gte(\"the number is 40\", \"45\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_number_gte(\"the number is 40\", \"45\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_number_gte(\"the number is 40\", \"45\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

## Example 6:

When used in the following Stack expression it returns a  value of type **Boolean**: `false`.

```
> has_number_gte("the number is 40", "foo")
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_number_gte("the number is 40", "foo") ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_number_gte(\"the number is 40\", \"foo\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_number_gte(\"the number is 40\", \"foo\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_number_gte(\"the number is 40\", \"foo\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

## Example 7:

When used in the following Stack expression it returns a  value of type **Boolean**: `false`.

```
> has_number_gte("four hundred", "foo")
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_number_gte("four hundred", "foo") ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_number_gte(\"four hundred\", \"foo\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_number_gte(\"four hundred\", \"foo\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_number_gte(\"four hundred\", \"foo\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

# `has_number_lt`

Tests whether `expression` contains a number less than max

## Example 1:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> has_number_lt("the number is 42", 44)
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_number_lt("the number is 42", 44) ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_number_lt(\"the number is 42\", 44) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_number_lt(\"the number is 42\", 44)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_number_lt(\"the number is 42\", 44)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 2:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> has_number_lt("the number is 42", 44.0)
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_number_lt("the number is 42", 44.0) ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_number_lt(\"the number is 42\", 44.0) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_number_lt(\"the number is 42\", 44.0)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_number_lt(\"the number is 42\", 44.0)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 3:

When used in the following Stack expression it returns a  value of type **Boolean**: `false`.

```
> has_number_lt("the number is 42", "40")
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_number_lt("the number is 42", "40") ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_number_lt(\"the number is 42\", \"40\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_number_lt(\"the number is 42\", \"40\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_number_lt(\"the number is 42\", \"40\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

## Example 4:

When used in the following Stack expression it returns a  value of type **Boolean**: `false`.

```
> has_number_lt("the number is 42.0", "40")
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_number_lt("the number is 42.0", "40") ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_number_lt(\"the number is 42.0\", \"40\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_number_lt(\"the number is 42.0\", \"40\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_number_lt(\"the number is 42.0\", \"40\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

## Example 5:

When used in the following Stack expression it returns a  value of type **Boolean**: `false`.

```
> has_number_lt("the number is 40", "40")
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_number_lt("the number is 40", "40") ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_number_lt(\"the number is 40\", \"40\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_number_lt(\"the number is 40\", \"40\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_number_lt(\"the number is 40\", \"40\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

## Example 6:

When used in the following Stack expression it returns a  value of type **Boolean**: `false`.

```
> has_number_lt("the number is 40", "foo")
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_number_lt("the number is 40", "foo") ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_number_lt(\"the number is 40\", \"foo\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_number_lt(\"the number is 40\", \"foo\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_number_lt(\"the number is 40\", \"foo\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

## Example 7:

When used in the following Stack expression it returns a  value of type **Boolean**: `false`.

```
> has_number_lt("four hundred", "foo")
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_number_lt("four hundred", "foo") ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_number_lt(\"four hundred\", \"foo\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_number_lt(\"four hundred\", \"foo\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_number_lt(\"four hundred\", \"foo\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

# `has_number_lte`

Tests whether `expression` contains a number less than or equal to max

## Example 1:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> has_number_lte("the number is 42", 42)
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_number_lte("the number is 42", 42) ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_number_lte(\"the number is 42\", 42) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_number_lte(\"the number is 42\", 42)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_number_lte(\"the number is 42\", 42)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 2:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> has_number_lte("the number is 42", 42.0)
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_number_lte("the number is 42", 42.0) ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_number_lte(\"the number is 42\", 42.0) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_number_lte(\"the number is 42\", 42.0)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_number_lte(\"the number is 42\", 42.0)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 3:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> has_number_lte("the number is 42", "42")
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_number_lte("the number is 42", "42") ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_number_lte(\"the number is 42\", \"42\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_number_lte(\"the number is 42\", \"42\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_number_lte(\"the number is 42\", \"42\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 4:

When used in the following Stack expression it returns a  value of type **Boolean**: `false`.

```
> has_number_lte("the number is 42.0", "40")
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_number_lte("the number is 42.0", "40") ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_number_lte(\"the number is 42.0\", \"40\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_number_lte(\"the number is 42.0\", \"40\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_number_lte(\"the number is 42.0\", \"40\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

## Example 5:

When used in the following Stack expression it returns a  value of type **Boolean**: `false`.

```
> has_number_lte("the number is 40", "foo")
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_number_lte("the number is 40", "foo") ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_number_lte(\"the number is 40\", \"foo\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_number_lte(\"the number is 40\", \"foo\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_number_lte(\"the number is 40\", \"foo\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

## Example 6:

When used in the following Stack expression it returns a  value of type **Boolean**: `false`.

```
> has_number_lte("four hundred", "foo")
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_number_lte("four hundred", "foo") ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_number_lte(\"four hundred\", \"foo\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_number_lte(\"four hundred\", \"foo\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_number_lte(\"four hundred\", \"foo\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

## Example 7:

When used in the following Stack expression it returns a  value of type **Boolean**: `true` when used with the following context:

```elixir
%{"response" => 3}
```

```
> has_number_lte(response, 5)
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_number_lte(response, 5) ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_number_lte(response, 5) impact",
    ...>   Expression.V2.Context.new(%{"response" => 3}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_number_lte(response, 5)",
    ...>   Expression.V2.Context.new(%{"response" => 3}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_number_lte(response, 5)",
    ...>   Expression.V2.Context.new(%{"response" => 3}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

# `has_only_phrase`

Tests whether the text contains only phrase

The phrase must be the only text in the text to match

## Example 1:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> has_only_phrase("Quick Brown", "quick brown")
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_only_phrase("Quick Brown", "quick brown") ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_only_phrase(\"Quick Brown\", \"quick brown\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_only_phrase(\"Quick Brown\", \"quick brown\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_only_phrase(\"Quick Brown\", \"quick brown\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 2:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> has_only_phrase("", " ")
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_only_phrase("", " ") ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_only_phrase(\"\", \" \") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_only_phrase(\"\", \" \")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_only_phrase(\"\", \" \")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 3:

When used in the following Stack expression it returns a  value of type **Boolean**: `false`.

```
> has_only_phrase("The Quick Brown Fox", "quick brown")
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_only_phrase("The Quick Brown Fox", "quick brown") ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_only_phrase(\"The Quick Brown Fox\", \"quick brown\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_only_phrase(\"The Quick Brown Fox\", \"quick brown\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_only_phrase(\"The Quick Brown Fox\", \"quick brown\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

# `has_only_text`

Returns whether two text values are equal (case sensitive). In the case that they are, it will return the text as the match.

## Example 1:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> has_only_text("foo", "foo")
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_only_text("foo", "foo") ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_only_text(\"foo\", \"foo\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_only_text(\"foo\", \"foo\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_only_text(\"foo\", \"foo\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 2:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> has_only_text("", "")
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_only_text("", "") ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_only_text(\"\", \"\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_only_text(\"\", \"\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_only_text(\"\", \"\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 3:

When used in the following Stack expression it returns a  value of type **Boolean**: `false`.

```
> has_only_text("foo", "FOO")
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_only_text("foo", "FOO") ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_only_text(\"foo\", \"FOO\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_only_text(\"foo\", \"FOO\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_only_text(\"foo\", \"FOO\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

# `has_pattern`

Tests whether `expression` matches the regex pattern

Both text values are trimmed of surrounding whitespace and matching is case-insensitive.

## Example 1:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> has_pattern("Buy cheese please", "buy (\w+)")
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_pattern("Buy cheese please", "buy (\w+)") ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_pattern(\"Buy cheese please\", \"buy (\\w+)\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_pattern(\"Buy cheese please\", \"buy (\\w+)\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_pattern(\"Buy cheese please\", \"buy (\\w+)\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 2:

When used in the following Stack expression it returns a  value of type **Boolean**: `false`.

```
> has_pattern("Sell cheese please", "buy (\w+)")
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_pattern("Sell cheese please", "buy (\w+)") ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_pattern(\"Sell cheese please\", \"buy (\\w+)\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_pattern(\"Sell cheese please\", \"buy (\\w+)\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_pattern(\"Sell cheese please\", \"buy (\\w+)\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

# `has_phone`

Tests whether `expression` contains a phone number.
The optional country_code argument specifies the country to use for parsing.

## Example 1:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> has_phone("my number is +12067799294 thanks")
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_phone("my number is +12067799294 thanks") ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_phone(\"my number is +12067799294 thanks\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_phone(\"my number is +12067799294 thanks\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_phone(\"my number is +12067799294 thanks\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 2:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> has_phone("my number is 2067799294 thanks", "US")
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_phone("my number is 2067799294 thanks", "US") ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_phone(\"my number is 2067799294 thanks\", \"US\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_phone(\"my number is 2067799294 thanks\", \"US\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_phone(\"my number is 2067799294 thanks\", \"US\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 3:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> has_phone("my number is 206 779 9294 thanks", "US")
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_phone("my number is 206 779 9294 thanks", "US") ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_phone(\"my number is 206 779 9294 thanks\", \"US\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_phone(\"my number is 206 779 9294 thanks\", \"US\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_phone(\"my number is 206 779 9294 thanks\", \"US\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 4:

When used in the following Stack expression it returns a  value of type **Boolean**: `false`.

```
> has_phone("my number is none of your business", "US")
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_phone("my number is none of your business", "US") ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_phone(\"my number is none of your business\", \"US\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_phone(\"my number is none of your business\", \"US\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_phone(\"my number is none of your business\", \"US\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

# `has_phone`

# `has_phrase`

Tests whether phrase is contained in `expression`

The words in the test phrase must appear in the same order with no other words in between.

## Example 1:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> has_phrase("the quick brown fox", "brown fox")
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_phrase("the quick brown fox", "brown fox") ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_phrase(\"the quick brown fox\", \"brown fox\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_phrase(\"the quick brown fox\", \"brown fox\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_phrase(\"the quick brown fox\", \"brown fox\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 2:

When used in the following Stack expression it returns a  value of type **Boolean**: `false`.

```
> has_phrase("the quick brown fox", "quick fox")
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_phrase("the quick brown fox", "quick fox") ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_phrase(\"the quick brown fox\", \"quick fox\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_phrase(\"the quick brown fox\", \"quick fox\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_phrase(\"the quick brown fox\", \"quick fox\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

## Example 3:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> has_phrase("the quick brown fox", "")
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_phrase("the quick brown fox", "") ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_phrase(\"the quick brown fox\", \"\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_phrase(\"the quick brown fox\", \"\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_phrase(\"the quick brown fox\", \"\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

# `has_text`

Tests whether there the `expression` has any characters in it

## Example 1:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> has_text("quick brown")
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_text("quick brown") ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_text(\"quick brown\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_text(\"quick brown\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_text(\"quick brown\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 2:

When used in the following Stack expression it returns a  value of type **Boolean**: `false`.

```
> has_text("")
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_text("") ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_text(\"\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_text(\"\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_text(\"\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

## Example 3:

When used in the following Stack expression it returns a  value of type **Boolean**: `false`.

```
> has_text(" 
> ")
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_text(" 
") ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_text(\" \n\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_text(\" \n\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_text(\" \n\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

## Example 4:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> has_text(123)
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_text(123) ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_text(123) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_text(123)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_text(123)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

# `has_time`

Tests whether `expression` contains a time.

## Example 1:

When used in the following Stack expression it returns a complex **Boolean** type of default value:
```elixir
true
```
with the following fields:

* *match* of type **Time**
.

```
> has_time("the time is 10:30")
%{"__value__" => true, "match" => ~T[10:30:00]}
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_time("the time is 10:30") ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_time(\"the time is 10:30\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", %{"__value__" => true, "match" => ~T[10:30:00]}, " impact"] = result
    ["chat for ", %{"__value__" => true, "match" => ~T[10:30:00]}, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_time(\"the time is 10:30\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert %{"__value__" => true, "match" => ~T[10:30:00]} = result
    %{"__value__" => true, "match" => ~T[10:30:00]}
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_time(\"the time is 10:30\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 2:

When used in the following Stack expression it returns a complex **Boolean** type of default value:
```elixir
true
```
with the following fields:

* *match* of type **Time**
.

```
> has_time("the time is 10:00 pm")
%{"__value__" => true, "match" => ~T[10:00:00]}
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_time("the time is 10:00 pm") ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_time(\"the time is 10:00 pm\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", %{"__value__" => true, "match" => ~T[10:00:00]}, " impact"] = result
    ["chat for ", %{"__value__" => true, "match" => ~T[10:00:00]}, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_time(\"the time is 10:00 pm\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert %{"__value__" => true, "match" => ~T[10:00:00]} = result
    %{"__value__" => true, "match" => ~T[10:00:00]}
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_time(\"the time is 10:00 pm\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 3:

When used in the following Stack expression it returns a complex **Boolean** type of default value:
```elixir
true
```
with the following fields:

* *match* of type **Time**
.

```
> has_time("the time is 10:30:45")
%{"__value__" => true, "match" => ~T[10:30:45]}
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_time("the time is 10:30:45") ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_time(\"the time is 10:30:45\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", %{"__value__" => true, "match" => ~T[10:30:45]}, " impact"] = result
    ["chat for ", %{"__value__" => true, "match" => ~T[10:30:45]}, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_time(\"the time is 10:30:45\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert %{"__value__" => true, "match" => ~T[10:30:45]} = result
    %{"__value__" => true, "match" => ~T[10:30:45]}
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_time(\"the time is 10:30:45\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 4:

When used in the following Stack expression it returns a  value of type **Boolean**: `false`.

```
> has_time("there is no time here, just the number 25")
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @has_time("there is no time here, just the number 25") ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @has_time(\"there is no time here, just the number 25\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "has_time(\"there is no time here, just the number 25\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@has_time(\"there is no time here, just the number 25\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

# `hour`

Returns only the hour of a datetime (0 to 23)

## Example 1:

> Get the current hour

When used in the following Stack expression it returns a  value of type **Integer**: `20`.

```
> hour(now())
20
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @hour(now()) ..."
"20"
```

    ..$> # Evaluate a string with expressions
    ..$> import ExUnit.Assertions
    ..$> result = Expression.V2.eval(
    ...>   "chat for @hour(now()) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    ..$> assert ["chat for ", 20, " impact"] = result
    ["chat for ", 20, " impact"]
    ..$>
    ..$> # Evaluate a standalone expression block
    ..$> result = Expression.V2.eval_block(
    ...>   "hour(now())",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    ..$>
    ..$> assert 20 = result
    20
    ..$>
    ..$> # Evaluate a string with expressions into a single string
    ..$> Expression.V2.eval_as_string(
    ...>   "@hour(now())",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "20"

---

# `isbool`

Returns `true` if the argument is a boolean.

## Example 1:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> isbool(true)
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @isbool(true) ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @isbool(true) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "isbool(true)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@isbool(true)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 2:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> isbool(false)
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @isbool(false) ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @isbool(false) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "isbool(false)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@isbool(false)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 3:

When used in the following Stack expression it returns a  value of type **Boolean**: `false`.

```
> isbool(1)
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @isbool(1) ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @isbool(1) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "isbool(1)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@isbool(1)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

## Example 4:

When used in the following Stack expression it returns a  value of type **Boolean**: `false`.

```
> isbool(0)
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @isbool(0) ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @isbool(0) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "isbool(0)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@isbool(0)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

## Example 5:

When used in the following Stack expression it returns a  value of type **Boolean**: `false`.

```
> isbool("true")
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @isbool("true") ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @isbool(\"true\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "isbool(\"true\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@isbool(\"true\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

## Example 6:

When used in the following Stack expression it returns a  value of type **Boolean**: `false`.

```
> isbool("false")
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @isbool("false") ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @isbool(\"false\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "isbool(\"false\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@isbool(\"false\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

# `isnumber`

Returns `true` if the argument is a number.

## Example 1:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> isnumber(1)
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @isnumber(1) ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @isnumber(1) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "isnumber(1)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@isnumber(1)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 2:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> isnumber(1.0)
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @isnumber(1.0) ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @isnumber(1.0) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "isnumber(1.0)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@isnumber(1.0)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 3:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> isnumber("1.0")
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @isnumber("1.0") ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @isnumber(\"1.0\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "isnumber(\"1.0\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@isnumber(\"1.0\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 4:

When used in the following Stack expression it returns a  value of type **Boolean**: `false`.

```
> isnumber("a")
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @isnumber("a") ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @isnumber(\"a\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "isnumber(\"a\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@isnumber(\"a\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

# `isstring`

Returns `true` if the argument is a string.

## Example 1:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> isstring("hello")
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @isstring("hello") ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @isstring(\"hello\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "isstring(\"hello\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@isstring(\"hello\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 2:

When used in the following Stack expression it returns a  value of type **Boolean**: `false`.

```
> isstring(false)
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @isstring(false) ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @isstring(false) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "isstring(false)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@isstring(false)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

## Example 3:

When used in the following Stack expression it returns a  value of type **Boolean**: `false`.

```
> isstring(1)
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @isstring(1) ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @isstring(1) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "isstring(1)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@isstring(1)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

# `left`

Returns the first characters in a text string. This is Unicode safe.

## Example 1:

When used in the following Stack expression it returns a  value of type **String**: `"foob"`.

```
> left("foobar", 4)
"foob"
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @left("foobar", 4) ..."
"foob"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @left(\"foobar\", 4) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", "foob", " impact"] = result
    ["chat for ", "foob", " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "left(\"foobar\", 4)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert "foob" = result
    "foob"
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@left(\"foobar\", 4)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "foob"

---

## Example 2:

When used in the following Stack expression it returns a  value of type **String**: `"Умерла Мадлен Олбрай"`.

```
> left("Умерла Мадлен Олбрайт - первая женщина на посту главы Госдепа США", 20)
"Умерла Мадлен Олбрай"
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @left("Умерла Мадлен Олбрайт - первая женщина на посту главы Госдепа США", 20) ..."
"Умерла Мадлен Олбрай"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @left(\"Умерла Мадлен Олбрайт - первая женщина на посту главы Госдепа США\", 20) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", "Умерла Мадлен Олбрай", " impact"] = result
    ["chat for ", "Умерла Мадлен Олбрай", " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "left(\"Умерла Мадлен Олбрайт - первая женщина на посту главы Госдепа США\", 20)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert "Умерла Мадлен Олбрай" = result
    "Умерла Мадлен Олбрай"
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@left(\"Умерла Мадлен Олбрайт - первая женщина на посту главы Госдепа США\", 20)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "Умерла Мадлен Олбрай"

---

# `len`

Returns the number of characters in a text string

## Example 1:

When used in the following Stack expression it returns a  value of type **Integer**: `3`.

```
> len("foo")
3
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @len("foo") ..."
"3"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @len(\"foo\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", 3, " impact"] = result
    ["chat for ", 3, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "len(\"foo\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert 3 = result
    3
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@len(\"foo\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "3"

---

## Example 2:

When used in the following Stack expression it returns a  value of type **Integer**: `3`.

```
> len("zoë")
3
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @len("zoë") ..."
"3"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @len(\"zoë\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", 3, " impact"] = result
    ["chat for ", 3, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "len(\"zoë\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert 3 = result
    3
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@len(\"zoë\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "3"

---

# `lower`

Converts a text string to lowercase

## Example 1:

When used in the following Stack expression it returns a  value of type **String**: `"foo bar"`.

```
> lower("Foo Bar")
"foo bar"
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @lower("Foo Bar") ..."
"foo bar"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @lower(\"Foo Bar\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", "foo bar", " impact"] = result
    ["chat for ", "foo bar", " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "lower(\"Foo Bar\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert "foo bar" = result
    "foo bar"
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@lower(\"Foo Bar\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "foo bar"

---

# `map`

map over a list of items and apply the mapper function to every item, returning
the result.

## Example 1:

> Map over the range of numbers, create a date in January for every number

When used in the following Stack expression it returns a  value of type **List with values Date, Date, Date**: `[~D[2022-01-01], ~D[2022-01-02], ~D[2022-01-03]]`.

```
> map(1..3, &date(2022, 1, &1))
[~D[2022-01-01], ~D[2022-01-02], ~D[2022-01-03]]
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @map(1..3, &date(2022, 1, &1)) ..."
"2022-01-012022-01-022022-01-03"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @map(1..3, &date(2022, 1, &1)) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", [~D[2022-01-01], ~D[2022-01-02], ~D[2022-01-03]], " impact"] = result
    ["chat for ", [~D[2022-01-01], ~D[2022-01-02], ~D[2022-01-03]], " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "map(1..3, &date(2022, 1, &1))",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert [~D[2022-01-01], ~D[2022-01-02], ~D[2022-01-03]] = result
    [~D[2022-01-01], ~D[2022-01-02], ~D[2022-01-03]]
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@map(1..3, &date(2022, 1, &1))",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "2022-01-012022-01-022022-01-03"

---

## Example 2:

> Map over the range of numbers, multiple each by itself and return the result

When used in the following Stack expression it returns a  value of type **List with values Integer, Integer, Integer**: `[1, 4, 9]`.

```
> map(1..3, &(&1 * &1))
[1, 4, 9]
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @map(1..3, &(&1 * &1)) ..."
"149"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @map(1..3, &(&1 * &1)) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", [1, 4, 9], " impact"] = result
    ["chat for ", [1, 4, 9], " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "map(1..3, &(&1 * &1))",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert [1, 4, 9] = result
    [1, 4, 9]
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@map(1..3, &(&1 * &1))",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "149"

---

# `max_vargs`

Returns the maximum value of all arguments

## Example 1:

When used in the following Stack expression it returns a  value of type **Integer**: `3`.

```
> max(1, 2, 3)
3
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @max(1, 2, 3) ..."
"3"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @max(1, 2, 3) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", 3, " impact"] = result
    ["chat for ", 3, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "max(1, 2, 3)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert 3 = result
    3
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@max(1, 2, 3)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "3"

---

# `min_vargs`

Returns the minimum value of all arguments

## Example 1:

When used in the following Stack expression it returns a  value of type **Integer**: `1`.

```
> min(1, 2, 3)
1
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @min(1, 2, 3) ..."
"1"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @min(1, 2, 3) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", 1, " impact"] = result
    ["chat for ", 1, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "min(1, 2, 3)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert 1 = result
    1
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@min(1, 2, 3)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "1"

---

# `minute`

Returns only the minute of a datetime (0 to 59)

## Example 1:

> Get the current minute

When used in the following Stack expression it returns a  value of type **Integer**: `55`.

```
> minute(now())
55
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @minute(now()) ..."
"55"
```

    ..$> # Evaluate a string with expressions
    ..$> import ExUnit.Assertions
    ..$> result = Expression.V2.eval(
    ...>   "chat for @minute(now()) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    ..$> assert ["chat for ", 55, " impact"] = result
    ["chat for ", 55, " impact"]
    ..$>
    ..$> # Evaluate a standalone expression block
    ..$> result = Expression.V2.eval_block(
    ...>   "minute(now())",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    ..$>
    ..$> assert 55 = result
    55
    ..$>
    ..$> # Evaluate a string with expressions into a single string
    ..$> Expression.V2.eval_as_string(
    ...>   "@minute(now())",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "55"

---

# `month`

Returns only the month of a date (1 to 12)

## Example 1:

> Get the current month

When used in the following Stack expression it returns a  value of type **Integer**: `6`.

```
> month(now())
6
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @month(now()) ..."
"6"
```

    ..$> # Evaluate a string with expressions
    ..$> import ExUnit.Assertions
    ..$> result = Expression.V2.eval(
    ...>   "chat for @month(now()) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    ..$> assert ["chat for ", 6, " impact"] = result
    ["chat for ", 6, " impact"]
    ..$>
    ..$> # Evaluate a standalone expression block
    ..$> result = Expression.V2.eval_block(
    ...>   "month(now())",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    ..$>
    ..$> assert 6 = result
    6
    ..$>
    ..$> # Evaluate a string with expressions into a single string
    ..$> Expression.V2.eval_as_string(
    ...>   "@month(now())",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "6"

---

# `not_`

Returns `false` if the argument supplied evaluates to truth-y

## Example 1:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> not(false)
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @not(false) ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @not(false) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "not(false)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@not(false)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

# `now`

Returns the current date time as UTC

```
It is currently @NOW()
```

## Example 1:

> return the current timestamp as a DateTime value

When used in the following Stack expression it returns a  value of type **DateTime**: `~U[2026-06-03 20:55:34.021830Z]`.

```
> now()
~U[2026-06-03 20:55:34.021830Z]
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @now() ..."
"2026-06-03T20:55:34.021830Z"
```

    ..$> # Evaluate a string with expressions
    ..$> import ExUnit.Assertions
    ..$> result = Expression.V2.eval(
    ...>   "chat for @now() impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    ..$> assert ["chat for ", ~U[2026-06-03 20:55:34.021830Z], " impact"] = result
    ["chat for ", ~U[2026-06-03 20:55:34.021830Z], " impact"]
    ..$>
    ..$> # Evaluate a standalone expression block
    ..$> result = Expression.V2.eval_block(
    ...>   "now()",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    ..$>
    ..$> assert ~U[2026-06-03 20:55:34.021830Z] = result
    ~U[2026-06-03 20:55:34.021830Z]
    ..$>
    ..$> # Evaluate a string with expressions into a single string
    ..$> Expression.V2.eval_as_string(
    ...>   "@now()",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "2026-06-03T20:55:34.021830Z"

---

## Example 2:

> return the current datetime and format it using `datevalue`

When used in the following Stack expression it returns a complex **String** type of default value:
```elixir
"2026-06-03"
```
with the following fields:

* *date* of type **DateTime**
.

```
> datevalue(now(), "%Y-%m-%d")
%{"__value__" => "2026-06-03", "date" => ~U[2026-06-03 20:55:34.081456Z]}
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @datevalue(now(), "%Y-%m-%d") ..."
"2026-06-03"
```

    ..$> # Evaluate a string with expressions
    ..$> import ExUnit.Assertions
    ..$> result = Expression.V2.eval(
    ...>   "chat for @datevalue(now(), \"%Y-%m-%d\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    ..$> assert ["chat for ", %{"__value__" => "2026-06-03", "date" => ~U[2026-06-03 20:55:34.081456Z]}, " impact"] = result
    ["chat for ", %{"__value__" => "2026-06-03", "date" => ~U[2026-06-03 20:55:34.081456Z]}, " impact"]
    ..$>
    ..$> # Evaluate a standalone expression block
    ..$> result = Expression.V2.eval_block(
    ...>   "datevalue(now(), \"%Y-%m-%d\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    ..$>
    ..$> assert %{"__value__" => "2026-06-03", "date" => ~U[2026-06-03 20:55:34.081456Z]} = result
    %{"__value__" => "2026-06-03", "date" => ~U[2026-06-03 20:55:34.081456Z]}
    ..$>
    ..$> # Evaluate a string with expressions into a single string
    ..$> Expression.V2.eval_as_string(
    ...>   "@datevalue(now(), \"%Y-%m-%d\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "2026-06-03"

---

# `or_vargs`

Returns `true` if any argument is `true`.
Returns the first truthy value found or otherwise false.

Accepts any amount of arguments for testing truthiness.

## Example 1:

> Return true if any of the values are true

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> true or false
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @or(true, false) ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @or(true, false) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "or(true, false)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@or(true, false)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 2:

> Return the first value that is truthy

When used in the following Stack expression it returns a  value of type **String**: `"foo"`.

```
> false or "foo"
"foo"
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @or(false, "foo") ..."
"foo"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @or(false, \"foo\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", "foo", " impact"] = result
    ["chat for ", "foo", " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "or(false, \"foo\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert "foo" = result
    "foo"
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@or(false, \"foo\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "foo"

---

## Example 3:

When used in the following Stack expression it returns a  value of type **Boolean**: `true`.

```
> true or true
true
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @or(true, true) ..."
"true"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @or(true, true) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", true, " impact"] = result
    ["chat for ", true, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "or(true, true)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert true = result
    true
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@or(true, true)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "true"

---

## Example 4:

When used in the following Stack expression it returns a  value of type **Boolean**: `false`.

```
> false or false
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @or(false, false) ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @or(false, false) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "or(false, false)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@or(false, false)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

## Example 5:

When used in the following Stack expression it returns a  value of type **String**: `"bee"` when used with the following context:

```elixir
%{"a" => false, "b" => "bee"}
```

```
> a or b
"bee"
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @or(a, b) ..."
"bee"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @or(a, b) impact",
    ...>   Expression.V2.Context.new(%{"a" => false, "b" => "bee"}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", "bee", " impact"] = result
    ["chat for ", "bee", " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "or(a, b)",
    ...>   Expression.V2.Context.new(%{"a" => false, "b" => "bee"}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert "bee" = result
    "bee"
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@or(a, b)",
    ...>   Expression.V2.Context.new(%{"a" => false, "b" => "bee"}, Expression.V2.Callbacks.Standard)
    ...> )
    "bee"

---

## Example 6:

When used in the following Stack expression it returns a  value of type **String**: `"a"` when used with the following context:

```elixir
%{"a" => "a", "b" => false}
```

```
> a or b
"a"
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @or(a, b) ..."
"a"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @or(a, b) impact",
    ...>   Expression.V2.Context.new(%{"a" => "a", "b" => false}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", "a", " impact"] = result
    ["chat for ", "a", " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "or(a, b)",
    ...>   Expression.V2.Context.new(%{"a" => "a", "b" => false}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert "a" = result
    "a"
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@or(a, b)",
    ...>   Expression.V2.Context.new(%{"a" => "a", "b" => false}, Expression.V2.Callbacks.Standard)
    ...> )
    "a"

---

## Example 7:

When used in the following Stack expression it returns a  value of type **Boolean**: `false` when used with the following context:

```elixir
%{}
```

```
> b or b
false
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @or(b, b) ..."
"false"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @or(b, b) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", false, " impact"] = result
    ["chat for ", false, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "or(b, b)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> refute result
    false
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@or(b, b)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "false"

---

# `parse_float`

```elixir
@spec parse_float(number() | String.t()) :: number() | nil
```

# `percent`

Formats a number as a percentage

## Example 1:

When used in the following Stack expression it returns a  value of type **String**: `"20%"`.

```
> percent(2/10)
"20%"
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @percent(2/10) ..."
"20%"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @percent(2/10) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", "20%", " impact"] = result
    ["chat for ", "20%", " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "percent(2/10)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert "20%" = result
    "20%"
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@percent(2/10)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "20%"

---

## Example 2:

When used in the following Stack expression it returns a  value of type **String**: `"20%"`.

```
> percent(0.2)
"20%"
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @percent(0.2) ..."
"20%"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @percent(0.2) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", "20%", " impact"] = result
    ["chat for ", "20%", " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "percent(0.2)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert "20%" = result
    "20%"
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@percent(0.2)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "20%"

---

## Example 3:

When used in the following Stack expression it returns a  value of type **String**: `"20%"` when used with the following context:

```elixir
%{"d" => "0.2"}
```

```
> percent(d)
"20%"
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @percent(d) ..."
"20%"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @percent(d) impact",
    ...>   Expression.V2.Context.new(%{"d" => "0.2"}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", "20%", " impact"] = result
    ["chat for ", "20%", " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "percent(d)",
    ...>   Expression.V2.Context.new(%{"d" => "0.2"}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert "20%" = result
    "20%"
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@percent(d)",
    ...>   Expression.V2.Context.new(%{"d" => "0.2"}, Expression.V2.Callbacks.Standard)
    ...> )
    "20%"

---

# `power`

Returns the result of a number raised to a power - equivalent to the ^ operator

## Example 1:

When used in the following Stack expression it returns a  value of type **Float**: `8.0`.

```
> power(2, 3)
8.0
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @power(2, 3) ..."
"8.0"
```

    ..$> # Evaluate a string with expressions
    ..$> import ExUnit.Assertions
    ..$> result = Expression.V2.eval(
    ...>   "chat for @power(2, 3) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    ..$> assert ["chat for ", 8.0, " impact"] = result
    ["chat for ", 8.0, " impact"]
    ..$>
    ..$> # Evaluate a standalone expression block
    ..$> result = Expression.V2.eval_block(
    ...>   "power(2, 3)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    ..$>
    ..$> assert 8.0 = result
    8.0
    ..$>
    ..$> # Evaluate a string with expressions into a single string
    ..$> Expression.V2.eval_as_string(
    ...>   "@power(2, 3)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "8.0"

---

# `proper`

Capitalizes the first letter of every word in a text string

## Example 1:

When used in the following Stack expression it returns a  value of type **String**: `"Foo Bar"`.

```
> proper("foo bar")
"Foo Bar"
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @proper("foo bar") ..."
"Foo Bar"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @proper(\"foo bar\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", "Foo Bar", " impact"] = result
    ["chat for ", "Foo Bar", " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "proper(\"foo bar\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert "Foo Bar" = result
    "Foo Bar"
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@proper(\"foo bar\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "Foo Bar"

---

# `read_digits`

Formats digits in text for reading in TTS

## Example 1:

When used in the following Stack expression it returns a  value of type **String**: `"plus two seven one"`.

```
> read_digits("+271")
"plus two seven one"
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @read_digits("+271") ..."
"plus two seven one"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @read_digits(\"+271\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", "plus two seven one", " impact"] = result
    ["chat for ", "plus two seven one", " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "read_digits(\"+271\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert "plus two seven one" = result
    "plus two seven one"
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@read_digits(\"+271\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "plus two seven one"

---

# `rem`

Return the division remainder of two integers.

## Example 1:

When used in the following Stack expression it returns a  value of type **Integer**: `0`.

```
> rem(4, 2)
0
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @rem(4, 2) ..."
"0"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @rem(4, 2) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", 0, " impact"] = result
    ["chat for ", 0, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "rem(4, 2)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert 0 = result
    0
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@rem(4, 2)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "0"

---

## Example 2:

When used in the following Stack expression it returns a  value of type **Integer**: `1`.

```
> rem(85, 3)
1
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @rem(85, 3) ..."
"1"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @rem(85, 3) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", 1, " impact"] = result
    ["chat for ", 1, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "rem(85, 3)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert 1 = result
    1
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@rem(85, 3)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "1"

---

# `remove_first_word`

Removes the first word from the given text. The remaining text will be unchanged

## Example 1:

When used in the following Stack expression it returns a  value of type **String**: `"bar"`.

```
> remove_first_word("foo bar")
"bar"
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @remove_first_word("foo bar") ..."
"bar"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @remove_first_word(\"foo bar\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", "bar", " impact"] = result
    ["chat for ", "bar", " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "remove_first_word(\"foo bar\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert "bar" = result
    "bar"
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@remove_first_word(\"foo bar\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "bar"

---

## Example 2:

When used in the following Stack expression it returns a  value of type **String**: `"bar"`.

```
> remove_first_word("foo-bar", "-")
"bar"
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @remove_first_word("foo-bar", "-") ..."
"bar"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @remove_first_word(\"foo-bar\", \"-\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", "bar", " impact"] = result
    ["chat for ", "bar", " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "remove_first_word(\"foo-bar\", \"-\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert "bar" = result
    "bar"
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@remove_first_word(\"foo-bar\", \"-\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "bar"

---

# `remove_first_word`

# `rept`

Repeats text a given number of times

## Example 1:

When used in the following Stack expression it returns a  value of type **String**: `"**********"`.

```
> rept("*", 10)
"**********"
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @rept("*", 10) ..."
"**********"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @rept(\"*\", 10) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", "**********", " impact"] = result
    ["chat for ", "**********", " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "rept(\"*\", 10)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert "**********" = result
    "**********"
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@rept(\"*\", 10)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "**********"

---

# `right`

Returns the last characters in a text string.
This is Unicode safe.

## Example 1:

When used in the following Stack expression it returns a  value of type **String**: `"ing"`.

```
> right("testing", 3)
"ing"
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @right("testing", 3) ..."
"ing"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @right(\"testing\", 3) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", "ing", " impact"] = result
    ["chat for ", "ing", " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "right(\"testing\", 3)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert "ing" = result
    "ing"
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@right(\"testing\", 3)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "ing"

---

## Example 2:

When used in the following Stack expression it returns a  value of type **String**: `"ту главы Госдепа США"`.

```
> right("Умерла Мадлен Олбрайт - первая женщина на посту главы Госдепа США", 20)
"ту главы Госдепа США"
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @right("Умерла Мадлен Олбрайт - первая женщина на посту главы Госдепа США", 20) ..."
"ту главы Госдепа США"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @right(\"Умерла Мадлен Олбрайт - первая женщина на посту главы Госдепа США\", 20) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", "ту главы Госдепа США", " impact"] = result
    ["chat for ", "ту главы Госдепа США", " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "right(\"Умерла Мадлен Олбрайт - первая женщина на посту главы Госдепа США\", 20)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert "ту главы Госдепа США" = result
    "ту главы Госдепа США"
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@right(\"Умерла Мадлен Олбрайт - первая женщина на посту главы Госдепа США\", 20)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "ту главы Госдепа США"

---

# `second`

Returns only the second of a datetime (0 to 59)

## Example 1:

When used in the following Stack expression it returns a  value of type **Integer**: `34` when used with the following context:

```elixir
%{"now" => ~U[2026-06-03 20:55:34.081828Z]}
```

```
> second(now)
34
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @second(now) ..."
"34"
```

    ..$> # Evaluate a string with expressions
    ..$> import ExUnit.Assertions
    ..$> result = Expression.V2.eval(
    ...>   "chat for @second(now) impact",
    ...>   Expression.V2.Context.new(%{"now" => ~U[2026-06-03 20:55:34.081828Z]}, Expression.V2.Callbacks.Standard)
    ...> )
    ..$> assert ["chat for ", 34, " impact"] = result
    ["chat for ", 34, " impact"]
    ..$>
    ..$> # Evaluate a standalone expression block
    ..$> result = Expression.V2.eval_block(
    ...>   "second(now)",
    ...>   Expression.V2.Context.new(%{"now" => ~U[2026-06-03 20:55:34.081828Z]}, Expression.V2.Callbacks.Standard)
    ...> )
    ..$>
    ..$> assert 34 = result
    34
    ..$>
    ..$> # Evaluate a string with expressions into a single string
    ..$> Expression.V2.eval_as_string(
    ...>   "@second(now)",
    ...>   Expression.V2.Context.new(%{"now" => ~U[2026-06-03 20:55:34.081828Z]}, Expression.V2.Callbacks.Standard)
    ...> )
    "34"

---

# `substitute`

Substitutes new_text for old_text in a text string. If instance_num is given, then only that instance will be substituted

## Example 1:

When used in the following Stack expression it returns a  value of type **String**: `"I can do"`.

```
> substitute("I can't", "can't", "can do")
"I can do"
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @substitute("I can't", "can't", "can do") ..."
"I can do"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @substitute(\"I can't\", \"can't\", \"can do\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", "I can do", " impact"] = result
    ["chat for ", "I can do", " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "substitute(\"I can't\", \"can't\", \"can do\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert "I can do" = result
    "I can do"
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@substitute(\"I can't\", \"can't\", \"can do\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "I can do"

---

# `sum_vargs`

Returns the sum of all arguments, equivalent to the + operator

```
You have @SUM(contact.reports, contact.forms) reports and forms
```

## Example 1:

When used in the following Stack expression it returns a  value of type **Integer**: `6`.

```
> sum(1, 2, 3)
6
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @sum(1, 2, 3) ..."
"6"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @sum(1, 2, 3) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", 6, " impact"] = result
    ["chat for ", 6, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "sum(1, 2, 3)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert 6 = result
    6
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@sum(1, 2, 3)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "6"

---

# `time`

Defines a time value which can be used for time arithmetic

## Example 1:

When used in the following Stack expression it returns a  value of type **Time**: `~T[12:13:14]`.

```
> time(12, 13, 14)
~T[12:13:14]
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @time(12, 13, 14) ..."
"12:13:14"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @time(12, 13, 14) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", ~T[12:13:14], " impact"] = result
    ["chat for ", ~T[12:13:14], " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "time(12, 13, 14)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert ~T[12:13:14] = result
    ~T[12:13:14]
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@time(12, 13, 14)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "12:13:14"

---

# `timevalue`

Converts time stored in text to an actual time

## Example 1:

When used in the following Stack expression it returns a  value of type **Time**: `~T[02:30:00]`.

```
> timevalue("2:30")
~T[02:30:00]
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @timevalue("2:30") ..."
"02:30:00"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @timevalue(\"2:30\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", ~T[02:30:00], " impact"] = result
    ["chat for ", ~T[02:30:00], " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "timevalue(\"2:30\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert ~T[02:30:00] = result
    ~T[02:30:00]
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@timevalue(\"2:30\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "02:30:00"

---

## Example 2:

When used in the following Stack expression it returns a  value of type **Time**: `~T[02:30:55]`.

```
> timevalue("2:30:55")
~T[02:30:55]
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @timevalue("2:30:55") ..."
"02:30:55"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @timevalue(\"2:30:55\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", ~T[02:30:55], " impact"] = result
    ["chat for ", ~T[02:30:55], " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "timevalue(\"2:30:55\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert ~T[02:30:55] = result
    ~T[02:30:55]
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@timevalue(\"2:30:55\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "02:30:55"

---

# `today`

Returns the current date

## Example 1:

When used in the following Stack expression it returns a  value of type **Date**: `~D[2026-06-03]`.

```
> today()
~D[2026-06-03]
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @today() ..."
"2026-06-03"
```

    ..$> # Evaluate a string with expressions
    ..$> import ExUnit.Assertions
    ..$> result = Expression.V2.eval(
    ...>   "chat for @today() impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    ..$> assert ["chat for ", ~D[2026-06-03], " impact"] = result
    ["chat for ", ~D[2026-06-03], " impact"]
    ..$>
    ..$> # Evaluate a standalone expression block
    ..$> result = Expression.V2.eval_block(
    ...>   "today()",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    ..$>
    ..$> assert ~D[2026-06-03] = result
    ~D[2026-06-03]
    ..$>
    ..$> # Evaluate a string with expressions into a single string
    ..$> Expression.V2.eval_as_string(
    ...>   "@today()",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "2026-06-03"

---

# `unichar`

Returns the unicode character specified by a number

## Example 1:

When used in the following Stack expression it returns a  value of type **String**: `"A"`.

```
> unichar(65)
"A"
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @unichar(65) ..."
"A"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @unichar(65) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", "A", " impact"] = result
    ["chat for ", "A", " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "unichar(65)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert "A" = result
    "A"
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@unichar(65)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "A"

---

## Example 2:

When used in the following Stack expression it returns a  value of type **String**: `"é"`.

```
> unichar(233)
"é"
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @unichar(233) ..."
"é"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @unichar(233) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", "é", " impact"] = result
    ["chat for ", "é", " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "unichar(233)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert "é" = result
    "é"
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@unichar(233)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "é"

---

# `unicode`

Returns a numeric code for the first character in a text string

## Example 1:

When used in the following Stack expression it returns a  value of type **Integer**: `65`.

```
> unicode("A")
65
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @unicode("A") ..."
"65"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @unicode(\"A\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", 65, " impact"] = result
    ["chat for ", 65, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "unicode(\"A\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert 65 = result
    65
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@unicode(\"A\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "65"

---

## Example 2:

When used in the following Stack expression it returns a  value of type **Integer**: `233`.

```
> unicode("é")
233
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @unicode("é") ..."
"233"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @unicode(\"é\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", 233, " impact"] = result
    ["chat for ", 233, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "unicode(\"é\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert 233 = result
    233
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@unicode(\"é\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "233"

---

# `upper`

Converts a text string to uppercase

## Example 1:

When used in the following Stack expression it returns a  value of type **String**: `"FOO"`.

```
> upper("foo")
"FOO"
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @upper("foo") ..."
"FOO"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @upper(\"foo\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", "FOO", " impact"] = result
    ["chat for ", "FOO", " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "upper(\"foo\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert "FOO" = result
    "FOO"
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@upper(\"foo\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "FOO"

---

# `weekday`

Returns the day of the week of a date (1 for Sunday to 7 for Saturday)

## Example 1:

When used in the following Stack expression it returns a  value of type **Integer**: `1` when used with the following context:

```elixir
%{"today" => ~D[2022-11-06]}
```

```
> weekday(today)
1
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @weekday(today) ..."
"1"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @weekday(today) impact",
    ...>   Expression.V2.Context.new(%{"today" => ~D[2022-11-06]}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", 1, " impact"] = result
    ["chat for ", 1, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "weekday(today)",
    ...>   Expression.V2.Context.new(%{"today" => ~D[2022-11-06]}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert 1 = result
    1
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@weekday(today)",
    ...>   Expression.V2.Context.new(%{"today" => ~D[2022-11-06]}, Expression.V2.Callbacks.Standard)
    ...> )
    "1"

---

## Example 2:

When used in the following Stack expression it returns a  value of type **Integer**: `3` when used with the following context:

```elixir
%{"today" => ~D[2022-11-01]}
```

```
> weekday(today)
3
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @weekday(today) ..."
"3"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @weekday(today) impact",
    ...>   Expression.V2.Context.new(%{"today" => ~D[2022-11-01]}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", 3, " impact"] = result
    ["chat for ", 3, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "weekday(today)",
    ...>   Expression.V2.Context.new(%{"today" => ~D[2022-11-01]}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert 3 = result
    3
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@weekday(today)",
    ...>   Expression.V2.Context.new(%{"today" => ~D[2022-11-01]}, Expression.V2.Callbacks.Standard)
    ...> )
    "3"

---

# `word`

Extracts the nth word from the given text string. If stop is a negative number,
then it is treated as count backwards from the end of the text. If by_spaces is
specified and is `true` then the function splits the text into words only by spaces.
Otherwise the text is split by punctuation characters as well

## Example 1:

When used in the following Stack expression it returns a  value of type **String**: `"cow"`.

```
> word("hello cow-boy", 2)
"cow"
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @word("hello cow-boy", 2) ..."
"cow"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @word(\"hello cow-boy\", 2) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", "cow", " impact"] = result
    ["chat for ", "cow", " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "word(\"hello cow-boy\", 2)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert "cow" = result
    "cow"
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@word(\"hello cow-boy\", 2)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "cow"

---

## Example 2:

When used in the following Stack expression it returns a  value of type **String**: `"cow-boy"`.

```
> word("hello cow-boy", 2, true)
"cow-boy"
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @word("hello cow-boy", 2, true) ..."
"cow-boy"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @word(\"hello cow-boy\", 2, true) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", "cow-boy", " impact"] = result
    ["chat for ", "cow-boy", " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "word(\"hello cow-boy\", 2, true)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert "cow-boy" = result
    "cow-boy"
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@word(\"hello cow-boy\", 2, true)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "cow-boy"

---

## Example 3:

When used in the following Stack expression it returns a  value of type **String**: `"boy"`.

```
> word("hello cow-boy", -1)
"boy"
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @word("hello cow-boy", -1) ..."
"boy"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @word(\"hello cow-boy\", -1) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", "boy", " impact"] = result
    ["chat for ", "boy", " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "word(\"hello cow-boy\", -1)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert "boy" = result
    "boy"
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@word(\"hello cow-boy\", -1)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "boy"

---

# `word`

# `word_count`

Returns the number of words in the given text string. If by_spaces is specified and is `true` then the function splits the text into words only by spaces. Otherwise the text is split by punctuation characters as well

```
> You entered @word_count("one two three") words
You entered 3 words
```

## Example 1:

When used in the following Stack expression it returns a  value of type **Integer**: `3`.

```
> word_count("hello cow-boy")
3
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @word_count("hello cow-boy") ..."
"3"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @word_count(\"hello cow-boy\") impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", 3, " impact"] = result
    ["chat for ", 3, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "word_count(\"hello cow-boy\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert 3 = result
    3
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@word_count(\"hello cow-boy\")",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "3"

---

## Example 2:

When used in the following Stack expression it returns a  value of type **Integer**: `2`.

```
> word_count("hello cow-boy", true)
2
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @word_count("hello cow-boy", true) ..."
"2"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @word_count(\"hello cow-boy\", true) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", 2, " impact"] = result
    ["chat for ", 2, " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "word_count(\"hello cow-boy\", true)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert 2 = result
    2
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@word_count(\"hello cow-boy\", true)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "2"

---

# `word_count`

# `word_slice`

Extracts a substring of the words beginning at start, and up to but not-including stop.
If stop is omitted then the substring will be all words from start until the end of the text.
If stop is a negative number, then it is treated as count backwards from the end of the text.
If by_spaces is specified and is `true` then the function splits the text into words only by spaces.
Otherwise the text is split by punctuation characters as well

## Example 1:

When used in the following Stack expression it returns a  value of type **String**: `"expressions are"`.

```
> word_slice("FLOIP expressions are fun", 2, 4)
"expressions are"
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @word_slice("FLOIP expressions are fun", 2, 4) ..."
"expressions are"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @word_slice(\"FLOIP expressions are fun\", 2, 4) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", "expressions are", " impact"] = result
    ["chat for ", "expressions are", " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "word_slice(\"FLOIP expressions are fun\", 2, 4)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert "expressions are" = result
    "expressions are"
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@word_slice(\"FLOIP expressions are fun\", 2, 4)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "expressions are"

---

## Example 2:

When used in the following Stack expression it returns a  value of type **String**: `"expressions are fun"`.

```
> word_slice("FLOIP expressions are fun", 2)
"expressions are fun"
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @word_slice("FLOIP expressions are fun", 2) ..."
"expressions are fun"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @word_slice(\"FLOIP expressions are fun\", 2) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", "expressions are fun", " impact"] = result
    ["chat for ", "expressions are fun", " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "word_slice(\"FLOIP expressions are fun\", 2)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert "expressions are fun" = result
    "expressions are fun"
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@word_slice(\"FLOIP expressions are fun\", 2)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "expressions are fun"

---

## Example 3:

When used in the following Stack expression it returns a  value of type **String**: `"FLOIP expressions"`.

```
> word_slice("FLOIP expressions are fun", 1, -2)
"FLOIP expressions"
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @word_slice("FLOIP expressions are fun", 1, -2) ..."
"FLOIP expressions"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @word_slice(\"FLOIP expressions are fun\", 1, -2) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", "FLOIP expressions", " impact"] = result
    ["chat for ", "FLOIP expressions", " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "word_slice(\"FLOIP expressions are fun\", 1, -2)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert "FLOIP expressions" = result
    "FLOIP expressions"
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@word_slice(\"FLOIP expressions are fun\", 1, -2)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "FLOIP expressions"

---

## Example 4:

When used in the following Stack expression it returns a  value of type **String**: `"fun"`.

```
> word_slice("FLOIP expressions are fun", -1)
"fun"
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @word_slice("FLOIP expressions are fun", -1) ..."
"fun"
```

    iex> # Evaluate a string with expressions
    iex> import ExUnit.Assertions
    iex> result = Expression.V2.eval(
    ...>   "chat for @word_slice(\"FLOIP expressions are fun\", -1) impact",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex> assert ["chat for ", "fun", " impact"] = result
    ["chat for ", "fun", " impact"]
    iex>
    iex> # Evaluate a standalone expression block
    iex> result = Expression.V2.eval_block(
    ...>   "word_slice(\"FLOIP expressions are fun\", -1)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    iex>
    iex> assert "fun" = result
    "fun"
    iex>
    iex> # Evaluate a string with expressions into a single string
    iex> Expression.V2.eval_as_string(
    ...>   "@word_slice(\"FLOIP expressions are fun\", -1)",
    ...>   Expression.V2.Context.new(%{}, Expression.V2.Callbacks.Standard)
    ...> )
    "fun"

---

# `word_slice`

# `word_slice`

# `year`

Returns only the year of a date

## Example 1:

When used in the following Stack expression it returns a  value of type **Integer**: `2026` when used with the following context:

```elixir
%{"now" => ~U[2026-06-03 20:55:34.083660Z]}
```

```
> year(now)
2026
```

When used as an expression in text, prepend it with an `@`:

```expression
> "... @year(now) ..."
"2026"
```

    ..$> # Evaluate a string with expressions
    ..$> import ExUnit.Assertions
    ..$> result = Expression.V2.eval(
    ...>   "chat for @year(now) impact",
    ...>   Expression.V2.Context.new(%{"now" => ~U[2026-06-03 20:55:34.083660Z]}, Expression.V2.Callbacks.Standard)
    ...> )
    ..$> assert ["chat for ", 2026, " impact"] = result
    ["chat for ", 2026, " impact"]
    ..$>
    ..$> # Evaluate a standalone expression block
    ..$> result = Expression.V2.eval_block(
    ...>   "year(now)",
    ...>   Expression.V2.Context.new(%{"now" => ~U[2026-06-03 20:55:34.083660Z]}, Expression.V2.Callbacks.Standard)
    ...> )
    ..$>
    ..$> assert 2026 = result
    2026
    ..$>
    ..$> # Evaluate a string with expressions into a single string
    ..$> Expression.V2.eval_as_string(
    ...>   "@year(now)",
    ...>   Expression.V2.Context.new(%{"now" => ~U[2026-06-03 20:55:34.083660Z]}, Expression.V2.Callbacks.Standard)
    ...> )
    "2026"

---

---

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