|dc.description.abstract||Static program analysis is a powerful technique for maintaining software, with
applications such as compiler optimizations, code refactoring, and bug finding.
Static analyzers are typically implemented in general-purpose programming
languages, such as C++ and Java; however, these analyzers are complex and
often difficult to understand and maintain. An alternate approach is to use
Datalog, a declarative language. Implementors can express analysis constraints
declaratively, which makes it easier to understand and ensure correctness of the
analysis. Furthermore, the declarative nature of the analysis allows multiple,
independent analyses to be easily combined.
Flix is a programming language for static analysis, consisting of a logic
language and a functional language. The logic language is inspired by
Datalog, but supports user-defined lattices. The functional language allows
implementors to write functions, something which is not supported in Datalog.
These two extensions, user-defined lattices and functions, allow Flix to
support analyses that cannot be expressed by Datalog, such as a constant
propagation analysis. Datalog is limited to constraints on relations, and
although it can simulate finite lattices, it cannot express lattices over an
infinite domain. Finally, another advantage of Flix is that it supports
interoperability with existing tools written in general-purpose programming
This thesis discusses the implementation of the Flix functional language,
which involves abstract syntax tree transformations, an interpreter back-end,
and a code generator back-end. The implementation must support a number of
interesting language features, such as pattern matching, first-class functions,
The thesis also evaluates the implementation, comparing the interpreter and code
generator back-ends in terms of correctness and performance. The performance
benchmarks include purely functional programs (such as an N-body simulation),
programs that involve both the logic and functional languages (such as matrix
multiplication), and a real-world static analysis (the Strong Update analysis).
Additionally, for the purely functional benchmarks, the performance of Flix
is compared to C++, Java, Scala, and Ruby.
In general, the performance of compiled Flix code is significantly faster
than interpreted Flix code. This applies to all the purely functional
benchmarks, as well as benchmarks that spend most of the time in the functional
language, rather than the logic language. Furthermore, for purely functional
code, the performance of compiled Flix is often comparable to Java and Scala.||en