Lo is an embryonic general-purpose programming language motivated by the observation that security, testability, and tractable concurrency all have the same solution: strict isolation between tasks communicating solely through passing messages. The project's solitary objective is to create a superb tool for software engineers in the real world – where failures happen and security matters.
Lo wasn't designed by rolling up features from existing languages but by starting with a clean slate and reimagining programming in terms of asynchronous message-passing between mutually isolated processes, then mapping the resulting constructs onto conventional syntax. Its design strives to minimize frustration by emphasizing simplicity and consistency: clear and concrete semantics embodied in a concise, intuitive, and familiar syntax.
The hope is that Lo will feel immediately comfortable to experienced developers despite some unusual semantics such as:
- Concurrency via asynchronous message-passing is a native construct; the call graph is a tree, not a stack.
- Every procedure signals explicit success or failure to its caller, independent of any return value. Procedure invocation is thus a branching construct like a conditional statement, with one branch for success and one for failure.
- Function-application expressions are not a semantic primitive but are defined in terms of procedure invocation (message sending). In other words, a procedure can optionally be invoked as a function-application expression.
- Procedures aren't intrinsically synchronous or asynchronous; any procedure can be invoked synchronously or asynchronously at the caller's discretion.
- Modules are stateless, and there are no non-local references to mutable data. All state is confined to activation records. Since modules are stateless, they can be duplicated at will by the runtime.
- Objects are isolated closure environments that cannot be directly referenced, but only accessed via facets.
- Since there's no shared state, only shared constants, each object can be its own thread.