An object is an instance of a class. An object may be referenced by one or more pointers, which associate a name (such as trainConductor
or whiteRook
) with an object stored in memory. A value is like an object, but has a primitive type.
Values are stored in variables
Primitive types such as Integers and Booleans are stored in variables of their specific type, which are different from pointers. Declaring a value literal (such as 5.3
or true
) automatically allocates the necessary memory space.
Ozark uses variables as properties of objects, and as connections between the inputs and outputs of methods. Like in flow-based programming, the programmer focuses on the flow of data rather than creating temporary states. The state is nicely wrapped up in the properties of the objects themselves.
Objects are stored in pointer variables
A pointer is a variable that can contain an object, rather than a primitive value.
When a pointer is set to an object, it maintains a reference to that object. If a pointer is set to another pointer, they are both then pointing to the same object. If that object's properties change, the difference will be reflected no matter from which pointer it is referenced.
Objects are allocated manually with the create
keyword when declaring a pointer, and a method must be executed immediately using the semicolon (;
) syntax.
inheritance GameBoard property @whitePieces: [ChessPiece] property @blackPieces: [ChessPiece] method setup create [ChessPiece]; assign to @whitePieces; setup | repeat 16 times create [ChessPiece]; assign to @blackPieces; setup | repeat 16 times create ChessRules; setupBoard white: @whitePieces, black: @blackPieces method use whitePieces: [ChessPiece], blackPieces: [ChessPiece] assign whitePieces to @whitePieces assign blackPieces to @blackPieces
Optionals
Ozark uses optionals to denote inputs, outputs & properties that are allowed to nave no value. Variables marked as optional have limited capabilities, but can be unpacked for conditional usage with the with
keyword.
You can specify a property, input or output as optional by including a question mark (?
) after the type.
Generics
Classes that manage objects of a nonspecific type can be built with generics. These special types are included in the class definition. You can restrict a generic type to only classes which inherit from a given ancestor with the of
keyword.
Types are separated from the class name and from each other by parenthesis ()
inheritance Collection type @Type1 type @Type2 of Hashable property @value: @Type1 property @left: @Type1 property @right: @Type1 property @id: @Type2
inheritance Example extension setup create btree: BinaryTree(Integer); setup [1, 2, 3, 4, 5] btree! 3 -> element print element
Primitive Types
There are 5 primary built-in types that come from the Ozark standard library: Integer
, Number
, Boolean
, Character
, and the user-defined enumeration. Arrays and tuples are also value-types, even though they may contain pointers.
The built-in types aren't pointers; Instead they represent types of values that can be stored directly in a fixed-size block of memory. Each built-in type represents a novel way to interpret bits and bytes. Conversely, a pointer holds a value that represents a memory address, and can thus have properties and other things that are stored in that block based on the class definition.
Primitive values don't themselves have methods, but they can be operated on by stateless functions that are built into the Ozark language.
Primitive types don't support inheritance, but you can coerce between some primitive value types. For example, you can use an Integer
in place of a Number
, or check its Boolean
truthiness (0
evaluates to false, anything else evaluates true
.)
Notice: Built-in types behave differently than other types.
Assigning one of the 5 basic types with the assign to
phrase creates a copy of the object, rather than having the new pointer reference the same object in memory.
Also, you cannot create subclasses of the 5 built-in types.
Integer
An Integer
is a number without a fractional component, like 0
, 3
, 4
, -3
, or 10000
. Integers are entered as decimals by default, but can be specified in binary with the prefix 0b
or in hexadecimal with the prefix 0x
. 0b1101
and 0x6A43
are examples of valid Integers in binary and hexadecimal, respectively.
Number
A Number
is a floating-point number, described by the IEEE 754 standard. A floating-point number is a number with a fractional component, such as 4.14
, 0.333
, or -200.03
. By default, these appear in decimal, but are stored in binary, and are subject to common binary floating-point math characteristics. Like Integers, you can specify Number values in binary or hexadecimal using the 0b
and 0x
prefixes. 0b101101.1101
and 0x12F2.FF43
are examples of valid Numbers in binary and hexadecimal, respectively.
A floating-point number has both a stored base, and a precision. The default base for a Number is 2, but you can also specify that a Number is in base 10 using `
notation, like property @var1:Number`d
or 0.333`d
. This has much slower performance, and is only recommended for scenarios when modeling real-life decimal systems where decimal precision is important, like financial models.
You can also specify different precision for a Number using _
. The default precision is 32, but you can specify 64 and 128. property @var1: Number`d_128
, 1`10_64 / 3`10
.
Boolean
A Boolean
can only ever be true or false. Ozark provides two Boolean literals that represent the two values: true
and false
.
Character
A Character
is a single character from the Unicode character set. A Character literal is surrounded by single quotes, such as 'x'
, '3'
, '^'
, or '🙉'
.
Ozark also has a String
type, which is treated exactly as an array of Characters. To specify a string literal, surround the group of Characters with double quotes to denote a string, such as "hello"
, "1234"
, or "wonderbread!!"
.
The backslash \
character is used as an escape character within strings. You can enter a backslash escaped by simply repeating it \\
. Other control characters in a string must appear in source code in their escaped form, such as \n
(newline) or \t
(tab).
Enumeration
An enumeration is a value for which the possibilities are defined in advance. Enumerations are declared programmatically, and appear as a root-level file with the extension .enumeration.en.ozark
. Enumerations follow the same naming convention as classes, and must have names unique from other classes and enumerations declared at the same level.
Possible values for enumerations are declared with the state
keyword, must start with a .
and a lowercase letter, and are referenced with dot notation.
state .forward state .off state .reverse
inheritance Machine property @direction: Switch method start assign .forward to @direction method stop assign .off to @direction method reverse assign .reverse to @direction