# Sets

There is no `NULL`

value in EdgeDB unlike in many other
databases or programming languages. This is deliberate,
as `NULL`

scalars create all sorts of problems when interacting with other data and operations.

Instead of the `NULL`

scalar value EdgeDB uses an empty
set `{}`

to denote the absence of data. The advantage
of using the empty set is that it works exactly like
every other set in every way. Its behavior is
well-defined and consistent across all operators and
functions.

For example, the `count`

function, which returns the number
of elements in a set, works just as well with an empty set:

The `exists`

operator returns `false`

if the set is
empty and `true`

otherwise:

Usually it is necessary to provide the type of the empty set using a cast, when the type is relevant and cannot be assumed:

In the example above, there is no context to indicate
the intended type of this empty set. EdgeQL will not
accept the input unless the empty set is given a cast
like `<int32>`

or `<int64>`

:

When an empty set is used as an element-wise operand or element-wise parameter of a function, the result is always an empty set too (albeit of whatever the return type is). This is because the Cartesian product of the empty set with anything else is still an empty set:

Because the Cartesian product of anything with an empty set is another empty set, there are some gotchas when an empty set is used where an array or tuple element are expected:

For more on Cartesian multiplication, see Chapter 11 of the Easy EdgeDB book or the Wikipedia page on Cartesian products.

Typically, if you want to splice 0 or 1 elements into an
array the `array_agg`

function and concatenation should
be used. A look at the function signature shows that it
will return an array, which does *not* have the gotcha
mentioned above with an empty set:

`std::array_agg(s: set of anytype) -> array<anytype>`

Try the following example with different values
specified for `x`

: