Methods & Functions

A method is a subroutine, attached to a class, that can have any number of predefined inputs and outputs. A method is executed by passing the method name and arguments to an object. You can't call methods on primitive objects; Instead, they can be transformed with stateless functions that are built into the Ozark language.

Methods

A method declaration specifies named inputs, named outputs, and a method body. The body is made of imperative statements. All methods are public (accessible to any context that has reference to the object.)

Conductor.class.en.ozark
inheritance Musician
	
method begin concerto: Song, orchestra: Orchestra
	concerto movement 1 -> movement1
	orchestra perform movement1

	concerto movement 2 -> movement2
	orchestra perform movement1

	concerto movement 3 -> movement3
	orchestra perform movement3

method conclude concerto: Song, orchestra: Orchestra
	orchestra conclude concerto

Methods do not have a "return value" like in other object-oriented languages. Statements are not expressions to be evaluated; They are instructions to be executed, and they may or may not have any number of outputs. Separating the concept of evaluable expressions from the that of executable instructions is one of the core uniquenesses of Ozark.

An object can't call its own methods, as we believe that procedural concept doesn't belong in an object oriented langauge. See this article for a discussion of the issue.

Inputs & outputs

Methods have any number of predefined inputs and outputs. Within a method, inputs are constant, meaning they cannot have their value changed. The only mutable items are the outputs of the method, the properties of the current object, and any deferred inputs to dispatched inline method calls.

When calling a method, the created outputs are constants that cannot be changed.

Within a method signature, inputs are declared sequentially after the method name, and outputs are declared after an arrow symbol (->).

The types of the variables and collections are defined explicitly in the method signature. Inputs are both named and ordered, allowing verbose method names. A method signature can use the implied keyword to specify that the first input and/or output name should be omitted when calling.

Sailboat.class.en.ozark
inheritance Boat

property @location: Location?
property @launch: Launch
property @navigate: Navigate
property @dock: Dock

method setup
	create Launch; assign to @launch; setup
	create Navigate; assign to @navigate; setup
	create Dock; assign to @dock; setup

method sail destination: WaterfrontLocation -> duration: TimeInterval
	@launch!
	destination port -> port
	port location -> location
	@navigate! destination: location -> assign to @location, duration; assign to duration
	@dock! port: port

Properties

Ozark code operates on one small scope at a time. A method may access the properties of the instance object, and the inputs and outputs of the method itself. No other predefined values are available to it.

Conversely, using a method is the only way of accessing the properties of a given object.

Overriding & extending parent methods

As discussed in Inheritance, a class inherits all methods and properties from its parent classes. To override a method in a child class, drop the method keyword and instead declare a replacement.

To extend a parent method, declare an extension instead. This is commonly used with the setup method. The body declared for the extension will execute after the code declared in the parent method. You can choose to add additional inputs and outputs to the extension.

Outside of extensions, methods with the same name but different named parameters are considered different methods.

Flower.class.en.ozark
inheritance Plant

property @color: Color

extension setup
	create Color; assign to @color; random

To add additional input & output parameters to an extension, prefix them with the ampersand (&) symbol.

Flower.class.en.ozark
inheritance Plant

property @color: Color

extension setup -> & facing: Direction
	create Direction; assign to facing; random

Calling methods

Method calls are the building blocks of other methods. Every line inside a method body is either a method call or a control flow statement. Call a method by passing the name of the method and the arguments to the object on which the method will be called.

A method call follows a cadence of:

subject, verb, argument, value, argument, value, ...

See the Ozark Style Guide for more information.

GuitarPlayer.class.en.ozark
inheritance Musician

property @guitar: writable Guitar

method play string: GuitarString -> note: implied Note
	string play -> assign to note

Functions

Ozark includes a number of built-in, stateless functions that can operate on primitive values, collections of any type, and the memory addresses of pointers. These functions loosely represent the logic gates available to the host machine.

There are two types of functions: prefix and infix. Prefix functions have syntax like a method but with no subject. Infix functions can be chained together according to the basic mathematical order of operations to yield a single output. Some infix functions can use special tuple matching nouns like any and nil, and operate on a variable or pointer of any kind.

In functions and methods alike, primitive inputs can often receive values of other primitive types. See Primitive Types for more info.

Note that since a string is an array, all functions that operate on arrays may also operate on strings.

Key For Tables Below
[] An array
{} A tuple (note that using a single value is OK here)
When calling the methods, actual values are used in place of unnamed input types, and the function yields outputs of the unnamed types listed.

Infix Functions
Number + Number -> NumberAdd
Number - Number -> NumberSubtract
Number * Number -> NumberMultiply
Number / Number -> NumberDivide
Integer % Integer -> IntegerModulus
Number ^ Number -> NumberPower
Boolean and Boolean -> BooleanAnd
Boolean nand Boolean -> BooleanNot and
Boolean or Boolean -> BooleanOr
Boolean nor Boolean -> BooleanNor
Boolean xor Boolean -> BooleanExclusive or
Boolean xnor Boolean -> BooleanExclusive nor
Number << Integer -> NumberLeft shift
Number >> Integer -> NumberSign-propagating right shift
Number >>> Integer -> NumberZero-fill right shift
Boolean Infix Pattern Matching Functions
@Type is @TypeEquals / Object equivalence
@Type is not @TypeNot equals / Object non-equivalence
@Type in [@Type]Containment
@Type not in [@Type]Non-containment
Number > NumberGreater than
Number >= NumberGreater than or equal
Number < NumberLess than
Number <= NumberLess than or equal
Prefix Functions
flip Boolean -> Boolean
reverse [@Type] -> [@Type]
round Number -> Integer
roundUp Number -> Integer
roundDown Number -> Integer
stepTo Integer, step: Integer? -> [Integer]
join [@Type] glue: [@Type] -> [@Type]
zip array: [[@Type]] -> [[@Type]]
zip tuple: [{}] -> [{}]
split [@Type], [@Type] -> [@Type], [@Type]
extract [@Type], @Type -> [@Type], [@Type]
interpret String -> Number
interpret String -> integer: Number
serialize {} -> String
open String
close String
run String
print String