# Generic Functions and Operators

|                                                                                                 |                                                                    |
| ----------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ |
| [`anytype = anytype`](https://docs.geldata.com/reference/stdlib/generic.md#operator::eq)        | Compares two values for equality.                                  |
| [`anytype != anytype`](https://docs.geldata.com/reference/stdlib/generic.md#operator::neq)      | Compares two values for inequality.                                |
| [`anytype ?= anytype`](https://docs.geldata.com/reference/stdlib/generic.md#operator::coaleq)   | Compares two (potentially empty) values for equality.              |
| [`anytype ?!= anytype`](https://docs.geldata.com/reference/stdlib/generic.md#operator::coalneq) | Compares two (potentially empty) values for inequality.            |
| [`anytype < anytype`](https://docs.geldata.com/reference/stdlib/generic.md#operator::lt)        | Less than operator.                                                |
| [`anytype > anytype`](https://docs.geldata.com/reference/stdlib/generic.md#operator::gt)        | Greater than operator.                                             |
| [`anytype <= anytype`](https://docs.geldata.com/reference/stdlib/generic.md#operator::lteq)     | Less or equal operator.                                            |
| [`anytype >= anytype`](https://docs.geldata.com/reference/stdlib/generic.md#operator::gteq)     | Greater or equal operator.                                         |
| [`len()`](https://docs.geldata.com/reference/stdlib/generic.md#function::std::len)              | Returns the number of elements of a given value.                   |
| [`contains()`](https://docs.geldata.com/reference/stdlib/generic.md#function::std::contains)    | Returns true if the given sub-value exists within the given value. |
| [`find()`](https://docs.geldata.com/reference/stdlib/generic.md#function::std::find)            | Returns the index of a given sub-value in a given value.           |

> Note: In EdgeQL, any value can be compared to another as long as their types are compatible.

## Operator: anytype = anytype

```eql
anytype = anytype -> bool
```

Compares two values for equality.

```edgeql-repl
db> select 3 = 3.0;
{true}
db> select 3 = 3.14;
{false}
db> select [1, 2] = [1, 2];
{true}
db> select (1, 2) = (x := 1, y := 2);
{true}
db> select (x := 1, y := 2) = (a := 1, b := 2);
{true}
db> select 'hello' = 'world';
{false}
```

> Warning: When either operand in an equality comparison is an empty set, the result will not be a `bool` but instead an empty set.
> 
> ```edgeql-repl
> db> select true = <bool>{};
> {}
> ```
> 
> If one of the operands in an equality comparison could be an empty set, you may want to use the [`coalescing equality`](https://docs.geldata.com/reference/stdlib/generic.md#operator::coaleq) operator (`?=`) instead.


## Operator: anytype != anytype

```eql
anytype != anytype -> bool
```

Compares two values for inequality.

```edgeql-repl
db> select 3 != 3.0;
{false}
db> select 3 != 3.14;
{true}
db> select [1, 2] != [2, 1];
{false}
db> select (1, 2) != (x := 1, y := 2);
{false}
db> select (x := 1, y := 2) != (a := 1, b := 2);
{false}
db> select 'hello' != 'world';
{true}
```

> Warning: When either operand in an inequality comparison is an empty set, the result will not be a `bool` but instead an empty set.
> 
> ```edgeql-repl
> db> select true != <bool>{};
> {}
> ```
> 
> If one of the operands in an inequality comparison could be an empty set, you may want to use the [`coalescing inequality`](https://docs.geldata.com/reference/stdlib/generic.md#operator::coaleq) operator (`?!=`) instead.


## Operator: anytype ?= anytype

```eql
optional anytype ?= optional anytype -> bool
```

Compares two (potentially empty) values for equality.

This works the same as a regular [`=`](https://docs.geldata.com/reference/stdlib/generic.md#operator::eq) operator, but also allows comparing an empty `{}` set. Two empty sets are considered equal.

```edgeql-repl
db> select {1} ?= {1.0};
{true}
db> select {1} ?= <int64>{};
{false}
db> select <int64>{} ?= <int64>{};
{true}
```


## Operator: anytype ?!= anytype

```eql
optional anytype ?!= optional anytype -> bool
```

Compares two (potentially empty) values for inequality.

This works the same as a regular [`=`](https://docs.geldata.com/reference/stdlib/generic.md#operator::eq) operator, but also allows comparing an empty `{}` set. Two empty sets are considered equal.

```edgeql-repl
db> select {2} ?!= {2};
{false}
db> select {1} ?!= <int64>{};
{true}
db> select <bool>{} ?!= <bool>{};
{false}
```


## Operator: anytype < anytype

```eql
anytype < anytype -> bool
```

Less than operator.

The operator returns `true` if the value of the left expression is less than the value of the right expression:

```edgeql-repl
db> select 1 < 2;
{true}
db> select 2 < 2;
{false}
db> select 'hello' < 'world';
{true}
db> select (1, 'hello') < (1, 'world');
{true}
```

> Warning: When either operand in a comparison is an empty set, the result will not be a `bool` but instead an empty set.
> 
> ```edgeql-repl
> db> select 1 < <int16>{};
> {}
> ```
> 
> If one of the operands in a comparison could be an empty set, you may want to coalesce the result of the comparison with `false` to ensure your result is boolean.
> 
> ```edgeql-repl
> db> select (1 < <int16>{}) ?? false;
> {false}
> ```


## Operator: anytype > anytype

```eql
anytype > anytype -> bool
```

Greater than operator.

The operator returns `true` if the value of the left expression is greater than the value of the right expression:

```edgeql-repl
db> select 1 > 2;
{false}
db> select 3 > 2;
{true}
db> select 'hello' > 'world';
{false}
db> select (1, 'hello') > (1, 'world');
{false}
```

> Warning: When either operand in a comparison is an empty set, the result will not be a `bool` but instead an empty set.
> 
> ```edgeql-repl
> db> select 1 > <int16>{};
> {}
> ```
> 
> If one of the operands in a comparison could be an empty set, you may want to coalesce the result of the comparison with `false` to ensure your result is boolean.
> 
> ```edgeql-repl
> db> select (1 > <int16>{}) ?? false;
> {false}
> ```


## Operator: anytype <= anytype

```eql
anytype <= anytype -> bool
```

Less or equal operator.

The operator returns `true` if the value of the left expression is less than or equal to the value of the right expression:

```edgeql-repl
db> select 1 <= 2;
{true}
db> select 2 <= 2;
{true}
db> select 3 <= 2;
{false}
db> select 'hello' <= 'world';
{true}
db> select (1, 'hello') <= (1, 'world');
{true}
```

> Warning: When either operand in a comparison is an empty set, the result will not be a `bool` but instead an empty set.
> 
> ```edgeql-repl
> db> select 1 <= <int16>{};
> {}
> ```
> 
> If one of the operands in a comparison could be an empty set, you may want to coalesce the result of the comparison with `false` to ensure your result is boolean.
> 
> ```edgeql-repl
> db> select (1 <= <int16>{}) ?? false;
> {false}
> ```


## Operator: anytype >= anytype

```eql
anytype >= anytype -> bool
```

Greater or equal operator.

The operator returns `true` if the value of the left expression is greater than or equal to the value of the right expression:

```edgeql-repl
db> select 1 >= 2;
{false}
db> select 2 >= 2;
{true}
db> select 3 >= 2;
{true}
db> select 'hello' >= 'world';
{false}
db> select (1, 'hello') >= (1, 'world');
{false}
```

> Warning: When either operand in a comparison is an empty set, the result will not be a `bool` but instead an empty set.
> 
> ```edgeql-repl
> db> select 1 >= <int16>{};
> {}
> ```
> 
> If one of the operands in a comparison could be an empty set, you may want to coalesce the result of the comparison with `false` to ensure your result is boolean.
> 
> ```edgeql-repl
> db> select (1 >= <int16>{}) ?? false;
> {false}
> ```


## Function: len()

```eql
std::len(value: str) -> int64
std::len(value: bytes) -> int64
std::len(value: array<anytype>) -> int64
```

Returns the number of elements of a given value.

This function works with the [`str`](https://docs.geldata.com/reference/stdlib/string.md#type::std::str), [`bytes`](https://docs.geldata.com/reference/stdlib/bytes.md#type::std::bytes) and [`array`](https://docs.geldata.com/reference/stdlib/array.md#type::std::array) types:

```edgeql-repl
db> select len('foo');
{3}

db> select len(b'bar');
{3}

db> select len([2, 5, 7]);
{3}
```


## Function: contains()

```eql
std::contains(haystack: str, needle: str) -> bool
std::contains(haystack: bytes, needle: bytes) -> bool
std::contains(haystack: array<anytype>, needle: anytype) -> bool
std::contains(haystack: range<anypoint>, needle: range<anypoint>) -> std::bool
std::contains(haystack: range<anypoint>, needle: anypoint) -> std::bool
std::contains(haystack: multirange<anypoint>, needle: multirange<anypoint>) -> std::bool
std::contains(haystack: multirange<anypoint>, needle: range<anypoint>) -> std::bool
std::contains(haystack: multirange<anypoint>, needle: anypoint) -> std::bool
```

Returns true if the given sub-value exists within the given value.

When *haystack* is a [`str`](https://docs.geldata.com/reference/stdlib/string.md#type::std::str) or a [`bytes`](https://docs.geldata.com/reference/stdlib/bytes.md#type::std::bytes) value, this function will return `true` if it contains *needle* as a subsequence within it or `false` otherwise:

```edgeql-repl
db> select contains('qwerty', 'we');
{true}

db> select contains(b'qwerty', b'42');
{false}
```

When *haystack* is an [`array`](https://docs.geldata.com/reference/stdlib/array.md#type::std::array), the function will return `true` if the array contains the element specified as *needle* or `false` otherwise:

```edgeql-repl
db> select contains([2, 5, 7, 2, 100], 2);
{true}
```

When *haystack* is a [range](https://docs.geldata.com/reference/stdlib/range.md#ref-std-range), the function will return `true` if it contains either the specified sub-range or element. The function will return `false` otherwise.

```edgeql-repl
db> select contains(range(1, 10), range(2, 5));
{true}

db> select contains(range(1, 10), range(2, 15));
{false}

db> select contains(range(1, 10), 2);
{true}

db> select contains(range(1, 10), 10);
{false}
```

When *haystack* is a [multirange](https://docs.geldata.com/reference/stdlib/range.md#ref-std-multirange), the function will return `true` if it contains either the specified multirange, sub-range or element. The function will return `false` otherwise.

```edgeql-repl
db> select contains(
...   multirange([
...     range(1, 4), range(7),
...   ]),
...   multirange([
...     range(1, 2), range(8, 10),
...   ]),
... );
{true}

db> select contains(
...   multirange([
...     range(1, 4), range(8, 10),
...   ]),
...   range(8),
... );
{false}

db> select contains(
...   multirange([
...     range(1, 4), range(8, 10),
...   ]),
...   3,
... );
{true}
```

When *haystack* is [JSON](https://docs.geldata.com/reference/stdlib/json.md#ref-std-json), the function will return `true` if the json data contains the element specified as *needle* or `false` otherwise:

```edgeql-repl
db> with haystack := to_json('{
...   "city": "Baerlon",
...   "city": "Caemlyn"
... }'),
... needle := to_json('{
...   "city": "Caemlyn"
... }'),
... select contains(haystack, needle);
{true}
```


## Function: find()

```eql
std::find(haystack: str, needle: str) -> int64
std::find(haystack: bytes, needle: bytes) -> int64
std::find(haystack: array<anytype>, needle: anytype, from_pos: int64=0) -> int64
```

Returns the index of a given sub-value in a given value.

When *haystack* is a [`str`](https://docs.geldata.com/reference/stdlib/string.md#type::std::str) or a [`bytes`](https://docs.geldata.com/reference/stdlib/bytes.md#type::std::bytes) value, the function will return the index of the first occurrence of *needle* in it.

When *haystack* is an [`array`](https://docs.geldata.com/reference/stdlib/array.md#type::std::array), this will return the index of the the first occurrence of the element passed as *needle*. For [`array`](https://docs.geldata.com/reference/stdlib/array.md#type::std::array) inputs it is also possible to provide an optional *from_pos* argument to specify the position from which to start the search.

If the *needle* is not found, return `-1`.

```edgeql-repl
db> select find('qwerty', 'we');
{1}

db> select find(b'qwerty', b'42');
{-1}

db> select find([2, 5, 7, 2, 100], 2);
{0}

db> select find([2, 5, 7, 2, 100], 2, 1);
{3}
```


