Lambdragon changes the semantics for all TS/JS files in a project in a few subtle but significant ways. These changes are necessary to enable some of the most advanced features, and they also lead to more robust code.

You can probably write a complete application without knowing any of this, but it pays off to understand the differences.

Fixing the Duality of Source Files

This dual behavior is in part responsible for many of the problems that plague JS development.

In x9, this dual behavior is replaced with a singular behavior:

This behavior is partially enforced by the compiler: For example, the x9 compiler disallows non-declaration statements at the top-level of a file.

Unfortunately, it is not possible to fully automate this process.

Eliminating the duality of source files allows the x9 compiler to provide a superior development experience, better tree shaking, inline testing and playgrounds, optimization for specific build-targets (ex: lazy loading), and other advanced features. It also ultimately forces developers to write safer code and eliminates a complete category of errors and bad practices.

More importantly, this restriction doesn’t take anything away from developers. You can still write programs and scripts that reach out and change the world, you just need to wrap these in top-level declarations and execute them intentionally.

Eliminating top-level Side Effects

As a consequence of eliminating the duality of source files, x9 introduces another non-standard behavior:

all top-level declarations are assumed to be “side-effect free”

This is another deviation from JS semantics, where this restriction does not exist.

First, let’s revisit the way things work in JS

Side Effects in normal JS/TS

In regular JS, all variable declaration statements below must be assumed to be side-effectful (a, b and c) since they have a call expession as their initializer (which executes code).

const a = createA();const b = createB();const c = createC();export default function() {  a();}