Every problem can be solved by every programming language... in theory.
In practice, however, some languages are more suited for some tasks than others.
In my opinion a systems programming language needs to fulfill 2 needs:
1) Overhead must be tightly controllable;
2) It should not crash.
The first point is pervasive, but fairly easy to implement: never do something unless okayed by the programmer (sic). The second point means that no result is ever unexpected. All special states must allways be captured and no access or value should ever have an undesired result.
Is this doable? Possibly. In a speedy language? Probably not. Yet a lot of these problems can be caught without overhead. That is the main target of Oceans constraints model: checking without overhead. And as you cannot check without knowing what is right or wrong, you need to inform Ocean.
Tied very closely to the constraints is the principle of reflection: the ability to examine your own meta-data. This is done through aspects. Aspects are compile time information blocks which are coupled to variables. The result of an aspect query is never a variable, but most often a literal - although labels are also a possibility. Please note that as the result of an aspect query can be fundamentally different tokens, which determine how the parser works on the text, the resulting token needs to be known when the parser work, meaning that aspects need to be defined before they are used. Currently this is solved by having the compiler define all the possible aspects (tagged comments being a special case)
Visibility-control is the first step. You cannot damage things you cannot reach (in theory). Almost all 3rd generation languages have these constraints.
Change-control is the next step: certain things you can see, but you are not allowed to alter. Again this is fairly common, but not as pervasive as one could wish.
Visibility and Change control can be grouped as Access-control.
Units, more than classes, form the basis of what kind of operations are allowed: It is perfectly in order to add an integer to a float, as long as they both have the same unit. Of course the destination must also have the right unit as well as enough range to store all possible outcomes.
Validity-control is part of the process of checking if none of the computational steps results in an out-of-bounds value. This is a part which can clearly result in huge overhead. It is however extremely important not to loose data.
Relation-control makes sure that certain conditions are allways met. Some at the start of a code block (pre-conditions), some at the end (post-conditions) and others throughout (invariants). Note that all these are part of a functions 'contract'.