Tech News
← Back to articles

Effect Systems vs. Print Debugging: A Pragmatic Solution

read original related products more articles

A discussion of how the Flix type and effect system supports print-debugging.

"Every lie we tell incurs a debt to the truth. Sooner or later, that debt is paid."

— Valery Legasov (Jared Harris, Chernobyl 2019)

Lying to a type system works the same way: the truth eventually comes out. In memory-safe languages, that usually means as a runtime error (e.g. a ClassCastException , a TypeError: foo is not a function , and so on). In memory-unsafe languages, the consequences can be more dire: corrupted data, segmentation faults, or arbitrary code execution. Nevertheless, if we are in a memory-safe language, we might not feel too bad about lying to the type system...

But what happens when you lie to the effect system? Nothing good.

To understand why, let us examine how the Flix compiler uses the effect system:

Dead code elimination: Flix uses the effect system to identify expressions, statements, and let-bindings that have no side effects and whose results are unused. The compiler removes such code, improving performance and reducing binary size.

Inlining and value propagation: Flix also uses the effect system to determine which let-bindings can be safely inlined without changing program semantics. This enables constant folding and closure elimination.

Automatic parallelization: The Flix compiler, in cooperation with the Flix Standard Library, automatically parallelizes a selected set of higher-order functions when their arguments are pure, and when parallel evaluation preserves program semantics.

Separating control-pure from control-impure code: Flix uses effect tracking to distinguish code that may trigger effects and handlers from purely computational code. Control-pure code is compiled without capturing the delimited continuation, while control-impure code includes the machinery required to reify the stack.

... continue reading