Basic Features

The root of Ozark is a class. Everything outside a method is declarative, and everything inside is imperative.

Strictly speaking, Ozark is a file type definition schema paired with a language for expressing imperitive instructions within a method.

Running a program in Ozark consists of creating an instance of a class, and then calling a method on that instance. See File Structure for more details about how files are structured in Ozark.

There are no global pointers or import statements. Pointers only exist within a method or as a property of a class.

inheritance Person

property @calculator: Calculator
property @cellPhone: Telephone

extension setup & calculator: Calculator, & cellPhone: Telephone
	assign calculator to @calculator
	assign cellPhone to @cellPhone

method clockIn time: implied Time
	@timeLog addEntry time, type: .clockIn

method clockOut time: implied Time
	@timeLog addEntry time, type: .clockOut

All methods are instance methods. The object-oriented philosophy suggests that state be tightly integrated with functionality and stored within objects, and within Ozark, that's always the case.

These object-oriented constraints are uniquely valuable to Ozark. Developers who inherit legacy code in other languages often find that the underlying object-oriented structure was abandoned in certain places for convenience, maybe with a global variable or misuse of the singleton pattern. When you work on someone else's Ozark code, you won't worry about that. This is one of the ways that Ozark has been built for readability.

Ozark also avoids techniques that don't truly adhere to the principles of OO development. Static methods are one example. Another is the noticable lack of an object's ability to call its own methods.

The lack of a self reference and of unnamed code blocks forces inheritance stacks to be tall, methods to be short, and software to be built with dependency injection. This results in a lot of small, hyper-focused classes.

method swing pitch: Pitch
	pitch ball -> ball
	ball getHit probability: 0.3
property @ball: Ball?

method throw target: BaseballPlayer
	target catch @ball

	clear @ball

method catch ball: implied Ball
	assign ball to @ball
inheritance SportsPlayer

property @offense: Offense
property @defense: Defense

extension setup
	create Offense; assign to @offense; setup
	create Defense; assign to @defense; setup

method bat pitcher: Pitcher
	pitcher pitch -> pitch
	@offense swing pitch

Instructions aren't expressions

Lines of code don't have a value to be computed behind the scenes. Instead, you explicitly define all steps in the order of execution. With this constraint, it's easier to visualize complexity of a method.

inheritance GameAsset

property @scene: GameScene

extension setup
	create GameScene; assign to @scene; setup

method processScene
	@scene evaluateActions
	@scene simulatePhysics
	@scene update


Many object-oriented languages define their classes through a set of imperative statements. In Ozark, the only imperative statements you'll find are inside of a method; Everything else is written as a declaration.

inheritance Driver
property @car: RaceCar
property @race: Race

extension setup car: RaceCar
	create Race; assign to @race; setup

	assign car to @car

method race track: RaceTrack, start: StartEvent
	@race enter track
	@race start @car
	@race! start

No return types for methods, just inputs and outputs

Rather than evaluating like an expression, a method is an action by an object, and has any number of inputs and/or outputs.

Strict programming

In Ozark, declaration order, indentation, spacing and naming conventions are all important.

Ozark code looks uniform, which makes it readable. It also means that an IDE can quickly parse Ozark into a logical model.

A code-generating application can use an Ozark file as a save format, much like Adobe Photoshop uses .psd files. Even better, this saved Ozark file can be opened, read, and edited by hand, then saved and read back into the code-generating application!

Strongly typed with no casting

Ozark is a strongly-typed language. There's no typecasting, only coersion between some primitive types like Integer and Number.

inheritance Color 
method rgbValue -> rgbValue: implied Number, Number, Number
	assign 0.0, 0.0, 0.7 to rgbValue
method ! color: Color, sheet: Paper -> document: implied Paper
	color rgbValue -> rgbValue
	sheet rgbFill rgbValue
	assign sheet to document
inheritance Appliance

property @paperTray: [Paper]
property @print: Print

extension setup
	create Print; assign to @print; setup
	create [Paper]; assign to @paperTray; setup | repeat 100 times

method rgbPrint color: Color -> document: Paper?
	with @paperTray
		extract @paperTray[-1] -> sheet, assign to @paperTray
		@print! color: color, sheet: sheet -> assign to document

Small scopes with no globals

When coding in Ozark, the current working scope is always small. The only mutable pointers are either properties of a class, outputs of the current method, or deferred inputs to a dispatched method. There are no globals. Pointers only exist to store the state of an object, and to connect the inputs & outputs of methods. Think of them as values that are handed from one method call to another until they are stored safely as properties of objects.