Option<T> types which can have either Some(value) or Nothing for values. Statically compiled languages can typecheck this so you don’t have null pointer errors.
Some languages like TypeScript have this baked into the language syntax, so you can do: let x: Foo | null = bar; and is also properly type checked.
E.g. it’s perfectly fine to say you might have an empty value via ‘Foo | null’ or ‘Foo?’ or with something like null, ‘Maybe Foo’ but to sneak it into plain old ‘Foo’ is problematic (a billion dollars worth of problems).
Option/Maybe monads are one option popular in static functional languages.
For set oriented languages, an empty set is an option. (This is very similar to the previous option, actually.)
Null is kind of a middle ground between these options and a ad hoc use of a specific sentinel value like using a signed integer variable when the data is logically unsigned, so you can use “-1” for missing data.
So I guess the better question is how do you express the idea of skipping checking for Sentinel when the language always checks for sentinel?
data Maybe a = Nothing | Just aThe only reason why you may need null is to check whether a reference is null. You remove this need by forbidding it in well defined programs.