The only data structures in the language are tables. So when those are stable
the whole data structure is safe. But the language is still capable of
generating an unending loop. When there should be a team of programmers it is
possible to give some of them a subset of the language where there are only
safe loops like retrieving records or the fixed 'for' loop. And in this
restricted state recursive routines are prohibited. But it is still possible
to create an unending loop by adding records to the same table within a loop
that reads records from it.
Monitor loops
So the database is still error prone and during development should
monitor every loop it starts and generate an error when a loop doesn't seem
to end. The developer can set a restriction to loops and to the maximal depth
of recursive routines. In this way routines can be stopped that turn wild.
The extra code to the program can be skipped in the final version of the
database but if people want to be on the safe side in a large project they
can keep it in place.
Maximal table length
The length of a table can also be restricted but this is an unnatural
way of working to my opinion. It is not a pleasant surprise to a programmer
to be notified of errors by users because of unforeseen growths of the
database. The restriction looks safe but is normally a harness that becomes
too tight eventually.
Forgiving code
Normally routines should be written that are resistant to false input.
It can result in an error to the user but whenever possible that should be
avoided. It is totally normal to ask for the first 3 tokens of a not existing
string. The result is also a not existing string but an error is not an issue.
Also reading from a file that doesn't exist only results in empty variables
but not in all kinds of errors. However it is always possible for a programmer
to detect that a file is not read and can write code to deal with that
situation.
Development checks
There can always be multiple versions of one module. One version is very
strict in accepting data and does a lot of checks on its integrity. The other
version is written for maximal speed. So when a stable version of a program
is finished the maximal speed version of the module can be used for better
performance and less size of the resulting object. The general way of working
should always be to have maximal checks during development and maximal speed
in production but only after the program proves to be stable.
Log warnings
The database uses a standard logging file that should be used when errors
or warnings occur. Also all kind of test data can be produced and stored here.
The data written to this file is flushed after each line so even when the
program is killed the log should contain all the relevant data. The final
version of a program should write less information to the log than a
development version, writing logs isn't normally the main function of a
program so beware of writing too much garbage to it. Garbage results in
missing that one detail in the log that is really relevant for the user or
developer.