There are a few techniques to make code more reliable:
It is a set of pre and postconditions attached to functions or types, which can be functions themselves. They might be enforced both at compile and execution time, or by external tools against the code See: ADA implementation
The programming language forces the programmer to specify types. The compiler enforces the coherency of the types. Types are connected by inheritance and composittion. Aspects can be specified via interfaces too.
Haskell excels at this.
It is a set of functions that are executed indepently of the execution
Individual units, modules or functions of the program are tested. They are specially effective for side-effect free functions and well designed code.
Domain behaviours are tested. Behaviour driven delveopment uses this as a premise as well. It uses a DSL specifically designed for the purpose of testing.
The idea is to test bigger sections of the code that follow certaing begaviours associated with the Domain.
Proving correctness of the algorithm with some mathematical framework. Formal proof is easier to do in functional languages due to their closeness to Algebra.
The quality of the code relies on the structure of it. A better structure implies less code or more robusts on most scenarios
Making the code closer to the domain means that there is less chance for implicit concepts or unexpected behaviour. Domain Driven design is a set of techniques to achieve this purpose
It involves the creation of new languages to deal with specific parts of the domain. It could be an internal or an external DSL