Offline OS

OTIL
Login

OTIL

OTIL: The One True Implementation Language

What OTIL is

  1. Part of OfflineOS - it is designed to be tightly integrated with the other programming languages and development tools
  2. A systems programming language - OTIL is specifically designed for writing the Kernel, dynamic loader and core libraries
  3. Procedural and Old-School - The primary influences of OTIL are Pascal (syntax) and C (memory-model). Additional ideas have been gleaned from Erlang, Ruby and even Algol.
  4. Statically and Strongly typed - Any mixing of datatypes without recasting will result in a compilation error. Unless a Slice is involved.
  5. Readable - Aside from integration with the greater OfflineOS toolchain, the greatest distinction between OTIL and its inspirations is the very high "signal-to-noise-ratio" of the syntax.

What OTIL isn't

  1. An application programming language - Use MIA instead
  2. Easy - Readability is a high priority but that doesn't imply that OTIL code should be easy to write.

Concepts

Toolchain Integration

OTIL has been co-designed with MIA for multi-language development and Mac / Build for no-nonsense meta-programming.

Multi-language development

While OTIL and MIA belong to very different paradigms they share a common format for modules so that MIA applications can seamlessly call libraries written in OTIL.

Meta-programming

Like how C/C++ has the C Pre-Processor, OTIL has the Mac macro language. However unlike the C Pre-Processor Mac is not intended for a specific language. Furthermore the namespace of macros in a OTIL source file is a subset of the Build project that it belongs to.

Statements vs Expressions

A statement is one step in the program's advancing state.

An expression are either a value, function call or mathematical equation.

In OTIL expressions only act as clauses of statements.

Syntax

See here

Datatypes

See here

Best Practises

Embed error conditions in data-structures

Global variables are a common source of bugs, especially in conjunction with multi-threading / multi-processing. Instead of a global error status put an error status field into the definition of a record type.

For example:

const input <- IO.ReadLine(file);

if status of input = IO.Okay

then

IO.PrintLine(content of input);

else

IO.PrintLine("Could not read file");

end

Don't short-circuit sub-routines

A common bad habit amongst developers is hiding a return or exit statement in an if clause that does not have a corresponding else clause. This is called short-circuiting and can greatly decrease the readability of a program.

Don't use strings directly

As briefly mentioned in the documentation of the string type, it is highly recommended to wrap this type in a record type that provides additional information about it.

This is primarily because of the unreliable nature of 0-terminated strings.

Under Consideration