Intuitively, a Datalog program is stratified if there is no recursion through negation, i.e. a predicate cannot depend negatively on itself. Given a Datalog program, a cycle detection algorithm can be used to determine if it is stratified. For example, the following Flix program contains an expression that cannot be stratified: def main(): #{Male(String), Husband(String), Bachelor(String)} = let p1 = Husband(x) :- Male(x), not Bachelor(x).; let p2 = Bachelor(x) :- Male(x), not Husband(x).; p1 <+> p2 // illegal, not stratified. because the last expression constructs a Datalog program value whose precedence graph contains a negative cycle: the Bachelor predicate negatively depends on the Husband predicate which in turn (positively) depends on the Bachelor predicate. The Flix compiler computes the precedence graph for every Datalog program valued expression and determines its stratification at compile-time. If an expression is not stratified, the program is rejected by the compiler. The stratification is sound, but conservative. For example, the following program is unfairly rejected: def main(): #{A(Int), B(Int)} = if (true) A(x) :- A(x), not B(x). else B(x) :- B(x), not A(x). The type system conservatively assumes that both branches of the if expression can be taken and consequently infers that there may be a negative cycle between the A and B predicates. Thus the program is rejected. This is despite the fact that at run-time the main function always returns a stratified Datalog program value. Design philosophy Flix is designed around a collection of stated principles: Everything is an expression. Most Flix constructs, except for top-level declarations, are expressions that evaluate to values. Closed-world assumption. The Flix compiler assumes that the source code of the entire program is available at compile-time. Pure and impure code is separated. The type and effect system precisely captures whether an expression may produce an effect The language has no compile-time warnings, only errors. The principles also list several programming language features that have been deliberately omitted. In particular, Flix lacks support for: Null values. Instead the use of the Option data type is recommended. Implicit coercions. Instead type conversions must be performed explicitly by the programmer. Reflection. The programmer cannot reflect over the structure of the program at run-time. References External links Official Website Flix implementation source code, hosted at GitHub. Procedural programming languages Functional languages Logic programming languages High-level programming languages