On the one hand, they make possible the sophisticated data and control flow analysis used by the CDL2 optimizers resulting in extremely efficient code.
However, as opposed to Prolog, control flow in CDL is deterministically based on success/failure, i.e., no other alternatives are tried when the current one succeeds.
The original version, designed by Cornelis H. A. Koster at the University of Nijmegen, which emerged in 1971, had a rather unusual concept: it had no core.
It is the responsibility of the programmer to provide the primitive operations in a form that can then be turned into machine instructions by means of an assembler or a compiler for a traditional language.
The evaluation rules are rather similar to the Backus–Naur form syntax descriptions; in fact, writing a parser for a language described in BNF is rather simple in CDL1.
It is fairly easy (albeit memory intensive) to assure the above behavior if all the data is dynamically allocated on a stack.
The CDL compiler uses your code as strings (there are conventions on how to refer to the input and output variables) and simply emits it as needed.
This lack of core primitives can be very painful when you have to write a snippet of code, even for the simplest machine instruction operation.
These were then replicated for each target architecture and OS allowing the production of highly efficient code for all.
To get a feel for the language, here is a small code fragment adapted from the CDL2 manual: The primitive operations are here defined in terms of Java (or C).
It gave up the open-ended feature of the previous CDL versions, and it provides primitives to basic arithmetic and storage access.
The extremely puritan syntax of the earlier CDL versions (the number of keywords and symbols both run in single digits) has also been relaxed.