O

FLEXIBILITY TO ADAPT TO ANY IDEA

THE O PROGRAMMING LANGUAGE

O is a high-level object-oriented general purpose programming language. It has a familiar but expressive syntax, static typing with type inference, built-in systems for working painlessly with Dependency Injection and Plugin frameworks, user-definable statements, functions as first-class citizens, and no null by default. O is designed from the ground up to be flexible and friendly, appropriate for small personal projects through enterprise systems all the way up to huge open-source communities.

O is a work in progress. There is no complete compiler yet and the language is not ready to use. Progress is gradual but constant though. There is a functioning first prototype of a lexer, but most of the effort at the moment is coming to a formalised specification for a version 1 of the language, because only then can real progress begin to be made on the compiler itself. To stay updated on language progress, you can follow the blog.


SYNTAX

O combines a traditional C-like syntax with powerful systems like the pipeline to make writing concise and readable code simple. Simple literals for complex structures such as blocks and methods allow conveying clear meaning without piles of symbols.

import std.io ;
entrypoint hello_world ;
this() {
	// "Hello World!"
	[ "Hello" , "cruel" , "World!" ] | where ( each[0].isany( "HW" ) ) | .join( " " ) | term.prln() ;

	// using indexing into an array
	[ "Hello" , "cruel" , "World!" ][ 0 , 2 ].join( " " ) | term.prln() ;

	// calling an anonymous method literal from the pipeline
	( string s ){ term.pr( s ) ; } | { pipe( "Hello " ) ; pipe( "World!\n" ) ; } ;
}

STRUCTURE

O follows a simple code structure that allows for cleaner and more readable code. Placing a single class in each file means braces are no longer needed for containing the definition, saving a whole indent level across the entire file. It also means namespaces can be tied to the class' location in source.

import std.io ;
class dog : ipet ;

string name ;
restricted string noise ;
human owner ;

this( this.name ) {
	make_noise() ;
}

void make_noise() {
	term.prln( noise ) ;
}

NO NULL

Null is widely regarded as the "Billion Dollar Mistake". O doesn't make that mistake. Every type has a default value based on its definition, meaning null checks become a thing of the past. In the rare case null is needed, there is a special null<t> class to offer the same functionality and more.

var doggo = dog() ;
doggo.owner.name = "Susan" ; // no null error

null<dog> doge ; // defaults to a "null" value
doge.owner.name = "Susan" ; // error: cannot read property of null object

FIRST-CLASS FUNCTIONS

O treats expressions, blocks, and methods as storable types. They have accessible attributes to work with and they may be modified programmatically at run-time. This allows the use of anonymous functions to be used as method parameters rather than having to rely on lambda expressions.

// 'expression' can be invoked to declare an int x and set it to 4 in any scope
exp<int> expression = { int x = 4 } ;

// 'block' can be invoked to expand it to its value at run time or even set to be the body of a method at run time
// notice how 'expression' is invoked and 'x' is available to use
block<int> blk = { expression() ; give x ; } ;

// 'mthd' can be declared and have its body assigned later or changed at run time
int mthd() ;
mhtd.body = { return blk() ; } ;

DI AND PLUGIN FRAMEWORKS

Both Dependency Injection and Plugin frameworks play a big role in modern software development. O has built-in systems for both, meaning there is no more depending on 3rd party libraries or unintuitive use of class constructors.

import std.pluginfw ;
class grocery_shop : plugin ;
dependency ifoodsource as farm ;

this() {
	register( "Cheap Vegetables" ) ;
}

USER-DEFINABLE STATEMENTS

O has the flexibility to allow the user to define statement-style methods, allowing for much more consistent code. Any of a library of keywords may be used as parameter separators too, making method invocations easier to understand without having to consult documentation.

t[] until( exp<bool> condition , body block<t> action ) {
	while ( ! condition() ) {
		yield action() ;
	}
}

int x = 10 ;
until ( x == 0 ) {
	term.pr( x -- , "... " ) ; // "10... 9... 8... 7... 6... 5... 4... 3... 2... 1... "
}

FREE AND OPEN SOURCE

The O compiler is licensed under GPLv3, meaning anyone is free to read, understand, and learn from the code, as well as being able to modify and contribute and share those contributions with others. The O standard library is licensed under LGPLv3, meaning all the same freedoms apply, but those that wish to write non-free code are free to do so.