The Goat Programming Language Reference
Version: 0.5 "Overdrive".
Copyright © 2017-2020 Ivan Kniazkov. See license for copying conditions.

Table of contents
1. Introduction
Goat is a high-level, dynamic, weakly typed, prototype-based, multi-paradigm, and interpreted programming language, based mostly on JavaScript syntax. It supports the basic functionality of JavaScript, but besides, it adds support for multithreading, multiple inheritance, operator overloading (like in C ++), has simplified and expanded syntax and data model, and so on.
Why "Goat"? I was bitten by a goat. Indeed. This is how it was: really, it’s very difficult to come up with a good language name. The name should be short and memorable, for example, "Go" (but "Go" is occupied). So, one spring morning I was lying in a hammock, programming on a laptop and eating an apple. It was a wonderful day, beautiful weather, birds were singing, and then suddenly my goat bit me. "Oh, you sweet little prankster", I thought (no no, actually I said another thing). I dropped my laptop and at this time the goat stole my apple. Then I thought perhaps the name "Goat" is not bad too. So I renamed the project folder to this name and since then it has not changed.
2. Where to download the latest release
On GitHub: https://github.com/kniazkov/goat/releases/latest .
3. How to launch Goat script
3.1. Quick start
Just download the executable file, open console, type executable name and specify a script file name as a parameter:
goat.exe program.goat
For UNIX-like systems, executable name is goat , without .exe extension:
./goat program.goat
3.2. Command line options
The Goat interpreter parses command line arguments as follows. All arguments started with two hyphens are internal parameters of the interpreter ("options"). The first argument which is not an option is the name of the script file. All next arguments are send to the script.
For example,
goat.exe --lib=../lib program.goat arg1 arg2
or, the same thing:
goat.exe program.goat --lib=../lib arg1 arg2
or:
goat.exe program.goat arg1 arg2 --lib=../lib
where: goat.exe is Goat executable, program.goat is name of the script, --lib=../lib is option of the interpreter, arg1 and arg2 are arguments of the script.
Here is a short list of interpreter options. All options are described in the Appendix section.
--lib
Path (paths) to external libraries (to importable files). For example, a path to the Goat standard library. Several paths can be separated by a semicolon.
goat.exe program.goat --lib=c:\goat\lib;c:\project
Note about path delimiting character, this is most commonly the slash ("/") or the backslash ("\"). While the interpreter parsed paths, it changes delimiting characters to the character used in the current platform. Say, for Windows, all delimiter characters replaced to the backslash, and for Linux (Unix) - to slash. So path --lib=..\folder\lib interpreted as well as path --lib=../folder/lib , for all platforms.
--language= or --lang=
Set language for compiler output messages. Supported languages are:
  • english (en) - default
  • russian (ru)
Example. If the interpreter finds an error in the script, the error message will be displayed in Russian:
program.goat (contains an error "Unknown character"):
    
     println(`Hello world`);
    
Command line:
    
     ./goat program.goat --lang=ru
    
Output:

     println(`Hello world`);
             ^
     program.goat, 1.9: неизвестный символ '`'
--debug
After starting, you switch to debug mode, where you can add breakpoints and execute the program line by line. This mode is described in the Step-by-step debugging section.
Example:
goat.exe program.goat --debug
--compile
Compile the script into bytecode, but do not execute it.
Example:
goat.exe program.goat --compile
As a result, a binary file program.goat.bin will be written.
--bin
Run a previously compiled script.
Example:
goat.exe --bin program.goat.bin
Since the compilation procedure was performed earlier, loading prepared bytecode is faster. This will reduce the overall program execution time.
4. Basics
Important note. A significant part of this chapter is the redesigned tutorial from: https://www.w3schools.com/js/default.asp . Since the Goat language is the modified JavaScript language, so the description of the Goat language is the modified description of the Javascript language. Any coincidences are NOT random.
4.1. Hello world
Create a new file, say hello_world.goat (file extension does not matter) containing one line:
print("Hello, world!");
and then launch it:
goat.exe hello_world.goat
That's all. The interpreter will start the script and will print Hello, world! to the console.
4.2. Internationalization and localization
It is possible to use any Unicode characters in string literals. The Goat interpreter parses source files in UTF-8 format. The output stream also encoded to UTF-8. The previous example, but contains nonlatin characters:
print("Привет, мир!");
4.3. Program and statements
4.3.1. Program
A computer program is a list of "instructions" to be "executed" by a computer. In a programming language, these programming instructions are called statements.
A Goat program is a list of programming statements.
var x, a, b; // statement 1
a = 2; // statement 2
b = 3; // ... 3
x = a + b; // ... 4
print(x); // ... 5
Goat programs are executed by the Goat interpreter.
4.3.2. Statements
Goat statements are composed of: Values , Operators , Expressions , Keywords , and Comments .
The statements are executed, one by one, in the same order as they are written.
4.3.3. Semicolons
Semicolons ; separate Goat statements. Add a semicolon at the end of each executable statement:
var x, a, b; // declare 3 variables
a = 2; // assign the value 2 to 'a'
b = 3; // assign the value 6 to 'b'
x = a + b; // assign the sum of 'a' and 'b' to 'x'
print(x); // print value of 'x'
When separated by semicolons, multiple statements on one line are allowed:
a = 2; b = 3; x = a + b;
Though ending statements with a semicolon is not required, but highly recommended. This example is correct:
print(2 + 3) // no semicolon at the end
4.3.4. White space
Goat parse tabulations and line breaks as white spaces. Goat ignores multiple spaces. You can add white space to your script to make it more readable. The following statements are equivalent:
var a, b = 0;
var a, b=0;
var a,
     b = 0;
4.3.5. Code blocks
Goat statements can be grouped together in code blocks, inside curly brackets {...} . The purpose of code blocks is to define statements to be executed together. One place you will find statements grouped together in blocks, is in Goat functions:
var f = $(a, b)
{
     var x;
     var y;
     x = a + b;
     y = a - b;
     print("summ: " + x + ", diff: " + y);
};
4.3.6. Keywords and keyword sequences
Goat statements often start with a keyword to identify the Goat action to be performed. Here is a list of the keywords (or keyword sequences):
Keyword Description
var Declares a variable
function or $ Declares a function (method)
thread Declares a thread
lock Declares a critical section
return Exits a function (method)
if .. else if .. else Marks a block of statements to be executed, depending on a condition
switch ( case , default) Marks a block of statements to be executed, depending on different cases
for ( in ) Marks a block of statements to be executed, as long as a condition is true
while , do .. while Executes a block of statements, and repeats the block, while a condition is true
break Terminates a switch or a loop
continue Jumps out of a loop and starts at the top
try .. catch .. finally Implements error handling to a block of statements
throw Throws an exception
new Creates a new object
import Imports a source file
debug Stops the execution of Goat script, and switch the interpreter to debug (step-by-step) mode
Goat keywords are reserved words. Reserved words cannot be used as names for variables.
4.4. Syntax
Goat syntax is the set of rules, how Goat programs are constructed:
var a, b, x; // How to declare variables
a = 2; // How to assign values
b = 3;
x = a + b; // How to compute values
print(x); // How to call functions
4.4.1. Values
The Goat syntax defines two types of values: fixed values and variable values. Fixed values are called literals. Variable values are called variables.
4.4.1.1. Literals
The most important rules for writing fixed values are:
Integer numbers are written without decimals:
123
Real numbers are written with decimals, the decimal separator is a dot:
0.001
Strings are text, written within double quotes:
"Hello"
Chars are symbols written within single quotes:
'A'
4.4.1.2. Variables
In a programming language, variables are used to store data values. Goat uses the var keyword to declare variables. An equal sign is used to assign values to variables.
In this example, x is defined as a variable. Then, x is assigned (given) the value 10:
var x;
x = 10;
4.4.2. Operators
Goat uses arithmetic operators ( + - * / ) to compute values:
(5 + 6) * 10
Goat uses an assignment operator ( = ) to assign values to variables:
var a, b;
a = 2;
b = 3;
4.4.3. Expressions
An expression is a combination of literals, variables, function calls, other expression and operators, which computes to a value. The computation is called an evaluation. For example, 5 * 10 evaluates to 50:
5 * 10
Expressions can also contain variable values:
x * 2
...or function calls:
x * sin(y)
The values can be of various types, such as numbers and strings:
"Hello" + ", " + "world"
4.4.4. Identifiers
Identifiers are names.
In Goat, identifiers are used to name variables. The rules for legal names are much the same in most programming languages. In Goat, the first character must be a letter or an underscore ( _ ). Subsequent characters may be letters, digits or underscores. Numbers are not allowed as the first character.
4.4.5. Case sensitive
All Goat identifiers are case sensitive. The variables maxValue and maxvalue , are two different variables.
var maxValue, maxvalue;
maxValue = 10;
maxvalue = 0.1;
4.5. Comments
Goat comments can be used to explain Goat code, and to make it more readable. Goat comments can also be used to prevent execution when testing alternative code.
4.5.1. Single line comments
Single line comments start with // . Any text between // and the end of the line will be ignored by Goat (will not be executed). This example uses a single-line comment before each code line:
// Create object:
var obj = {};
// Add a field to the object:
obj.value = 10;
This example uses a single line comment at the end of each line to explain the code:
var x = 5; // Declare x, give it the value of 5
var y = x + 2; // Declare y, give it the value of x + 2
4.5.2. Multi-line comments
Multi-line comments start with /* and end with */ . Any text between /* and */ will be ignored by Goat. This example uses a multi-line comment (a comment block) to explain the code:
/*
The code below declares the function which calculates
and print sum and difference of two arguments
*/
var f = $(a, b)
{
     var x;
     var y;
     x = a + b;
     y = a - b;
     print("summ: " + x + ", diff: " + y);
};
4.5.3. Using comments to prevent execution
Using comments to prevent execution of code is suitable for code testing. Adding // in front of a code line changes the code lines from an executable line to a comment. This example uses // to prevent execution of one of the code lines:
var person = {};
person.name = "Ivan";
//person.gender = "Male";
person.age = 33;
This example uses a comment block to prevent execution of multiple lines:
var person = {};
person.name = "Ivan";
/*
person.gender = "Male";
person.age = 33;
*/
4.6. Variables
Goat variables are containers for storing data values. In this example, x , y , and z , are variables:
var x = 5;
var y = 6;
var z = x + y;
4.6.1. Identifiers
All Goat variables must be identified with unique names. These unique names are called identifiers. Identifiers can be short names (like x and y ) or more descriptive names ( age , sum , totalVolume ). The general rules for constructing names for variables (unique identifiers) are:
  • names can contain letters, digits and underscores;
  • names must begin with a letter;
  • names can also begin with _ ;
  • names are case sensitive ( y and Y are different variables);
  • reserved words (like Goat keywords) cannot be used as names.
4.6.2. Data types
Goat can handle many types of data. Goat variables can hold numbers like 100 and text values like "Hello". Basic data types are:
Integer number (without decimal character):
var i = 10;
Real (floating-point) number:
var r = 0.01;
String:
var s = "Hello";
Char (single symbol):
var c = 'A';
And Boolean:
var b = true;
4.6.3. Declaring (creating) Goat variables
Creating a variable in Goat is called "declaring" a variable. You declare a JavaScript variable with the var keyword:
var name;
After the declaration, the variable has no value (technically it has the value of undefined ). To assign a value to the variable, use the equal sign:
name = "Ivan";
You can also assign a value to the variable when you declare it:
var name = "Ivan";
4.6.4. One statement, many variables
You can declare many variables in one statement. Start the statement with var and separate the variables by comma:
var name = "Ivan", age = 33, gender = "male";
A declaration can span multiple lines:
var name = "Ivan",
     age = 33,
     gender = "male";
4.6.5. Undefined
Variables are often declared without a value. The value can be something that has to be calculated, or something that will be provided later, like user input. A variable declared without a value will have the value undefined .
var name; // value of 'name' is undefined
4.6.6. Re-declaring variables
If you re-declare a Goat variable, it will lose old value.
var name = "Ivan";
// do something...
var name; // now, value of 'name' if undefined
4.6.7. Arithmetic
As with algebra, you can do arithmetic with Goat variables, using operators like = and + :
var x = 5 + 2 + 3;
You can also add strings, but strings will be concatenated:
var s = "Hello" + ", " + "world!"
Also try this. The Goat language will convert second operator to string if the first operator is string:
var s = "Value is" + ' ' + 5;
4.7. Operators
4.7.1. Examples
The assignment operator ( = ) assigns a value to a variable.
var x = 10;
The addition operator ( + ) adds numbers:
var a = 2;
var b = 3;
var c = a + b;
The multiplication operator ( * ) multiplies numbers.
var a = 2;
var b = 3;
var c = a * b;
4.7.2. Arithmetic operators
Arithmetic operators are used to perform arithmetic on numbers:
Operator Description
+ Addition
- Subtraction
* Multiplication
/ Division
% Modulus (remainder)
++ Increment
-- Decrement
4.7.3. Assignment operators
Assignment operators assign values to Goat variables.
Operator Example Same as
= x = y
+= x += y x = x + y
-= x -= y x = x - y
*= x *= y x = x * y
/= x /= y x = x / y
%= x %= y x = x % y
The addition assignment operator ( += ) adds a value to a variable.
var x = 10;
x += 5;
Value of x will be: 15
4.7.4. String operators
The + and += operators can also be used to add (concatenate) strings.
var a = "Hello";
var b = "world";
var s = a + ", " + b;
Value of s will be: Hello, world!
4.7.5. Adding strings and not-strings
Adding two numbers, will return the sum, but adding a string and a not-string (number, symbol etc) will return a string:
var x = 2 + 3;
var s = "result is: " + x;
Value of s will be: result is: 5
4.7.6. Comparison operators
Operator Description
== Equal to
!= Not equal
> Greater than
< Less than
>= Greater than or equal to
<= Less than or equal to
? Ternary operator
4.7.7. Logical operators
These logical operators work only with binary ( Boolean ) type:
Operator Description
&& Logical and
|| Logical or
These logical operators work with all types:
Operator Description
! Logical not
!! Logical double not
4.7.8. Bitwise operators
Bitwise operators work with Integer type.
Operator Description Example Same as Result Decimal
& And 5 & 1 0101 & 0001 0001 1
| Or 5 | 1 0101 | 0001 0101 5
~ Not ~5 ~0101 ...111010 -6
^ Xor 5 ^ 1 0101 ^ 0001 0100 4
<< Left shift 5 << 1 0101 << 1 1010 10
>> Signed right shift 5 >> 1 0101 >> 1 0010 2
>>> Zero fill right shift 5 >>> 1 0101 >>> 1 0010 2
4.7.9. Special operators
Operator Description
-> Inherit
# Write protect
4.7.10. Common operators
Each object supports these operators: -> (inherit), # (write protect), == (equal), != (not equal) and ! (logical not).
-> (inherit)
Each object can be a prototype for a new object. Below in this document, it will be explained what is prototyping.
# (write protect)
Returns a write protected object, that is, an object whose properties can not be changed.
== (equal) and != (not equal)
In common case, an object equals to another object, if these objects are the same object. For numbers, strings, other built-in types, an object is equal to another object if these objects have the same value, for example, 5 == 2 + 3 .
! (not)
In common case, not object is false . The chapters about the comparison and conditions will describe how this is used.
!! (double not)
Double negation is used to cast any object to Boolean type.
4.8. Arithmetic
4.8.1. Arithmetic Operations
A typical arithmetic operation operates on two numbers. The two numbers can be literals:
var x = 100 + 50;
or variables:
var x = a + b;
or expressions:
var x = (100 + 50) * a;
4.8.2. Operators and operands
The numbers (in an arithmetic operation) are called operands.
The operation (to be performed between the two operands) is defined by an operator.
Operand Operator Operand
100 + 50
If at least one of the operators is a real number, the result will be a real number. If both operators are integers, the result will be an integer.
The addition operator ( + ) adds numbers.
var a = 2;
var b = 3;
var c = a + b; // 5
The subtraction operator ( - ) subtracts numbers.
var a = 2;
var b = 3;
var c = a - b; // -1
The multiplication operator ( * ) multiplies numbers.
var a = 2;
var b = 3;
var c = a * b; // 6
The division operator ( / ) divides numbers.
var a = 6;
var b = 2;
var c = a / b; // 3
If at least one of operators is a real number, the Goat interpreter performs real division (for example, 6.0 / 4 = 1.5 ). If both operators are integers, the interpreter performs integer division, i.e. the fractional part of the result will be lost ( 6 / 4 = 1 ).
The modular operator ( % ) returns the division remainder.
var a = 17;
var b = 10;
var c = a % b; // 7
The increment operator ( ++ ) increments numbers.
var a = 2;
a++; // 3
The decrement operator ( -- ) decrements numbers.
var a = 2;
a--; // 1
4.8.3. Operator precedence
Operator precedence describes the order in which operations are performed in an arithmetic expression.
var x = 100 + 50 * 3;
As in traditional mathematics, the multiplication is done first. Multiplication ( * ) and division ( / ) have higher precedence than addition ( + ) and subtraction ( - ).
The precedence can be changed by using parentheses:
var x = (100 + 50) * 3;
When using parentheses, the operations inside the parentheses are computed first.
When many operations have the same precedence (like addition and subtraction), they are computed from left to right:
var x = 100 + 50 - 3;
4.8.4. Operator precedence values
Value Operator Description Example
21 () Expression grouping (3 + 4)
20 . Member person.name
20 [] Member person["name"]
20 ?. Member with void guard person?.name
19 () Function call func()
19 new Create new StringBuilder()
18 ++ Prefix increment ++x
18 -- Prefix decrement --x
17 ++ Postfix increment x++
17 -- Postfix decrement x--
16 ! Logical not !x
16 !! Logical double not !!x
16 ~ Bitwise not ~x
15 + Unary plus +x
15 - Unary minus -x
14 -> Inherit A -> { }
13 # Write protect # { }
12 * Multiplication 10 * 5
12 / Division 10 / 5
12 % Modulo (remainder) 17 % 10
11 + Addition 2 + 3
11 - Subtraction 5 - 2
10 << Shift left x << 2
10 >> Shift right x >> 2
10 >>> Shift right (unsigned) x >>> 2
9 & Bitwise and x & y
8 ^ Bitwise xor x ^ y
7 | Bitwise or x | y
6 < Less than x < y
6 <= Less than or equal x <= y
6 > Greater than x > y
6 >= Greater than or equal x >= y
5 == Equal x == y
5 != Not equal x != y
4 && Logical and x && y
3 || Logical or x || y
2 ? Ternary operator a ? b : c
1 = Assign x = y
1 += Assign by x += y
1 -= Assign by x -= y
1 *= Assign by x *= y
1 /= Assign by x *= y
1 %= Assign by x %= y
1 <<= Assign by x <<= y
1 >>= Assign by x >>= y
1 >>>= Assign by x >>>= y
1 &= Assign by x &= y
1 ^= Assign by x ^= y
1 |= Assign by x |= y
4.9. Assignment
The = assignment operator assigns a value to a variable.
var x = 10; // 10
The += assignment operator adds a value to a variable.
var x = 10;
x += 5; // 15
The -= assignment operator subtracts a value from a variable.
var x = 10;
x -= 5; // 5
The *= assignment operator multiplies a variable.
var x = 10;
x *= 5; // 50
The /= assignment operator divides a variable.
var x = 10;
x /= 5; // 2
The %= assignment operator assigns a remainder to a variable.
var x = 17;
x %= 10; // 7
4.10. Data types
Goat variables can hold many data types: numbers, strings, objects and more:
var length = 16; // Integer
var price = 11.99; // Real
var name = "Ivan"; // String
var obj = {name: "Ivan", age: 33}; // Object
4.10.1. Concept
In programming, data types is an important concept. To be able to operate on variables, it is important to know something about the type.
For example, when adding a number and a something, the Goat interpreter will treat the second operator as a number:
var x = 2 + 3; // result is: 5
But, when adding a string and a something, the Goat interpreter will treat the second operator as a string. If the second operator is not a string, the interpreter will convert it to the string:
var s = "text" + 123; // result is: "text123"
The Goat interpreter evaluates expressions from left to right (but according to precedence). Different sequences can produce different results:
var s1 = "text" + 2 + 3; // result is: "text23"
var s2 = "text" + (2 + 3); // result is: "text5"
4.10.2. Goat types are dynamic
The Goat language has dynamic types. This means that the same variable can be used to hold different data types:
var x; // 'x' is undefined
x = 5; // now 'x' is a integer
x = "Ivan"; // now 'x' is a string
4.10.3. Strings
A string (or a text string) is a series of characters like "Abracadabra". Strings are written with double quotes:
var name="Ivan";
4.10.4. Chars
Char is a single symbol. Chars are written with single quotes:
var c = 'A';
4.10.5. Integers
A number without decimal point:
var i = 10;
4.10.6. Real numbers
A number with decimal point (also, it called "floating-point number"):
var r = 0.01;
4.10.7. Booleans
Booleans can only have two values: true or false :
var t = true;
var f = false;
Booleans are often used in conditional testing:
var x = 5;
var y = 5;
var z = 6;
var t = (x == y); // true
var f = (x == z); // false
4.10.8. Arrays
Goat arrays are written with square brackets. Array items are separated by commas. The following code declares (creates) an array called herd , containing three items (goats nicknames):
var herd = ["Dirty", "Stinky", "Crazy"];
Array indexes are zero-based, which means the first item is [0] , second is [1] , and so on.
4.10.9. Objects
Goat objects are written with curly braces. Object properties are written as name: value pairs, separated by commas.
var goat = { name: "Stinky", wool: Color.WHITE, age: 3};
4.10.10. Undefined
In the Goat language, a variable without a value, has the value undefined .
var name; // value is undefined
Any variable can be emptied, by setting the value to undefined .
name = undefined;
4.10.11. Null
In the Goat language, null is "nothing". It is supposed to be something that doesn't exist. Any variable can be emptied, by setting the value to null .
name = null;
null is not undefined ! null means: it defined, but the value of it is "nothing".
4.11. Functions
A Goat function is a block of code designed to perform a particular task. A Goat function is executed when "something" invokes it (calls it).
var myFunction = function(a, b)
{
     return a * b; // the function returns the product of 'a' and 'b'
};
Why Functions? You can reuse code: Define the code once, and use it many times. You can use the same code many times with different arguments, to produce different results.
4.11.1. Syntax
A Goat function is defined with the function keyword, followed by parentheses (). The parentheses may include parameter names separated by commas: (parameter_1, parameter_2, ...) . The code to be executed, by the function, is placed inside curly brackets: {} . To name a function (for the ability of invocation), the function object needs to be written to a variable:
var name = function(parameter_1, parameter_2, parameter_3)
{
     //code to be executed
};
In the Goat language, the function keyword (it is long and is used very often ) can be changed to a dollar sign $ :
var name = $(parameter_1, parameter_2, parameter_3)
{
     //code to be executed
};
Function parameters are listed inside the parentheses () in the function definition. Function arguments are the values received by the function when it is invoked. Inside the function, the arguments (the parameters) behave as local variables.
4.11.2. Return
When the Goat interpreter reaches a return statement , the function will stop executing, then the interpreter will "return" to execute the code after the invoking statement. Functions often compute a return value. The return value is "returned" back to the "caller":
var myFunction = function(a, b)
{
     return a * b; // the function returns the product of 'a' and 'b'
};

var x = myFunction(4, 3);
The result in x will be 12 .
4.11.3. Invocation
The () operator invokes the function.
To invoke a function without arguments, use empty operator:
var doSomething = function()
{
     //...
};

//...

doSomething();
To invoke a function with arguments, place arguments, separated by comma, inside the () operator:
var doSomething = function(a, b, c)
{
     //...
};

//...

doSomething("test", 3.14, false);
An argument can be any expression - string, number, another function call, etc.
4.11.4. Built-in functions
The Goat language has a lot of built-in functions (so-called built-in library). This library provides type definitions and functions for tasks such as string handling, mathematical computations, input/output processing and several other operating system services.
For example, the print function converts the first argument to a string and outputs it to a console:
print(2 + 3); // outputs: 5
Built-in functions are fully described in the appropriate chapter.
4.12. Objects
4.12.1. Real life objects, properties and methods
In real life, a car is an object . A car has properties like weight and color, and methods like start and stop.
Object:
var car = {};
Properties:
car.name = "Fiat";
car.model = 500;
car.weight = "850kg";
car.color = "white";
Methods:
car.start();
car.drive();
car.brake();
car.stop();
All cars have the same properties , but the property values differ from car to car.
All cars have the same methods , but the methods are performed at different times.
4.12.2. Goat objects
Recall that Goat variables are containers for data values. This code assigns a simple value ("Fiat") to a variable named car :
var car = "Fiat";
Objects are variables too. But objects can contain many values. This code assigns many values ("Fiat", 500, "white") to a variable named car:
var car = {type: "Fiat", model: 500, color:"white"};
The values are written as name:value pairs (name and value separated by a colon).
4.12.3. Properties
The name:values pairs (in Goat objects) are called properties.
var goat = { name: "Stinky", wool: Color.WHITE, age: 3 };
Property Value
name "Stinky"
wool Color.WHITE
age 3
4.12.4. Methods
Methods are actions that can be performed on objects. Methods are stored in properties as function definitions. In other words, methods are functions that are performed on an object.
var person =
{
     firstName : "Scott",
     lastName : "Cameron",
     age : 45,
    
     fullName : function()
     {
         return firstName + ' ' + lastName;
     }
};

var name = person.fullName(); // result is: "Scott Cameron"
4.12.5. Definition
You define (and create) a Goat object with an object literal:
var person = { firstName : "Scott", lastName : "Cameron", age : 45 };
Spaces and line breaks are not important. An object definition can span multiple lines:
var person =
{
     firstName : "Scott",
     lastName : "Cameron",
     age : 45
};
4.12.6. Accessing object properties
You can access object properties in two ways:
objectName.propertyName
or
objectName["propertyName"]
For example,
person.lastName
or
person["lastName"];
4.12.7. Accessing object methods
You access an object method with the following syntax:
objectName.methodName()
For example,
name = person.fullName();
4.12.8. Nested objects
Properties can be not only strings and numbers, but also arrays and objects:
var person = {
     firstName : "Scott",
     lastName : "Cameron",
     age : 45,
     children: [
         { firstName: "Ann", lastName: "Cameron", age: 10 },
         { firstName: "Dave", lastName: "Cameron", age: 14 }
     ]
};
Thus, objects can be unlimitedly nested within each other.
4.12.9. Objects, variables and references
Let's create a new object and assign it to a variable:
var a = { name: "Ivan", age: 33 };
Then, let's assign this variable to another variable:
var b = a;
Okay. Now, we try to look what the second variable contains:
print(b); // output: "{"name":"Ivan","age":33}"
Right, it contains the same that contains the first variable. Now, we change one property of the second variable:
b.name = "John";
Now let's look at the result:
print(b); // output: "{"name":"John","age":33}"
And now let's see what the first variable contains:
print(a); // output: "{"name":"John","age":33}"
Thus, we changed the property of the second variable, but the first one also changed. Why? The Goat programming language does not store whole objects in variables. The Goat programming language stores in the variables only references to objects, but not the objects themselves. If you copy one variable to another, only the reference is copied.
What can you do if you need to make a real copy of the object? Use special method clone :
var a = { name: "Ivan", age: 33 };
var b = a.clone();
b.name = "Jonh";
print(b); // output: "{"name":"John","age":33}"
print(a); // output: "{"name":"Ivan","age":33}"
4.13. Scope
Scope determines the accessibility (visibility) of variables.
Variables declared within a Goat block (function, etc), become local to this block. Local variables have local scope: they can only be accessed within the block.
// code here can not use 'nickname'

var myFunction = function()
{
     var nickname = "Stinky";
    
     // code here can use 'nickname'
};

// code here can not use 'nickname'
However, local variables can be accessed from inner blocks:
var myFunction = function()
{
     var nickname = "Stinky";
    
     //...
     if (expression)
     {
         // code here can use 'nickname'
     }
    
     // code here can use 'nickname'
};
Functions are inner blocks also. So, each function can access variables, declared outside this function:
var myFunction = function()
{
     var nickname = "Stinky";
    
     //...
     var innerFunction = function()
     {
         // code here can use 'nickname'
     };
    
     // code here can use 'nickname'
};
Variables declared within a block, redefines variables with the same names, declared outside a block. New variable uses only in this block:
var myFunction = function()
{
     var nickname = "Stinky";
     //...
     print(nickname); // output: "Stinky"
     //...
     var innerFunction = function()
     {
         var nickname = "Dirty"; // redefine 'nickname' variable
         //...
         print(nickname); // output: "Dirty"
     };
     //...
     innerFunction();
     //...
     print(nickname); // output: "Stinky"
};
4.14. Strings
Goat strings are used for storing and manipulating text.
4.14.1. Definition
A Goat string is zero or more characters written inside double quotes.
var s = "Have a nice day";
4.14.2. Special characters
Because strings must be written within quotes, Goat will misunderstand this string:
var s = "The line "No, I am your father" is often misquoted as "Luke, I am your father."";
The string will be chopped to "The line " .
The solution to avoid this problem, is to use the backslash escape character. The backslash ( \ ) escape character turns special characters into string characters:
Code Result Description
\n New line
\r Carriage return
\t Tabulation
\' ' Apostrophe (single quote)
\" " Double quote
\\ \ Backslash
The sequence \" inserts a double quote in a string:
var s = "The line \"No, I am your father\" is often misquoted as \"Luke, I am your father.\"";
The sequence \\ inserts a backslash in a string:
var s = "The character \\ is called backslash.";
4.14.3. Strings are objects
The Goat language has no primitive types. All data represented as objects, including strings. For example, another way to define string is the explicit definition (as an object) by operator new :
var s = new String("My name is Ivan");
Don't create strings using operator new. This makes no sense. This example is needed to show that in principle, the string does not differ from other objects (it has a prototype, it can be created by the new operator, and so on).
Since a string is an object, it has properties, including methods. For example, the length method returns the length of a string:
var s = "Test";
var n = s.length(); // value of 'n' will be 4
4.14.4. String methods
length ( )
Returns the length of a string.
substr ( start, count )
Extracts a part of a string and returns the extracted part in a new string.
Parameters:
  • start (Integer): the starting index (position). 0 is the first symbol
  • count (Integer): optional; count of characters. If not specified, the substring begins with the character at the specified index and extends to the end of this string. If specified, anyway, the method returns not more symbols than it possible
Example:
var a = "This is an example.";
var b = a.subString(5, 2); // "is"
var c = a.subString(11); // "example."
split ( separator )
Splits a string into an array of substrings using a separator.
Parameter:
  • separator (Char | String): a separator
Example:
var s = "My name is James Bond";
var a = s.split(' '); // ["My","name","is","James","Bond"]
encode ( encoding )
Encodes a string into an array of bytes. Returns instance of ByteArray object.
Parameter:
  • encoding (String): encoding; now only "utf8" is supported
Example:
var s = "abcd 123 Тест";
var a = s.encode("utf8"); // 61 62 63 64 20 31 32 33 20 d0 a2 d0 b5 d1 81 d1 82
trim ( )
Cuts whitespace at the beginning and end of the string. Newline markers and tabulators are whitespaces too.
valueof ( object )
Converts any object to a string.
Parameter:
  • object (any type): an object
Example:
var i = 256 * 256;
var s = String.valueof(i); // "65536"
This is the static method, i.e. meant to be relevant to all the instances of a class rather than to any specific instance.
4.14.5. String operators
Remind that each object (include strings) supports these operators: -> (inherit), == (equal), != (not equal) and ! (logical not). Other operators are:
Operators +, +=
Converts the second operand to a string and then concatenates strings.
Example:
var s0 = "hello" + ", " + "world!"; // "hello, world!";
var s1 = "test" + 123; // "test123"
var s2 = "value";
s2 += 3.14; // "value3.14"
One of the simplest methods to convert anything to a string is adding this object to an empty string:
var s = "" + 3.14; // "3.14"
Operators <, <=, >, >=
Lexicographical comparison of strings. If the second operator is not a string, returns false .
Example:
print("hello" &gt;= "hell"); // outputs: true
4.15. Characters
A character ( Char ) is a type that corresponds to a symbol or grapheme: letter, digit etc.
4.15.1. Definition
A Goat char is one character written inside single quotes.
var c = 'A';
4.15.2. Special characters
As in strings, special characters after a backslash can be used here:
Code Result Description
\n New line
\r Carriage return
\t Tabulation
\' ' Apostrophe (single quote)
\" " Double quote
\\ \ Backslash
The sequence \' means a single quote:
var c = '\'';
4.15.3. Char methods
valueof ( object )
Static method. Converts object to a char.
Parameter:
  • object (any type): an object
Example:
var i = 65;
var c = Char.valueof(i); // 'A'
If the object is an integer, returns a Char containing the character associated with the specified character code. Else, if the object is a char, just returns this object. Else, if the object is a string and this string contains only one symbol, returns this symbol. In all other cases, returns null .
4.15.4. Char operators
Operators ++, --
Increments or decrements of a Char variable (or a field) by 1.
Example:
var c = 'A'; // 'A';
c++; // 'B'
c++; // 'C'
c--; // 'B'
Operators <, <=, >, >=
Comparison of two Char objects. If the second parameter is not a char, returns false .
Example:
print('A' < 'B'); // outputs: true
4.16. Numbers
The Goat interpreter operates two type of numbers: integers and real numbers.
4.16.1. Integers
4.16.1.1. Definition
Integer numbers are written without decimal point:
var i = 3;
Also, Goat interprets numerical constants as hexadecimal if they are preceded by 0x :
var i = 0x12ab34; // lower case symbols
var j = 0x56CD78; // upper case symbols
and interprets numerical constants as binary if they are preceded by 0b :
var i = 0b1011;
4.16.1.2. Methods
string ( radix )
Converts integer to a string.
Parameter:
  • radix (Integer): optional, radix, one of: 2, 10 or 16, default 10
Example:
var i = 254;
var s = i.string(); // "254"
var h = "0x" + i.string(16); // "0xfe"
valueof ( object, radix )
Static method. Converts object to an integer.
Parameters:
  • object (any type): an object
  • radix (Integer): optional, radix, one of: 2, 10 or 16, default 10
Example:
var s = " fffe ";
var i = Integer.valueof(s, 16); // 65534
Attempts to convert a value to an integer, returns null if failed.
Object type Conversion result
Integer Returns unchanged
Real Returns the integer part of a real number
Boolean Returns 1 if true , 0 if false
Char Returns the character code as a number
String Attempts to recognize a string as a number. Ignores whitespace before and after. Returns null if failed
Other type null
4.16.1.3. Operators
The Integer type has more operators than the other types.
Operators +, +=, -, -=, *, *=, /, /=
Addition, subtraction, multiplication and division. Note that multiplication and division have a higher precedence than addition and subtraction, just as in algebra. If the second operand is a real number, then the result will also be a real number. If the second operand is an integer, the result will integer. Else if the second operand is not a number, returns false .
Example:
var a = 2;
var b = 3;
var c = 5;
var x = a + b * c; // 17
Operators %, %=
Modulo (remainder). Returns the remainder of an integer divided by an integer.
Example:
var x = 17 % 10 // 7
Operators <, <=, >, >=
Comparison of two numbers (integer or real number). If the second parameter is not a number, returns false .
Example:
print(4 > 3); // outputs: false
Operators ++, --
Increments or decrements of an Integer variable (or a field) by 1.
Example:
var x = 1; // 1;
x++; // 2
x++; // 3
x--; // 2
Operator ~
The bitwise not , or complement, is a unary operation that performs logical negation on each bit, forming the ones complement of the given binary value. Bits that are 0 become 1, and those that are 1 become 0:
Example:
var x = 0b1011;
var n = ~x; // ...1110100
The Integer is 64-bit data type, all these bits change their values. So in this example, all first bits became 1.
Operators <<, <<=
Left shift, i.e. bitwise operation that shifts all the bits of its operand. Shifts left by pushing zeros in from the right and let the leftmost bits fall off.
Example:
var x = 0b1011;
var s = x << 2; // 101100
Left shifts can be useful as an efficient way to perform multiplication of unsigned integers by powers of 2. Shifting left by n bits on unsigned binary number has the effect of multiplying it by 2 to the power of n :
var x = 5;
var s = x << 3; // 5 * 8 = 40
Operators >>, >>=
Signed right shift, shifts right by pushing copies of the leftmost bit in from the left, and let the rightmost bits fall off.
Example:
var x = -5 // ...111011;
var s = x > 1; // ...111101 (-3)
Operators >>>, >>>=
Unsigned (zero fill) right shift, one or more zero bits are pushed in from the left, and the rightmost bits fall off.
Example:
var x = 5 // 101;
var s = x >>> 1; // 010 (2)
Operators &, &=
Bitwise and returns 1 only if both bits are 1.
Example:
var x = 5 // 101;
var y = 1 // 001;
var b = x & y; // 001 (1)
Operators |, |=
Bitwise or returns 1 if one of the bits are 1.
Example:
var x = 5 // 101;
var y = 1 // 001;
var b = x | y; // 101 (5)
Operators ^, ^=
Bitwise xor (exclusive or ) returns 1 if the bits are different.
Example:
var x = 5 // 101;
var y = 1 // 001;
var b = x ^ y; // 100 (4)
4.16.2. Real numbers
4.16.2.1. Definition
Real numbers are written with the decimal point (dot):
var i = 3.14;
4.16.2.2. Methods
valueof ( object )
Static method. Converts object to a real number.
Parameter:
  • object (any type): an object
Example:
var s = " 65,535 ";
var r = Real.valueof(s); // 65.535
Attempts to convert a value to a real number, returns null if failed.
Object type Conversion result
Real Returns unchanged
Integer Returns the integer as a real number
Boolean Returns 1.0 if true , 0.0 if false
Char Returns the character code as a number
String Attempts to recognize a string as a real number. Ignores whitespace before and after. Recognizes a comma , as well as a dot . as a decimal separator. Returns null if failed
Other type null
4.16.2.3. Operators
Real type supports only these operators: + , += , - , -= , * , *= , / , /= , < , <= , > , >= , ++ , -- . Bitwise operators are not supported.
4.17. Arrays
Goat arrays are used to store multiple values in a single variable.
4.17.1. Creating an array
Using an array literal [ ] :
var array_name = [item1, item2, ...];
For example:
var herd = ["Dirty", "Stinky", "Crazy"];
Spaces and line breaks are not important. A declaration can span multiple lines:
var herd = [
     "Dirty",
     "Stinky",
     "Crazy"
];
Array elements can be objects, arrays, numbers, strings... (remind that numbers, strings etc - all are objects). Arrays are special kinds of objects. You can have functions in an array. You can have even arrays in an array.
4.17.2. Access the elements of an array
You refer to an array element by referring to the index number. [0] is the first element in an array. [1] is the second. Array indexes start with 0.
This statement accesses the value of the first element in herd array:
var name = herd[0];
This statement modifies the first element in herd array:
herd[0] = "Nasty";
4.17.3. Adding array elements
The way to add a new element to an array is using the push method:
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.push("Lemon"); // adds a new element ("Lemon") to fruits
4.17.4. The difference between arrays and objects
Arrays use numbered indexes.
Objects use named indexes.
Arrays are a special kind of objects, with numbered indexes.
4.17.5. Array methods
length ( )
Returns the length (count of items) of an array.
push ( object )
Adds a new item to the end of an array.
Parameter:
  • object (any type): an item
4.17.6. Array operators
Operator +
If the second operand is array, returns a new array that is a concatenation of two operands, i.e. contains all items from the left operand and then all items from the right operand. Otherwise, if the second operand is not an array (so it is another object), returns a new array contains all items from the left operand plus one additional item (right operand).
Example:
var a = [1,2,3];
var b = [4,5];
var x = a + b; // [1,2,3,4,5]
var y = x + 6; // [1,2,3,4,5,6]
4.17.7. Looping array elements
The best way to loop through an array, is using a for loop:
var fruits = ["Banana", "Orange", "Apple", "Mango"];
var i, count = fruits.length();
for (i = 0; i < count; i++)
{
     println(fruits[i]);
}
Output:
Banana
Orange
Apple
Mango
The same result with for..in loop:
var fruits = ["Banana", "Orange", "Apple", "Mango"];
var fruit;
for (fruit in fruits)
{
     println(fruit);
}
4.18. Booleans
A Goat Boolean represents one of two values: true or false .
4.18.1. Boolean values
Very often, in programming, you will need a data type that can only have one of two values, like
  • Yes or No
  • On or Off
  • Light Side or Dark Side
For this, The Goat programming language has a Boolean data type. It can only take the values true or false .
var t = true;
var f = false;
4.18.2. Comparisons and conditions
The chapter Comparisons gives a full overview of comparison operators.
The chapter Conditions gives a full overview of conditional statements.
Here are some examples:
Operator Description Example
== Equal to if (day == "Monday")
> Greater than if (salary > 9000)
< Less than if (age < 18)
The Boolean value of an expression is the basis for all Goat comparisons and conditions.
4.19. Comparison and logical operators
Comparison and logical operators are used to test for true or false .
4.19.1. Comparison operators
Comparison operators are used in logical statements to determine equality or difference between variables or values.
Given that x = 5 , the table below explains the comparison operators:
Operator Description Comparing Returns
== Equal to x == 8 false
x == 5 true
x == "5" false
!= Not equal x != 8 true
> Greater than x > 8 false
< Less than x < 8 true
>= Greater than or equal to x >= 8 false
<= Less than or equal to x <= 5 true
Comparison operators can be used in conditional statements to compare values and take action depending on the result:
if (age < 18) print("Too young");
4.19.2. Logical operators
Logical operators are used to determine the logic between variables or values.
Given that x = 6 and y = 3 , the table below explains the logical operators:
Operator Description Example Returns
&& Logical and (x < 10 && y > 1) true
|| Logical or (x == 5 || y == 5) false
! Logical not !(x == y) true
Logical and (&&)
The expression A && B is true if A and B are both true ; else it is false .
Logical or (||)
The expression A || B is true if A or B (or both) are true ; if both are false , the expression is false .
Logical not (!)
The expression !A is true if A is false .
4.19.3. Conditional (ternary) operator
Goat also contains a conditional operator that assigns a value to a variable based on some condition:
variablename = (condition) ? value1 : value2
For example,
var voteable = (age < 18) ? "Too young" : "Old enough";
If the variable age is a value below 18, the value of the variable voteable will be "Too young" , otherwise the value of voteable will be "Old enough" .
4.19.4. Comparing different types
Comparing data of different types may give unexpected results. As a rule, the operators == and != check that the types of the two variables match, otherwise will be returned default value ( false in case of == ). For example, you can compare numbers but you can not compare a number and a string. If you need to compare, just explicit convert an operand to another type to match the second operand:
var s = "1024"; // String
var i = 256 * 4; // Integer
if (String.valueof(i) == s)
{
     // do something
}
There is one exclusion. You can compare integer numbers and real numbers although they are different types. An integer operand will be converted to a real before comparison.
If you really not sure that operands have the same type, but you extremely need to compare it, cast both operands to the same type:
var s = "1024";
var i = 256 * 4;
if (Real.valueof(i) == Real.valueOf(s)) // convert both to Real
{
     // do something
}
4.20. Conditions
4.20.1. Conditional statements
Conditional statements are used to perform different actions based on different conditions.
Very often when you write code, you want to perform different actions for different decisions. You can use conditional statements in your code to do this. In Goat we have the following conditional statements:
  • Use if to specify a block of code to be executed, if a specified condition is true
  • Use else to specify a block of code to be executed, if the same condition is false
  • Use else if to specify a new condition to test, if the first condition is false
  • Use switch to specify many alternative blocks of code to be executed
4.20.2. The 'if' statement
Use the if statement to specify a block of Goat code to be executed if a condition is true. Syntax:
if (condition)
{
     block of code to be executed if the condition is true
}
Example (outputs "Okay" ):
var testscore = 70;
//...
if (testscore > 60)
{
     print("Okay");
}
Note that if is in lowercase letters. Uppercase letters ( If or IF ) will generate a Goat error.
4.20.3. The 'else' statement
Use the else statement to specify a block of code to be executed if the condition is false. Syntax:
if (condition)
{
     block of code to be executed if the condition is true
}
else
{
     block of code to be executed if the condition is false
}
Example (outputs "Excellent result" ):
var testscore = 95;
//...
if (testscore < 90)
{
     print("Okay");
}
else
{
     print("Excellent result");
}
4.20.4. The 'else if' statement
Use the else if statement to specify a new condition if the first condition is false. Syntax:
if (condition1)
{
     block of code to be executed if condition1 is true
}
else if (condition2)
{
     block of code to be executed if the condition1 is false and condition2 is true
}
else
{
     block of code to be executed if the condition1 is false and condition2 is false
}
Example:
if (testscore < 50)
{
     print("Bad result");
}
else if (testscore < 90)
{
     print("Okay");
}
else
{
     print("Excellent result");
}
4.20.5. Single statements instead of blocks
If a block contains only one statement, you can use this statement without parentheses. The previous example, but with single statements instead of blocks:
if (testscore < 50)
     print("Bad result");
else if (testscore < 90)
     print("Okay");
else
     print("Excellent result");
It's a little shorter, isn't it? You can even write the whole 'if' statement to one line:
if (obj == null) return;
It's the same to:
if (obj == null)
     return;
Or
if (obj == null)
{
     return;
}
Of course, the same rules apply to other constructions described below.
4.21. Switch statement
The switch statement is used to perform different actions based on different conditions. Use the switch statement to select one of many blocks of code to be executed.
4.21.1. Syntax
switch(expression)
{
     case n:
         code block
         break;
     case n:
         code block
         break;
     default:
         code block
}
This is how it works:
  • The switch expression is evaluated once.
  • The value of the expression is compared with the values of each case.
  • If there is a match, the associated block of code is executed.
Example. This function converts weekday (as a number between 0 and 6) to a string:
var weekday = function(number)
{
     var day;
     switch (number)
     {
         case 0:
             day = "Sunday";
             break;
         case 1:
             day = "Monday";
             break;
         case 2:
             day = "Tuesday";
             break;
         case 3:
             day = "Wednesday";
             break;
         case 4:
             day = "Thursday";
             break;
         case 5:
             day = "Friday";
             break;
         case 6:
             day = "Saturday";
     }
     return day;
};
4.21.2. The 'break' keyword
When Goat reaches a break keyword, it breaks out of the switch block. This will stop the execution of more code and case testing inside the block. When a match is found, and the job is done, it's time for a break. There is no need for more testing.
It is not necessary to break the last case in a switch block. The block breaks (ends) there anyway.
4.21.3. The 'default' keyword
The default keyword specifies the code to run if there is no case match.
Example. This function converts weekday (as a number between 0 and 6) to a string, but if a weekday is neither Saturday (6) nor Sunday (0), returns a default message:
var weekday = function(number)
{
     var day;
     switch (number)
     {
         case 0:
             day = "Sunday";
             break;
         case 6:
             day = "Saturday";
             break;
         default:
             day = "Working day";
     }
     return day;
};
The default case (if exists) does not necessarily have to be the last one. However, it will always be executed only if all other conditions have not been executed. This block is recommended to be the last block for good visibility.
4.21.4. Common code blocks
Sometimes you will want different switch cases to use the same code:
var weekday = function(number)
{
     var day;
     switch (number)
     {
         case 0:
             day = "Sunday";
             break;
         case 6:
             day = "Saturday";
             break;
         case 4:
         case 5:
             day = "Soon it is Weekend";
             break;
         default:
             day = "Working day";
     }
     return day;
};
4.22. Loops
4.22.1. What are loops
Loops can execute a block of code a number of times.
Loops are handy, if you want to run the same code over and over again, each time with a different value. Often this is the case when working with arrays.
For example, we have an array:
var herd = ["Dirty", "Stinky", "Crazy", "Nasty", "Dumb", "Dumber"];
Instead of writing:
print(herd[0] + "\n");
print(herd[1] + "\n");
print(herd[2] + "\n");
print(herd[3] + "\n");
print(herd[4] + "\n");
print(herd[5] + "\n");
You can write:
var i, l = herd.length();
for (i = 0; i < l; i++)
{
     println(herd[i]);
}
4.22.2. Different kinds of loops
Goat supports different kinds of loops:
  • for - loops through a block of code a number of times;
  • for..in - loops through the properties of an object or through all items of an array;
  • while - loops through a block of code while a specified condition is true;
  • do..while - also loops through a block of code while a specified condition is true.
4.22.3. The 'for' loop
The for loop is often the tool you will use when you want to create a loop. The for loop has the following syntax:
for (statement 1; statement 2; statement 3)
{
     code block to be executed
}
Statement 1 is executed before the loop (the code block) starts.
Statement 2 defines the condition for running the loop (the code block).
Statement 3 is executed each time after the loop (the code block) has been executed.
Example (outputs "0123456789" ):
var i;
for (i = 0; i < 10; i++)
{
     print(i);
}
From the example above, you can read:
Statement 1 sets a variable before the loop starts ( i = 0 ).
Statement 2 defines the condition for the loop to run ( i must be less than 10).
Statement 3 increases a value ( i++ ) each time the code block in the loop has been executed.
4.22.3.1. Statement 1
Normally you will use statement 1 to initialize the variable used in the loop ( i = 0 ). This is not always the case, Goat doesn't care. Statement 1 is optional. You can omit statement 1 (like when your values are set before the loop starts):
var i = 0;
for (; i < 10; i++)
{
     print(i);
}
Also, you can declare a variable in statement 1 using var keyword:
for (var i = 0; i < 10; i++)
{
     print(i);
}
This variable will be visible only inside the 'for' loop.
4.22.3.2. Statement 2
Often statement 2 is used to evaluate the condition of the initial variable. This is not always the case, Goat doesn't care. Statement 2 is also optional. If statement 2 returns true , the loop will start over again, if it returns false , the loop will end.
If you omit statement 2, you must provide a break or a return inside the loop. Otherwise, the loop will never end.
4.22.3.3. Statement 3
Often statement 3 increments the value of the initial variable. This is not always the case, Goat doesn't care, and statement 3 is optional. Statement 3 can do anything like negative increment ( i-- ), positive increment ( i = i + 15 ), or anything else. Statement 3 can also be omitted (like when you increment your values inside the loop):
for (i = 0; i < 10; )
{
     print(i);
     i++;
}
4.22.4. The 'for..in' loop
The Goat for..in statement loops through the properties of an object:
var person = {name: "Ivan", age: 33, gender: "male"};
var x;
for (x in person)
{
     if (person.contains(x))
         println(x + ": " + person[x]);
}
Output:
name: Ivan
age: 33
gender: male
Some notes. First, objects store unordered pairs key:value . The order of traversal of object properties may not match with the order of the properties at object creation. In the example above, the output can be:
age: 33
name: Ivan
gender: male
Second, you must have noticed that this is an additional contains method call. Why? In fact, any object contains references to additional auxiliary methods, so without calling contains method, the output will be similar to something like:
gender: male
age: 33
name: Ivan
clone: function
instanceof: function
flat: function
get: function
set: function
iterator: function
...
The contains method returns true if object itself contains property with given name. So, we can exclude all auxiliary properties (methods and fields).
The Goat for..in statement can also loop through all items of an array:
var herd = ["Dirty", "Stinky", "Crazy", "Nasty", "Dumb", "Dumber"];
var goat;
for (goat in herd)
{
     println(goat);
}
4.22.5. The 'while' loop
The while loop loops through a block of code as long as a specified condition is true . Syntax:
while (condition)
{
     code block to be executed
}
Example (outputs "0123456789" ):
var i = 0;
while (i < 10)
{
     print(i);
     i++;
}
Note: if you forget to increase the variable used in the condition, the loop will never end.
4.22.6. The 'do..while' loop
The do..while loop is a variant of the while loop. This loop will execute the code block once, before checking if the condition is true , then it will repeat the loop as long as the condition is true . Syntax:
do
{
     code block to be executed
}
while (condition);
Example. The loop will always be executed at least once, even if the condition is false , because the code block is executed before the condition is tested:
var i = 0;
do
{
     print(i);
     i++;
} while (i < 10);
4.22.7. The 'break' statement
You have already seen the break statement used in an earlier chapter of this tutorial. It was used to "jump out" of a switch statement. The break statement can also be used to "jump out" of a loop. The break statement breaks the loop and continues executing the code after the loop (if any):
var i;
for (i = 0; i < 10; i++)
{
     if (i == 6)
         break;
     print(i);
}
Output: 012345 .
4.22.8. The 'continue' statement
The continue statement breaks one iteration (in the loop), if a specified condition occurs, and continues with the next iteration in the loop.
This example skips the value of 3:
var i;
for (i = 0; i < 10; i++)
{
     if (i == 3)
         continue;
     print(i);
}
Output: 012456789 .
4.23. Exceptions
4.23.1. Errors will happen!
When executing Goat code, different errors can occur. For example, division by zero:
print(1 / 0); // oops
The try statement lets you test a block of code for errors.
The catch statement lets you handle the error.
The throw statement lets you create custom errors.
The finally statement lets you execute code, after try and catch, regardless of the result.
4.23.2. Try and catch
The try statement allows you to define a block of code to be tested for errors while it is being executed.
The catch statement allows you to define a block of code to be executed, if an error occurs in the try block.
The Goat statements try and catch come in pairs:
try
{
     Block of code to try
}
catch(err)
{
     Block of code to handle errors
}
Example:
try
{
     print(4 / 4);
     print(4 / 2);
     print(4 / 1);
     print(4 / 0);
}
catch(err)
{
     print("Error");
}
Output:
124Error
When an error occurs, Goat will normally stop and generate an error object. The technical term for this is: Goat will throw an exception (throw an error).
4.23.3. The 'throw' statement
The throw statement allows you to create a custom error.
Technically you can throw an exception (throw an error). The exception can be any object:
throw "Oops!"; // throw a string
The thrown object passes as a parameter of the catch statement.
If you use throw together with try and catch , you can control program flow and generate custom error messages.
var kelvin2Celsius = function(value)
{
     if (value < 0)
         throw "Wrong parameter: " + value;
    
     return value - 273.15;
};

try
{
     print("\n" + kelvin2Celsius(300));
     print("\n" + kelvin2Celsius(0));
     print("\n" + kelvin2Celsius(-10));
}
catch(err)
{
     print("\n" + err);
}
Output:
26.85
-273.15
Wrong parameter: -10
4.23.4. The 'finally' statement
The finally statement lets you execute code, after try and catch, regardless of the result:
try
{
     Block of code to try
}
catch(err)
{
     Block of code to handle errors
}
finally
{
     Block of code to be executed regardless of the try / catch result
}
4.23.5. The error object
The exception can be any object. For some situations, the interpreter throws predefined exception objects, such as:
Exception Situation
Exception Common type for all exceptions
Exception.IllegalArgument Illegal argument of a function or an operator
Exception.IllegalContext Incorrect execution context, usually this occurs if you try to apply the methods of one object to another object
Exception.IllegalOperation This operation cannot be executed
Exception.IllegalOperation.DivisionByZero Division by zero, print(1 / 0);
Exception.IllegalOperation.UndeclaredVariable Attempt to assign a value to an undeclared variable
Exception.IllegalReference Attempt to write or read a non-existent object ( undefined or null )
Exception.IllegalType Object has a type that was not expected
Exception.IllegalType.IsNotAFunction Attempt to call an object as a function (but it is not a function)
Exception.IllegalType.IsNotAMethod Attempt to call an object as a method (but it is not a method)
Exception.IllegalType.OperatorNotFound This operator does not apply to the object, print("abc" - "def");
Each object (include error objects) has the instanceof method. You can use this method to determine the type of exception:
try
{
     // do something
}
catch(err)
{
     if (err.instanceof(Exception.IllegalOperation))
     {
         // do domething if operation is illegal
     }
}
4.24. Import
4.24.1. Overview
Sometimes the program becomes so large that it is more reasonable to separate it into several files. In addition, you can use pre-designed libraries - say, to recognize XML files. Goat provides a way to include files to a program using an import keyword.
import "xml.goat";

// now, you can use functions from XML library:
var root = Xml.parse("<root></root>");
No file will be imported twice. For example, your program uses library A and library B . But library B uses (imports) library A too. So, library A will be imported only once, for the whole project.
Where the interpreter finds files to import?
  • first, in the current folder, where was started Goat script;
  • second, in the list of folders specified in the --lib option of the interpreter.
4.24.2. --lib option
Path (paths) to importable files. For example, folder c:\goat\lib contains Goat standard library; so, to use it, launch the interpreter with --lib option:
goat.exe program.goat --lib=c:\goat\lib
Several paths can be separated by a semicolon. The interpreter for each imported file first searches the first path in the list, then the second one, and so on.
4.25. Debugging
4.25.1. Interactive mode
Goat has two basic modes: script and interactive. The script mode is the mode where the script files are run in the Goat interpreter. Interactive mode is a command line shell that gives immediate feedback for each statement while running in shared memory. As new lines are fed into the interpreter, each new line is executed.
To start interactive mode, launch the Goat interpreter without script file (in common cases without any parameters):
goat.exe
Will open a console:
Ok.
>
Enter any correct statement and press Enter:
> var i = 0;

>
In the example above, the interpreter will create a variable i and wait for the new statement to be entered. So, now you can print the value of the variable:
> print(i);
0
>
You can use any statements you want:
> for (var k = 0; k < 10; k++) print(k);
0123456789
>
If statement takes more than one line, add a backslash to go a new line:
> for (var k = 0; k < 10; k++) \
{ \
     if (k == 3) continue; \
     print(k); \
}
012456789
>
The values of all variables are saved:
> var obj = {};

> obj.field = 1;

> print(obj);
{field:1};
>
To print the value of an expression, add a question mark before the expression:
> ? 2 + 3
5
>
Any expressions are applicable:
> ? "test".instanceof(String)
true
>
The special statement quit (or q ) exits interactive mode.
quit
4.25.2. Step-by-step debugging
4.25.2.1. The '--debug' command line parameter
If to add this parameter to the command line, the interpreter will be started in step-by-step mode. The program will be compiled, but will not be run. Will open a console instead:
C:\>goat.exe program.goat --debug
?
4.25.2.2. Commands in debugging mode
The interpreter is waiting for the command to be entered after the question mark. A command is one letter and possibly some auxiliary parameters, for example:
? b program.goat : 1
setting breakpoint at program.goat, 1
?
After the question mark in square brackets, the default command can be displayed. It will be executed if do not enter any command (that is, just press Enter). Most of all cases, this is the previous command:
? [c]
Additional information can be displayed before prompt, such as the current line being executed.
40 -> program.goat, 4.5
var j = i * i
? [n]
Where,
ticks -> filename, position
statement
? [cmd]
  • ticks - count of ticks (instructions) executed by the Goat virtual machine;
  • filename - current file name;
  • position - current position (line and symbol in this line);
  • statement - statement that will be executed;
  • cmd - default command.
Here is list of commands:
Command Mnemonic Example Description
b filename : line breakpoint b program.goat : 10 Inserts a breakpoint . The program will stop on position, specified by this command
r run Runs the program. This command can be done only once in a debugging session
c continue Continue executing of the program. This command can be entered only if the program is was run
n next Execute the next statement and then stop (wait for next command)
e enter Execute the next statement, but, if it is a function call, enter to function and then stop on the first statement
l leave Leave current function, i.e. execute all statements, and stop on the next statement after the function call
p variable print p obj.value Prints the value of the variable
4.25.2.3. The 'debug' keyword
The debug keyword stops the execution of Goat, and switch the interpreter to step-by-step mode. It like breakpoint, but in program source code. In other words, it is "constant breakpoint". If no debugging is available, the debug statement has no effect.
Example, square_numbers.goat :
var i, j;
for (i = 0; i < 10; i++)
{
     debug;
     j = i * i;
     println(j);
}
Then launch the interpreter with --debug option:
goat.exe square_numbers.goat --debug
The program will start and then stop on debug keyword:
> square_numbers.goat, 3.4: debug;
[c] ?
5. Advanced programming
Forget everything you learned in school.
5.1. The new look at objects
5.1.1. Keys and values
Objects are containers for pairs key:value :
var person = { firstName : "Scott", lastName : "Cameron", age : 45 };
The key:value pairs (in Goat objects) are called properties.
Values can be any objects: strings, numbers etc. What about keys? In the example above, keys are identifiers (such as names of variables).In common cases, using identifiers as keys is enough: it is convenient. You always can add a new property using the dot operator . :
person.profession = "Programmer";
But, keys can be not only identifiers. You can use any object as a key. For example, integers:
person[3] = "value";
...or booleans:
person[true] = false;
...and, of course, strings:
person["profession"] = "Programmer";
If you use a string as a key, and this string can be an identifier (the first character must be a letter or an underscore ( _ ), subsequent characters may be letters, digits or underscores), Goat transforms this string to an identifier. Later you can access to this field using identifier:
person["weight"] = 80;
//...
print(person.weight); // output: "80"
And vice versa, any property declared using an identifier, can be accessed using a string:
person.weight = 80;
//...
print(person["weight"]); // output: "80"
So, objects are containers for pairs key:value , where the key can be an identifier or any object, and the value can be any object. However, the Goat program works a little faster if you use identifiers as keys, so this is the preferred method.
5.1.2. Everything is an object
All data (strings, numbers, booleans) represented as objects. These are "special" objects that have special behavior. But beyond this, these objects do everything the same as other, "ordinary" objects.
For example, you can add a property for a string:
var str = "hello!";
str.somePropertyName = 123;
5.2. Methods
5.2.1. Difference between method and function
A method in object-oriented programming is a function associated with an object.
In other words, functions work only with parameters, but methods also "see" all the properties (fields and other methods) of their own object and can modify these.
Example. Declare an object obj that contains one field x and one method getX . The method has access to the field:
var obj =
{
     x: 10;
    
     getX : $()
     {
         return x;
     }
};

var n = obj.getX(); // 10
A method call is differs from a function call by writing a point after an associated object whose method is called:
// function call:
ret_val = function_name(arg_1, arg_2, arg_3);

// method call:
ret_val = object.method_name(arg_1, arg_2, arg_3);
5.2.2. Search order
Since a property (or variable) with the same name can be defined in many places, the programming language specifies a clear order of searching for the value by name.
Suppose we want to read a variable named x . The highest priority has local variables:
var obj =
{
     x: 10; // property 'x'
    
     getX : $()
     {
         var x = 2 + 3; // local variable 'x'
         return x;
     }
};

var n = obj.getX(); // 5
If a local variable with this name is not found, the Goat programming language tries to find this name in the list of arguments of the method:
var obj =
{
     x: 10; // property 'x'
    
     getX : $(x) // method with argument named 'x'
     {
         return x;
     }
};

var n = obj.getX(7); // 7
Then the search is performed in the object properties:
var x = 777; // external variable 'x'

var obj = {
     x: 10; // property 'x'
    
     getX : $()
     {
         return x;
     }
};

var n = obj.getX(); // 10
The last thing to do is look for variables outside the object:
var x = 777; // external variable 'x'

var obj =
{
     getX : $()
     {
         return x;
     }
};

var n = obj.getX(); // 777
5.2.3. The 'this' keyword
When a method is called, a special variable named this is always defined. This variable refers to the object whose method was called. You can not overwrite the value of this variable. This variable is used to explicitly access the properties of the "own" object.
var obj =
{
     x: 10; // property 'x'
    
     getX : $()
     {
         return this.x;
     }
};

var n = obj.getX(); // 10
In fact, the example above is completely analogous to this example:
var obj = {
     x: 10; // property 'x'
    
     getX : $()
     {
         return x; // without 'this' keyword
     }
};

var n = obj.getX(); // 10
That is, in most cases, we can do without using this keyword. But in some cases, this keyword cannot be avoided. For example, if you already have a local variable or an argument with that name, but you want to explicit read or write the property of the object:
var obj = {
     x: 10; // property 'x'
    
     getX : $()
     {
         return x;
     }
    
     setX " $(x)
     {
         this.x = x; // read the argument 'x' and write the property 'x'
     }
};

obj.setX(777);
var n = obj.getX(); // 777
Or, you can add new properties to own object (which are not yet there):
var obj =
{
     x: 10; // property 'x'
    
     init : $() // constructor
     {
         this.y = 20; // add a new property 'y'
     }
};
5.2.4. Changing the context
Summing up the above, it can be said that the function differs from the method only by the process of calling. Any method can be "transformed" to a function:
// an object that contains a method:
var obj =
{
     doSomething : $()
     {
         println("hello!");
     }
};

var func = obj.doSomething; // copying the property pointed to the method to a variable
func(); // function call, prints: "hello!"
However, in this case, the context is changed: the reference to this became undefined :
// an object that contains a method and a value:
var obj =
{
     value : 3,
    
     doSomething : $()
     {
         println(this?.value);
     }
};

// do call as a method
obj.doSomething();

// do call as a function
var func = obj.doSomething;
func();
Output:
3
undefined
In some cases, when the context is not important, a method is named a "static method". In other cases, calling a method as a function will throw an IllegalContext exception.
If needed, we can change the context of a method called, i.e. replace this to "another this ". There are two methods: call and apply .
call ( thisArg, arg1, arg2, ... )
Calls a function with a given this value and arguments provided individually.
Parameters:
  • thisArg (any type): A new context
  • arg1 (any type): First argument
  • arg2, ... (any type): other arguments
Example:
// an object that contains a method and a value:
var obj =
{
     value : 3,
    
     doSomething : $(x, y)
     {
         println(this?.value);
         println(x);
         println(y);
     }
};

// do call as a method
obj.doSomething(7, "test");

// do call as a method with another context
var context =
{
     value : 555
};

var func = obj.doSomething;
func.call(context, 7, "test");
Output:
3
7
test
555
7
test
apply ( thisArg, argsArray )
Calls a function with a given this value and arguments provided as an array.
Parameters:
  • thisArg (any type): A new context
  • argsArray (Array): An array object, specifying the arguments
Example:
// the previous example, but the 'apply' method is used:
func.apply(context, [7, "test"]);
5.3. Prototypes
5.3.1. Prototype and inheritance
Goat is prototype-oriented language. What is "prototype" means?
A prototype is an object from which other objects inherit properties and methods. Any object can be a prototype for another object.
Inheritance is when an object is based on another object.
How does it work? When accessing an object (method call or field reading), the Goat programming language first looks for this property in the object itself. If Goat does not find it, it tries to look for this property in the prototype object. If still not found, then Goat is searching in a prototype of the prototype, and so on. Consider an example of simple inheritance:

Fig. 1. Simple inheritance

// declare an object:
var parent = { x: 1 };

// inherit another object:
var child = parent -> { y: 2, z: 3 };

// now you have access to properties in the parent object:
println(child.x); // output: "1"
Here, the child is the heir to the parent . Access of any parent's property by name has no different from that of the child's property. And it can be said that a child has the same properties as a parent. However, the child itself does not copy these properties, it only refers to them.
Inheritance nesting is not limited, any object can have a prototype, and a prototype can have its pro-prototype, and so on:

Fig. 2. Inheritance nesting

// declare an object:
var grandpa = { a: 1, b: 2 };

// inherit another object:
var dad = grandpa -> { x: 3 };

// inherit from heir:
var son = dad -> { y: 4, z: 5 };

// now you have access to properties of the pro-prototype:
println(son.a); // output: "1"

// and to properties of the prototype:
println(son.x); // output: "3"

// as well as to object's own properties:
println(son.z); // output: "5"
5.3.2. Operator ->
Operator -> builds a new object from the prototype and description:
var obj = prototype -> description;
A prototype is an object from which properties (fields and methods) will be used if properties with such names are not found in the child object.
A description is an object that will be cloned before a prototype is attached to it. The description thus extends the prototype, and as a result, a new object is created that contains both its own properties and the properties of all its parents.
Example:
// declare an object:
var A = { x: 1 };

// inherit:
var B = A -> { y: 2, z: 3 }; // 'B' contains 'x', 'y' and 'z'
Of course, you can declare a description elsewhere:
// declare an object:
var A = { x: 1 };

// declare a description:
var D = { y: 2, z: 3 };

// inherit:
var B = A -> D; // 'B' still contains 'x', 'y' and 'z'
5.3.3. Order of searching in a prototype chain
If you created a new object using an operator -> , then this object, in turn, can also be a prototype of some other object:
// declare an object:
var A = { x: 1 };

// inherit first time:
var B = A -> { y: 2 }; // 'B' contains 'x' and 'y'

// inherit second time:
var C = B -> { z: 3 }; // 'C' contains 'x', 'y' and 'z'
The Goat programming language looks for the property by its name along the whole prototype chain, from the last to the first prototype. For example,
print(C.x);
The order of search is:
  • first, a property named x will be searched in the C object and will not be found;
  • second, a property will be searched in the B object and will not be found;
  • finally, a property will be searched in the A object and will be found.
Another example, attempt to read an undefined property:
print(C.w);
In this case, the Goat programming language will scan the whole prototype chain (first C , then B , then A ), but will not find the properties and return undefined result.
5.3.4. Changing the prototype
You can not change the prototype of the object. Instead, you can change some properties of the prototype itself. In this case, these properties will immediately change in all children:
// declare an object:
var A = { x: 1 };

// inherit:
var B = A -> { y: 2, z: 3 };

// read the value of 'x' property (of the child object):
print(B.x); // output: "1"

// change the value of 'x' property (in the parent object):
A.x = 777;

// read the value of 'x' property again:
print(B.x); // output: "777"
5.3.5. The 'new' operator
The new operator creates a new object from the prototype and then calls a special method - constructor to initialize the object.
// declare the class:
var Vector =
{
     x : 0,
     y : 0
};

// create the object using the 'new' operator
var v = new Vector();
In the simplest case, as in the example above, this operation is completely analogous to the inheritance from the prototype:
var v = Vector -> { };
But, in addition to inheritance, the new operator calls a chain of constructors.
5.3.5.1. Constructor
A constructor is a method named init .
// declare the class:
var Vector =
{
     init : $()
     {
         this.x = 0;
         this.y = 0;
     }
};

// create the object using the 'new' operator
var v = new Vector();
Output:
{x:0,y:0}
Note that in the first example (without the constructor), the x and y variables are not owned by the new object, but by the prototype. In the new example, the variables are created each time the object is created by the new operator, and these variables are owned by the object.
Where can this be useful? This is necessary in cases where each object must have its own independent data set.
Let's consider another example. Say there is some "Dictionary" class that stores values in an associative array:
var Dictionary =
{
     data : {},
    
     add : $(english, french)
     {
         data[english] = french;
     }
};

// create the first dictionary
var d1 = new Dictionary();
d1.add("red", "rouge");
d1.add("green", "vert");

// create the second dicrionary
var d2 = new Dictionary();
d2.add("blue", "bleu");
d2.add("black", "noir");

// read the data from the first dictionary:
print(d1.data);
Will this work? No. The output is:
{"red":"rouge","green":"vert","blue":"bleu","black":"noir"}
But should be:
{"red":"rouge","green":"vert"}
The resulting object contains data from both the first and second dictionary. Why? Because the d.data object is not owned by d1 object but owned by its prototype, that is, both objects d1 and d2 have access to it. But this is wrong. Each dictionary instance must have its own object for data storage. To solve the issue, you can create this object in the constructor:
var Dictionary =
{
     init : $()
     {
         this.data = {};
     },
    
     add : $(english, french)
     {
         data[english] = french;
     }
};

// create the first dictionary
var d1 = new Dictionary();
d1.add("red", "rouge");
d1.add("green", "vert");

// create the second dicrionary
var d2 = new Dictionary();
d2.add("blue", "bleu");
d2.add("black", "noir");

// read the data from the first dictionary:
print(d1.data);
Now it's right:
{"red":"rouge","green":"vert"}
So, constructors are needed to initialize objects, so that each instance of a class, created using the new operator, contains its unique data.
5.3.5.2. Constructor with parameters
An init method can have parameters that are passed to it as arguments of the new operator:
var Vector =
{
     init : $(x, y)
     {
         this.x = x;
         this.y = y;
     }
};

var v = new Vector(10, 20);

print(v);
Output:
{x:10,y:20}
So, the parameterized constructor allows initializing an object using the data passed as parameters.
5.3.5.3. Constructors chain
Consider a chain of prototypes, with each prototype containing an init method:
var A =
{
     init : $()
     {
         this.x = 1;
     }
};

var B = A ->
{
     init : $()
     {
         this.y = 2;
     }
};

var C = B ->
{
     init : $()
     {
         this.z = 3;
     }
};

var obj = new C();

print(obj);
Output:
{x:1,y:2,z:3}
As you can see, all three constructors were called, because the resulting object contains all three variables.
How it works. If the prototype chain contains prototypes that have an init method, then the new operator calls these methods one by one, starting from the "deepest" prototype.
In the example above, the init method of object A will be called first, then the init method of object B , then the init method of object C .
This order of calling constructors allows you to correctly initialize the object. Let's try to change the value of the variable in the last constructor:
var A =
{
     init : $()
     {
         this.x = 1;
     }
};

var B = A ->
{
     init : $()
     {
         this.y = 2;
     }
};

var C = B ->
{
     init : $()
     {
         x = 7;
         this.z = 3;
     }
};

var a = new A();
var b = new B();
var c = new C();

print("" + a + "\n" + b + "\n" + c);
Output:
{x:1}
{x:1,y:2}
{x:7,y:2,z:3}
You see? Each subsequent constructor in the chain complements the object's initialization. During this, of course, the results of the work of the previous constructor can be changed.
5.3.5.4. Passing parameters to the constructors chain
When passing parameters through the new operator, all parameters are passed only to the first constructor:
var A =
{
     init : $()
     {
         this.x = 10;
     }
};

var B = A ->
{
     init : $(y, z)
     {
         this.y = y;
         this.z = z;
     }
};

var obj = new B(20, 30);

print(obj);
Output:
{x:10,y:20,z:30}
All others (not first) constructors in the chain are called without parameters.
5.3.6. Overriding
You can override properties (fields and methods) in children's objects.
Method overriding, in Goat programming language, is a language feature that allows a subobject to provide a specific implementation of a method that is already provided by one of its prototypes. The implementation in the subobject overrides (replaces) the implementation in the prototype by providing a method that has the same name as the method in the prototype. The version of a method that is executed will be determined by the object that is used to invoke it.
// the object with the method which will be overridden:
var Animal =
{
     talk : $()
     {
         print("This animal can not speak.\n");
     }
};

// inherit the first object and override the method:
var Goat = Animal ->
{
     talk : $()
     {
         print("Baa!\n");
     }
};

// inherit the second object and override the method again:
var Cow = Animal ->
{
     talk : $()
     {
         print("Moo!\n");
     }
};

// inherit the third object but does not override the method:
var Fish = Animal ->
{
};

// create three objects and call the methods:
var g = new Goat();
var c = new Cow();
var f = new Fish();

g.talk();
c.talk();
f.talk();
Output:
Baa!
Moo!
This animal can not speak.
The same rule for fields. Field with the same name as in prototype overrides the previous field:
// the object with the field which will be overridden:
var Programmer =
{
     salary : 1000
};

// inherit the first object and override the field:
var Senior = Programmer ->
{
     salary : 1500
};

// inherit the second object but does not override the field:
var UnitTester = Programmer ->
{
};

// create two objects and read the fields:
var s = new Senior();
var ut = new UnitTester();

print(s.salary);
print("\n");
print(ut.salary);
Output:
1500
1000
5.3.7. Operator overloading
Operators can be redefined. From the point of view of the interpreter, the operator is no different from the usual method. The method that defines the operator has the same name as the operator itself. Let's consider an example:
var Vector =
{
     init : $(x, y)
     {
         this.x = x; this.y = y
     },
    
     toString : $()
     {
         return "X: " + x + ", Y: " + y;
     },
    
     "+" : $(vec)
     {
         return new Vector(x + vec.x, y + vec.y);
     },
    
     "*" : $(val)
     {
         return new Vector(x * val, y * val);
     }
};

var v1 = new Vector(100, 200);
var v2 = new Vector(200, 400);

var v3 = v1 + v2;
print(v3.toString() + "\n");

var v4 = v1 * 5;
print(v4.toString() + "\n");
Output:
X: 300, Y: 600
X: 500, Y: 1000
In the example above, the class "Vector" is described. A vector is a complex data structure. Vectors can be summed, a vector can be multiplied by a number. Therefore, for this structure, two operators are defined: + and * . Each operator returns a new vector as the result of an operation of addition or multiplication.
How it works. When the interpreter processes a binary operator, it finds the corresponding method at the left operand and calls this method, passing the right operand as the parameter. The result of the operation is the return value of the method. In the case of a unary operator, the method is called without parameters.
Unary operators: ++ , -- , ! , ~ , + , - , and binary operators + , - , * , / , % , << , >> , >>> , & , ^ , | , < , <= , > , >= , && , || can be overloaded.
Operators "Assign by" ( += , *= , etc.) can be overloaded also.
Operators overloading is a powerful tool that greatly simplifies code writing and improves code readability.
5.3.8. Multiple inheritance
5.3.8.1. Definition
Multiple inheritance is a feature of some object-oriented, including prototype-oriented programming languages in which an object or class can inherit characteristics and features from more than one parent object or parent class.
In the example below, the "Brick" object is the "Building Material", but it is made from the "Clay" object. Clay plates and clay mugs are also made from "Clay", and consequently they inherit all clay properties, but they cannot be used as building material (I hope).

Fig. 3. Multiple inheritance

Objects in the Goat programming language can have more than one prototype. In this case, the resulting object will contain all the properties and methods of all parents. Consider another example:

Fig. 4. Multiple inheritance (another example)

var mom = { a: 1 };

var dad = { b: 2, c: 3 };

var son = [mom, dad] -> { d: 4, e: 5 };

println(son.a); // output: "1"
println(son.b); // output: "2"
println(son.e); // output: "5"
If the array is specified as a parameter to the -> operator, the resulting object will be formed from all objects in that array.
5.3.8.2. Diamond inheritance
Let's look at one more example:
var Animal =
{
     eat : $()
     {
         println("'eat' method is called");
     }
};

var Mammal = Animal ->
{
     drinkMilk : $()
     {
         println("'drinkMilk' method is called");
     }
};

var WingedAnimal = Animal ->
{
     flap : $()
     {
         println("'flap' method is called");
     }
};

// A bat is a winged mammal
var Bat = [Mammal, WingedAnimal] ->
{
};

var bat = new Bat();
bat.flap();
bat.drinkMilk();
bat.eat();
Output:
'flap' method is called
'drinkMilk' method is called
'eat' method is called
The graph for it:

Fig. 5. Diamond inheritance

Here, the links between the four objects form a rhomb (a "diamond"), and this situation is called "diamond inheritance". This situation is not a bug, on the contrary, it happens everywhere. However, there may be a problem, which is called...
5.3.8.3. The diamond problem
Let's add a method getOffspring() to two classes:
var Animal =
{
     eat : $()
     {
         println("'eat' method is called");
     }
};

var Mammal = Animal ->
{
     drinkMilk : $()
     {
         println("'drinkMilk' method is called");
     },

     getOffspring : $()
     {
         println("a new pet was born");
     }
};

var WingedAnimal = Animal ->
{
     flap : $()
     {
         println("'flap' method is called");
     },

     getOffspring : $()
     {
         println("we successfully laid an egg");
     }
};

// A bat is a winged mammal
var Bat = [Mammal, WingedAnimal] ->
{
};

var bat = new Bat();
bat.getOffstring();
The new graph for this structure is:

Fig. 6. Diamond problem

Specifically, now we have two different methods with the same name ( getOffspring ) in the Bat object prototypes. The problem is: which one of these methods will be called if you call it from the object? The answer is: it depends on the order of search, which is determined by the results of the topological sorting of the prototypes graph.
5.3.8.4. Topological sorting
The topological sorting of a graph is sorting in which all nodes of the graph are arranged in a linear order in which the node positioned not after all its ancestors. Consider some graph:

Fig. 7. A graph

Result of topological sorting for this graph:

Fig. 8. Topological sorting result

Thus, after topological sorting, all nodes (in our case, prototypes) form a linear list, from left to right, and:
  • Each prototype is always on the right of all its children;
  • In multiple inheritance, the first prototype is to the left of the next one, so the order of prototypes is important.
5.3.8.5. Dealing with the diamond problem
The Goat programming language determines the order of prototypes traversal as a result of the topological sorting of prototypes graph. This defines behavior in two cases:
  • Property searching: the sorted list of prototypes is viewed from left to right, and the search ends as soon as the property is found;
  • Calling init methods when creating an object: the sorted list of prototypes is viewed from right to left, and each prototype is searched for an init method.

Fig. 9. Solving diamond problem

So, for the example above, calling the getOffspring() method from the Bat object will found this method in the Mammal object, because the Mammal object is to the left of the WindedAnimal object in the prototype list:
var bat = new Bat();
bat.getOffstring(); //output: "a new pet was born"
5.3.8.6. Constructor chain for the multiple inheritance
Now, based on the previous chapter, consider the example that contains constructor chain for the multiple inheritance with the diamond problem:
var A =
{
     init : $()
     {
         println('A');
     }
};

var B = A ->
{
     init : $()
     {
         println('B');
     }
};

var C = A ->
{
     init : $()
     {
         println('C');
     }
};

var D = C ->
{
     init : $()
     {
         println('D');
     }
};

var E = [B, D] ->
{
     init : $()
     {
         println('E');
     }
};

var F = E ->
{
     init : $()
     {
         println('F');
     }
};

var obj = new F();
Output:
A
C
D
B
E
F
As discussed earlier, the calling order determined by topological sorting, starting from the deepest (right) prototype. For this case, the sorted prototype chain is: F, E, B, D, C, A, so initialization methods are called in the reversed order.
5.3.9. The main object
All objects in the Goat programming language are derived from the base prototype, named Object . This prototype has some predefined useful methods, so, any Goat object has access to these methods. Consider all these methods below.
5.3.9.1. The 'instanceof' method
The method checks whether there is an object passed as an argument in the prototype chain. This is a way to determine if an object is instantiated from a specific prototype.
Consider this code:
var A = { };
var B = A -> { };
var C = A -> { };

var X = new A();
var Y = new B();
var Z = new C();
Here,
  • X.instanceof(A) returns true because object A is a prototype of object X ;
  • but X.instanceof(B) and X.instanceof(C) returns false because objects B and C are not prototypes of object X ;
  • Y.instanceof(B) returns true because object B is a prototype of object Y ;
  • Y.instanceof(A) returns true because object A is a prototype of object B and object B is a prototype of object Y ;
  • Y.instanceof(C) returns false because object C is not a prototype of object Y ;
  • Z.instanceof(C) returns true because object C is a prototype of object Z ;
  • Z.instanceof(A) returns true because object A is a prototype of object C and object C is a prototype of object Z ;
  • Z.instanceof(B) returns false because object B is not a prototype of object Z .
Obviously, an instanceof(Object) call for any object will return true , because any object derived from Object :
undefined.instanceof(Object) // even that's true
5.3.9.2. The 'clone' method
Returns a clone of the object, that is, a new object in which all properties are the same as in the source object.
The method creates a new object and then copies all the properties and methods from the original object to the new one. Now, if you change the copy, the original object will unchanged:
var original =
{
     x : 10,
     y : 20,
     z : 30
};

var copy = original.clone();

copy.y = 40;

print(original);
print(copy);
Output:
{"x":10,"y":20,"z":30}{"x":10,"y":40,"z":30}
If possible, do not use clone method, inherit an object instead! Cloning is an expensive operation, due to the need to copy each field.
However, note that this method clones only object, i.e. copies (does not clone) each property. It is not "deep cloning". That means that properties of properties will point to the same objects. Consider an example:
var data =
{
     x : 10,
     y : 20,
     z : 30
};

var original =
{
     obj : data
};

var copy = original.clone();

copy.obj.y = 40;

print(original.obj.y); // 40
In this example, after cloning, the following object graph will be constructed:

Fig. 10. Cloning

The clone method is implicitly called in some other operations. For example, operators -> (inherit) and # (write protect, see below) call this method. This method (however, like all the others) can be redefined. And then the operators will call the overridden method.
For example, you can prevent cloning an object, and instead of a clone, return the object itself:
var original =
{
     x : 10,
     y : 20,
     z : 30,
    
     clone : $()
     {
         return this;
     }
};

var copy = original.clone(); // copy is the same object as the original
5.3.9.3. The 'flat' method
Returns a flat object, that is, an object that contains all the properties of the source object, as well as all properties of all prototypes of the source object.
The method creates a new object and then copies all the properties and methods from the original object and from all prototypes of the original object. Thus, a new object has no prototypes (that is, the prototype will be Object ) but has all data from the original object:
var A =
{
     x : 10
};

var B = A ->
{
     y : 20
};

var C = B->
{
     z : 30
};

var F = C.flat();

print(F);
Output:
{"x":10,"y":20,"z":30}
The new object is, as it were, "flat", the same as if it were declared thus:
var F =
{
     x : 10,
     y : 20,
     z : 30
};

Fig. 11. Original object before calling the 'flat' method


Fig. 12. The result of calling the 'flat' method

Note that the copying is done starting from the most "deepest" prototype. Thus, if somewhere in the chain of prototypes some property was redefined, then the "flat" object will contain an overridden property:
var A =
{
     x : 10
};

var B = A ->
{
     x : 15, // overrided
     y : 20
};

var C = B->
{
     z : 30
};

var F = C.flat();

print(F);
Output:
{"x":15,"y":20,"z":30}
5.3.9.4. The 'get' and 'set' methods
The get method returns the value of a property, for example:
var obj =
{
     value : 7
};


var x = obj.get("value");
print(x); // output: "7"
It is the same as:
var x = obj["value"];
The set method sets (changes) the value of a property:
var obj =
{
     value : 7
};

obj.set("value", 11);
print(obj); // output: "{"value":11}"
It is the same as:
obj["value"] = 11;
What's the point? By overriding the get and set methods, you can change the operator [ ] behavior, because using the operator [ ] :
  • for reading, implicitly calls the get method;
  • for writing, implicitly calls set method.
In fact, as a rule, the 'get' method returns the value of a property. But for some types it is redefined, for example, for arrays, it returns an item of an array, for strings, it returns a character.
So, you able to create own collection.
Example 1. Redefining a getter :
var obj =
{
     get : $(index)
     {
         switch(index)
         {
             case 0:
                 return "zero";
             case 1:
                 return "one";
             case 2:
                 return "two";
         }
         return "other";
     }
};

var i;
for (i = 0; i < 5; ++i)
{
     println(obj[i]);
}
Output:
zero
one
two
other
other
Example 2. Multidimensional array (matrix) implementation. In this case, the get method has two arguments and the set method has three:
var Matrix =
{
     init : $(w, h)
     {
         this.w = w;
         this.h = h;
         this.data = [];
         for (var i = 0; i < w * h; i++)
             data.push(0);

     },
    
     get : $(x, y)
     {
         return data[y * w + x];
     },
    
     set : $(x, y, value)
     {
         data[y * w + x] = value;
     },
};

var m = new Matrix(5, 5);
m[1, 2] = 7;
m[3, 3] = 5;
for (var y = 0; y < m.h; y++)
{
     for (var x = 0; x < m.w; x++)
         print(" " + m[x, y]);
     print('\n');
}
Output:
0 0 0 0 0
0 0 0 0 0
0 7 0 0 0
0 0 0 5 0
0 0 0 0 0
5.3.9.5. The 'contains' method
The method checks whether the object contains a property with the specified name.
var obj = {value: 0};
println(obj.contains("value"); // true
println(obj.contains("abc"); // false
The second parameter of the method (it is optional) determines whether the property should be searched not only in the object but also in its prototypes:
var proto = {value: 0};
var obj = proto -> { };
println(obj.contains("value"); // false
println(obj.contains("value", true); // true
This function has two main applications. First one - excluding unnecessary properties when enumerating all properties:
var obj = {x: 10, y: 20, z: 30 };
for (var prop in obj)
{
     if (obj.contains(prop))
         println(prop + ": " + obj[prop]);
}
Output:
x: 10
y: 20
z: 30
Without using this method, the for..in statement enumerates all properties, including inherited, including even inherited from the Object prototype, and output will be like:
z: 30
y: 20
x: 10
clone: function
instanceof: function
flat: function
get: function
set: function
iterator: function
contains: function
!: function
!!: function
&&: function
||: function
#: function
The second application is to determine the presence of a property with the undefined value. For example, if you read an unknown object property, the [ ] operator returns the undefined value:
var obj = {};
println(obj["abc"]); // "undefined"
Suppose we added a property with the undefined value:
var obj = {};
obj.abc = undefined;
println(obj["abc"]); // "undefined"
The result has not changed (obviously). However, the object now contains a property, i.e. the fact that this property was once added or changed to undefined . If this fact is important for your algorithm, you can use the contains method:
var obj = {};
obj.abc = undefined;
println(obj.contains("abc")); // "true"
5.3.9.6. The 'iterator' method
Returns an instance of an iterator object. Iterators are used to enumerate values in a sequence. See the Iterators chapter for more info.
5.3.10. Prototypes of built-in types
Each object of built-in type (string, integer, etc) has own built-in prototype:
  • String is the prototype for strings. Every time you define a string, for example, var s = "hello, world" you create a new object that has the String prototype;
  • Integer is the prototype for integers;
  • Real is the prototype for floating-point numbers;
  • Char is the prototype for characters;
  • Boolean is the prototype for booleans;
  • Null is the prototype for null constant;
  • Array is the prototype for all arrays;
  • functions are also objects! Each time you declare a function, for example, var f=$(){ } an object is created, the prototype of which is Function .
Other prototypes of built-in classes are: Thread , Exception , File , StringBuilder , ByteArray .
Each prototype has, respectively, its properties, methods, and operators. For example, strings have a predefined + operator, which concatenating strings.
Using a prototype, you can check whether the object is the right data type. Here is an example of a function, at the beginning of which it is checked whether the argument is an integer:
var f = $(value)
{
     if (value.instanceof(Integer))
     {
         //...
     }
};
This is a graph that shows the relations between built-in prototypes. Here is not all, but most of built-in objects inherit the Object :

Fig. 13. Inheritance of some built-in types

Some of these prototypes have their heirs, say, the Exception object:

Fig. 14. Inheritance of exceptions

You can create a built-in object using the new operator, just like any other object:
var b = new StringBuilder();
However, the new operator works also for "primitive" objects, like integers and strings:
var s = new String("hello");
It is the same as:
var s = "hello!";
What's the point? First, it is done for compatibility (all objects work same, as much as possible), and second, the new operator tries to convert the argument to its "own" type, and it can be used to convert types:
var i = new Integer("1024"); // 1024
If the conversion fails, returns an object by default (0 for Integer , Real and Number ), an empty string for String , false for Boolean ), contrary with valueof ' method (it returns null ).
Note, you can't call the new operator for some abstract prototypes (such Iterator or File ), this will throw an IlegalOperation exception. To create an object of such type, you should call the appropriate method (in these cases iterator() and open() ).
5.4. All about nothing
There are special objects in the Goat programming language that means "nothing": undefined , null and void .
5.4.1. undefined
As previously described, undefined means that no value has been assigned. Any variable defined using "var" keyword without an initial value has the value of undefined :
var v;
print(v); // output: "undefined"
Moreover, if you try to read the value of an undeclared variable, this value will also be undefined :
print(n3j9v0kXXq); // output: "undefined"
The same is true if you read a non-existent property of an object:
var obj = { x: 10, y: 20 };
print(obj.z); // output: "undefined"
Is undefined an object? Yes. This is an object, and it even has its own prototype: Undefined . But you can not do anything with this object. You cannot change the properties of undefined , you can not call methods (except derived from the Object , say, instanceof ). All you can is compare this object to undefined :
if (obj == undefined)
{
     //...
}
5.4.2. null
The second special object. It means that the value was defined, that is, it is not equal to undefined , but it is empty. Null is not numeric, is not a string. This is "nothing".
Unlike undefined , the null object is not created implicitly anywhere. It can be explicitly assigned to a variable or returned from a method:
var n = null;

var f = $()
{
     //...
     return null;
};
null is not equal to undefined :
var u; // undefined

if (u == null) // false!
{
     //...
}
Is null an object? Yes. This is an object, like undefined , and it has its own prototype: Null . You can not add prototypes to null , but you can call methods, derived from the Object :
print(null.instanceof(Null)); // "true"
5.4.3. void
The third data type, which combines the two previous ones.
The void object has prototype Void ", and both Undefined and Null inherits from Void . So, in other words, undefined is void and null is void . This is used if you need to check with one operation whether the object is null or undefined :
var f = $(value)
{
     if (value == void)
     {
         throw new Exception.IllegalArgument();
     }
    
     //...
};
This is the same as:
var f = $(value)
{
     if (value == undefined || value == null)
     {
         throw new Exception.IllegalArgument();
     }
    
     //...
};
5.4.4. Operator ?. (void guard)
You can not read a property from undefined or null . If you try to read a property from void , this will throw an exception Exception.IllegalReference . Thus, sometimes it is necessary to check whether a variable (most often an argument of a method) is a void. This avoids unintended consequences like exceptions. For example:
// safe 'exist' field reading from 'some.object.that.might.not.exist':
if (some != void)
{
     if (some.object != void)
     {
         if (some.object.that != void)
         {
             if (some.object.that.might != void)
             {
                 if (some.object.that.might.not != void)
                 {
                     return some.object.that.might.not.exist;
                 }
             }
         }
     }
}
return 0;
This, probably, is not the shortest solution.
Operator ?. read a property (calls a method) only if a left object is not void, otherwise returns undefined:
/* if object is void (null or undefined) then val = undefined,
   else val = property: */
val = object?.property;

/* if object is void (null or undefined) then val = undefined,
   else val is result of method call: */
val = object?.method();
The result can be supplemented by the or ( || ) operator to change undefined to alternate value:
/* if object is void (null or undefined) then val = alternate,
   else val = property: */
val = object?.property || alternate;

/* if object is void (null or undefined) then val = alternate,
   else val is result of method call: */
val = object?.method() || alternate;
Okay, let's rewrite the first example. Is not it, much shorter:
return some?.object?.that?.might?.not?.exist || 0;
5.5. Objects write protection
Objects can be write protected. After protecting, nothing can change (or add) properties or methods of the object.
5.5.1. Operator #
This is a unary operator. It clones an object passed as a parameter (to the right of the operator) and then write protect the result of cloning. The object returned by the operator cannot be changed:
var obj = #
{
     x : 10,
     y : 20
};

obj.z = 30; // illegal operation!
The operator does not change the original object. Only its copy is protected:
var A =
{
     x : 10,
     y : 20
};

var B = #A;

A.z = 30; // allowed
B.z = 30; // is not allowed
5.5.2. What happens when writing to a write protected object?
The interpreter will immediately throw an exception Exception.IllegalOperation :
var A = #
{
     x: 10,
     y: 20
};

try
{
     A.z = 0;
}
catch(e)
{
     if (e.instanceof(Exception.IllegalOperation))
         print("oops!");
}
5.5.3. Why is it necessary to protect objects from writing?
Obviously, to prevent changes that will lead to an error. A classic example is the creation of enumerations. The standard library contains many such enumerations. For example, file mode for i/o operations:
File.Mode =
{
     READ : "READ",
     WRITE : "WRITE",
     APPEND : "APPEND",
     FULL : "FULL"
};
This enumeration is used when opening a file:
var file = open(file_name, File.Mode.WRITE);
However, if it were possible, intentionally or accidentally, to change the values of this enumeration, for example, like this:
File.Mode.WRITE = "READ";
...continued use of this enumeration would result in an error. Therefore, such an object must be immutable. To protect object, just add operator # before object declaration.
All objects of the standard library - classes, functions, enums, including built-in, i.e. Object, String, Integer, etc. - are write protected.
5.6. Iterators
An iterator is a special type that allows getting (enumerate) some objects in sequence, one after another. Based on iterators, some algorithms and language structures are work.
5.6.1. The 'Iterator' object
The Iterator object is abstract, it means, it contains some stub methods that must be overridden in derived objects. It defines two methods:
valid ( )
Returns true if the iterator is valid, i.e. can return the next object.
next ( )
Returns the next object.
Example:
var iter = collection.iterator();
while (iter.valid())
{
     var obj = iter.next();
     // do something with the object
}
5.6.2. The 'iterator' method
The instance of the Iterator object returns by the iterator method. This method is defined in the Object , so, each object inherits it and can override it. The default implementation returns an iterator that enumerates names of all properties:
var obj =
{
     x : 7,
     y : 11,
     z : "test"
};

var iter = obj.iterator();

while(iter.valid())
{
     var key = iter.next();
     if (obj.contains(key))
         println("" + key + " = " + obj[key]);
}
Output:
x = 7
y = 11
z = test
This behavior is redefined for some objects. For example, for strings, the iterator method returns an iterator that enumerates all characters of this string:
var s = "test";
var i = s.iterator();

while(i.valid())
{
     println(i.next());
}
Output:
t
e
s
t
5.6.3. The 'for..in' loop
In fact, this statement implicitly calls the iterator method from an object and then does the while loop, calling the valid and the next methods from a returned iterator.
The previous example can be rewritten as:
var obj =
{
     x : 7,
     y : 11,
     z : "test"
};

for (var key in obj)
{
     if (obj.contains(key))
         println("" + key + " = " + obj[key]);
}
So, any object can be transformed into an enumerable collection or generator, all you need is to define your own iterator and override the iterator method.
5.6.4. Generators
A generator is an iterator that does not enumerate items of a collection (object, array, etc) but generates values itself.
The built-in range method is a generator: it returns values from some range:
for (var v in range(10))
{
     print(v);
}
Output:
0123456789
As an example of a custom generator, let's write a generator that returns squares of numbers from 0 to 10:
// Iterator
var SquareIterator =
{
     init : $()
     {
         this.value = -1;
     },
    
     valid : $()
     {
         return value < 10;
     },
    
     next : $()
     {
         value++;
         return value * value;
     }
};

// Generator
var SquareNumbers =
{
     iterator : $()
     {
         return new SquareIterator();
     }
};

// Loop
for (var num in SquareNumbers)
{
     println(num);
}
Output:
0
1
4
9
16
25
36
49
64
81
100
5.7. Threads
The Goat programming language supports threads. A thread of execution is the sequence of programmed instructions that managed independently by a scheduler. In other words, threads are the ability to execute two or more sections of code at the same time.
Each running program contains at least one thread. Goat does not separate the "main" and "non-main" threads - each thread can initiate a new thread, and each thread can stop the execution of another thread (if it has a reference to this). The program ends only when all threads are completed.
5.7.1. Threads declaration
Threads are declared in the same way as functions, but the thread keyword is used instead of the function keyword:
var a = thread()
{
     for (var i = 0; i < 10; i++)
         print('A');
};
The thread keyword can be changed to two dollar signs $$ (for shortness):
var a = $$()
{
     for (var i = 0; i < 10; i++)
         print('A');
};
5.7.2. Starting
To start a thread, need to call the run() method:
var a = thread()
{
     for (var i = 0; i < 10; i++)
         print('A');
};

a.run();
Output:
AAAAAAAAAA
You can re-run a thread that is already in progress. The second instance of a thread will be created and started.
var a = thread()
{
     for (var i = 0; i < 10; i++)
         print('A');
};

a.run();
a.run();
Output:
AAAAAAAAAAAAAAAAAAAA
You can run two, three, as many threads as you need, and they will run at the same time:
var a = thread()
{
     for (var i = 0; i < 10; i++)
         print('A');
};

var b = thread()
{
     for (var i = 0; i < 10; i++)
         print('B');
};

a.run();
b.run();
The output is something like this:
ABABABABABABABABABAB
Note: there is no guarantee of the order of execution of threads. The result may well be:
AABBBAAAABABBAABABAB
It is guaranteed that every thread will be executed from beginning to end.
The Thread prototype is derived from the Function . So, all function features are applicable for the threads. Say, you can run thread as function (if you need it, though not likely):
var t = thread()
{
     for (var i = 0; i < 10; i++)
         print(i);
};

t();
5.7.3. The 'Runner' object
The 'run' method returns an instance of the 'Runner' object, which has the set of methods to started thread control.
kill ( )
Kills the thread (without resuming ability) and removes it from the thread list. Returns true if the thread was killed.
Example:
var b = thread()
{
     // this thread will never end if anybody does not stop it!
     while(true)
         print('B');
};

var r = b.run();
for (var i = 0; i < 10; i++)
     print('A');
r.kill();
The output is something like this: BBABBABBABBBABBABBABBBABBABBABBBABB . Obviously, this approach allows controlling some "infinite" processes, such as services, listeners, etc.
alive ( )
Returns true if the thread is alive (not finished yet or not killed).
Example:
var b = thread()
{
     for (var i = 0; i < 10; i++)
         print('B');
};

var r = b.run();
while(r.alive())
     print('A');
works ( )
Returns true if the thread works now (alive and not suspended).
suspend ( )
Suspends the thread, returns true if the thread is suspended.
resume ( )
Resumes the suspended thread, returns true if the thread is resumed.
Example:
var t = thread()
{
     // infinite thread
     while(true)
         print('#');
};

// run the thread
var r = t.run();

// print "AAAAA", result should be like "#A##A##A##A##A"
for (var i = 0; i < 5; i++)
     print('A');
    
// suspend the thread then print "BBBBB"
r.suspend();
for (var i = 0; i < 5; i++)
     print('B');

// resume then print 'CCCCC'
r.resume();
for (var i = 0; i < 5; i++)
     print('C');

// kill the thread
r.kill();

// Output: "#A##A##A##A##A##BBBBB##C##C##C##C##C##"
join ( )
Joins the thread, i.e. suspends the current thread while the joined thread is alive.
Example:
var t = thread()
{
     for (var i = 0; i < 5; i++)
         print('A');
};

var r = t.run();
r.join();
for (var i = 0; i < 5; i++)
     print('B');
    
// Output: "AAAAABBBBB"
id ( )
Returns numeric identifier of the thread (≥0).
5.7.4. Getting a reference to the current thread
For some cases is needed to get an instance of the Runner object for the current thread. The static Thread.current method returns it. Example (prints the current thread Id):
var r = Thread.current();
println(r.id());
5.7.5. Passing parameters to a thread
All parameters of the run method are passed to the thread as if it were a simple function call:
var t = thread(count)
{
     for (var i = 0; i < count; i++)
         print(i);
};
t.run(10); // output: "0123456789"
5.7.6. Synchronization
Two or more threads can access the same data. Simultaneous reading or writing can lead to an incorrect result: if one thread reads an object and the other thread writes it (i.e. adds or changes properties), in some cases the first thread may read incorrect data (if at the time of reading some data has changed, and some are not). Obviously, in order to preserve the consistency of the data, during the access to such a shared object, concurrent threads must be blocked - until one reads, the other can not write; until one writes, the other cannot read.
The Goat programming language provides some tools for synchronization.
5.7.6.1. Critical section
This is the simplest primitive of synchronization. Inside the critical section, the interpreter does not switch threads.
A critical section is a block of code after the lock keyword:
lock
{
     // some code here...
}
The lock keyword can be used as a method name. A critical section is defined as the lock keyword and any statement after it. It doesn't have to be a block statement:
lock ++value;
Critical sections should be made very short, it is recommended to do it only for reading/writing one-two-three variables, as a long suspend of other threads can negatively affect the execution of the script. However, is the fastest way of synchronization.
Example: writing a variable from 7 threads simultaneously:
var x = 0;

var t = thread()
{
     var i;
     for (i = 0; i < 100; ++i)
     {
         lock
         {
             ++x;
         }
     }
};

var r1 = t.run();
var r2 = t.run();
var r3 = t.run();
var r4 = t.run();
var r5 = t.run();
var r6 = t.run();
var r7 = t.run();
r1.join();
r2.join();
r3.join();
r4.join();
r5.join();
r6.join();
r7.join();
println(x); // output: "700"
What happens if we wouldn't use a critical section here? The increment ++x is not an atomic operation, it takes three steps:
  • Loading value of a variable (or a property);
  • Increment;
  • Storing a new value to a variable.
Let's say the initial value of variable 0 and two threads increment it.
  • The first thread loads the value of the variable (0).
  • The second thread loads the value of the variable (0, because the first thread did not change it yet).
  • The first thread increments the value (1).
  • The second thread increments the value (1, because it "does not know" that the first thread did something - the threads are independent).
  • The first thread stores the value to the variable (1).
  • The second thread stores the value to the variable (rewrites 1 to 1, but should be 2 - error).
This example does not take into account the fact that threads do not necessarily execute their instructions strictly by one. In fact, the first thread can execute any number of instructions before passing control to another thread. But in any case, unsynchronized access to shared resources can lead to serious errors that hard to detect and fix.
5.8. Command line arguments
As previously described, all arguments started with two hyphens are internal parameters of the interpreter; the first argument which is not an option is the name of the script file. All next arguments are sent to the script and can be read from the special pseudo-array named parg .
The parg object is always created by the interpreter when the script starts. It contains zero or more String objects.
Example. The script that reads file specified as the first argument and makes a copy (write another file) with the name specified as the second argument.
import "io.goat";

if (parg.length() != 2)
{
     println("syntax: goat copy.goat <source> <destination>");
     exit(-1);
}

var data = load(parg[0]);
if (!data)
{
     println("could not open '" + parg[0] + '\'');
     exit(-1);
}

var dst = open(parg[1], File.Mode.WRITE);
if (!dst)
{
     println("could not open '" + parg[1] + "' for writing");
     exit(-1);
}

var len1 = data.length();
var len2 = dst.write(data);
println("Read " + len1 + " bytes, " + len2 + " bytes written.");
dst.close();
Note that the parg object is pseudo-array. It inherited from ArrayLike prototype (see Prototypes of built-in types chapter). This object like a read-only array: you can read length of this and get an item by index, but can not modify it.
5.9. Hardware dependent data
5.9.1. Ports
A port is a variable in the address space representing the interface between the Goat runtime and computer or peripheral devices. The port list is different for various platforms.
The Goat context contains the special object named ports , each field of which linked to a hardware port. You can use the [ ] operator for accessing a separate port, for example:
ports["gpio0"] = true;
For each platform at least one port, "null" , is defined, for debugging purposes. Writing to this port produces nothing, reading from this port always returns null :
print(ports["null"]); // "null"
6. Standard library
The standard library contains functions and classes for solving common tasks.
All the functionality of the standard library is divided into two parts: internal (as part of the interpreter core) and external.
The functionality of the inner part of the library is written in C++ language and is the minimum required set for solving most tasks. This functionality includes platform-dependent components, such as working with files. No additional modules are required to use the internal library, these classes and functions are always available.
The external library is written in the Goat language. It is a set of files that contain separate classes for solving various tasks. To use this class from the library, you need to link the corresponding file using the import keyword.
6.1. Internal (core) library
6.1.1. Functions
6.1.1.1. Input/output
print ( object )
Converts an object to a string and sends this string to standard output.
Parameter:
  • object (any type): an object
Example:
print("Hello");
print(2 + 3);
print(0.01);
print(false);
print(null);
println ( object )
Converts an object to a string and sends this string to standard output with a newline at the end.
Parameter:
  • object (any type): an object
Example:
println("Hello");
getc ( )
Reads one character from the standard input. Returns null if no characters (end-of-file is reached).
Example:
while(true)
{
     var c = getc();
     if (c == null)
         break;
     print(c);
}
gets ( )
Reads characters from the standard input and stores them as a string until a newline character or the end-of-file is reached.
Example:
while(true)
{
     var s = gets();
     println(s);
}
open ( fname, mode )
Opens a file.
Parameters:
  • fname (String): file name
  • mode (File.Mode): mode, see below
Example:
var file = open("reference.xml", File.Mode.READ);
var data = file.read(256); // read first 256 bytes
Returns an instance of File , or null if the file can not be opened. For all modes that allow writing, in case if file not exists, the new one is created.
Available file modes are:
  • File.Mode.READ , allows only to read a file, writing operations are blocked;
  • File.Mode.WRITE , only write operations;
  • File.Mode.APPEND , only write operations, new data will be added to the end of the existing file;
  • File.Mode.FULL , both reading and writing.
See description of File class for more details.
6.1.1.2. Mathematical
abs ( arg )
Computes absolute value.
Parameter:
  • arg (Integer | Real): a value
Example:
var x = abs(-123); // 123
The returned value has the same type as the argument.
acos ( arg )
Returns the arc cosine of arg, expressed in radians.
Parameter:
  • arg (Real): a value
Example:
var x = acos(-1); // 3.1415927...
asin ( arg )
Returns the arc sine of arg, expressed in radians.
Parameter:
  • arg (Real): a value
Example:
var x = asin(1); // 1.5707963...
atan ( arg )
Returns the arc tangent of arg, expressed in radians.
Parameter:
  • arg (Real): a value
atan2 ( y, x )
Returns arc tangent from 2 arguments, expressed in radians.
Parameters:
  • y (Real): y-coordinate
  • x (Real): x-coordinate
Example:
var x = atan2(1, 1); // 0.7853982 radians, i.e. 45 degrees
cbrt ( arg )
Returns the cubic root of arg.
Parameter:
  • arg (Real): a value
Example:
var x = cbrt(27); // 3
cos ( arg )
Returns the cosine of an angle of arg radians.
Parameter:
  • arg (Real): a value
Example:
var x = cos(60.0 * PI / 180.0); // 0.5
exp ( arg )
Computes exponential function.
Parameter:
  • arg (Real): value of the exponent
Example:
var x = exp(5); // 148.413159
log ( arg )
Computes natural logarithm (reverse operation to exp ).
Parameter:
  • arg (Real): value whose logarithm is calculated
Example:
var x = log(exp(5)); // 5
log2 ( arg )
Computes binary logarithm.
Parameter:
  • arg (Real): value whose logarithm is calculated
Example:
var x = log2(1024); // 10
log10 ( arg )
Computes common (base-10) logarithm.
Parameter:
  • arg (Real): value whose logarithm is calculated
Example:
var x = log2(1000); // 3
round ( arg )
Returns the rounded (integer) value of arg.
Parameter:
  • arg (Real): a value
Example:
var x = round(2.8); // 3
var y = round(-2.1); // -2
Return type is Integer .
sin ( arg )
Returns the sine of an angle of arg radians.
Parameter:
  • arg (Real): a value
Example:
var x = sin(PI/2); // 1
sqrt ( arg )
Returns the square root of arg.
Parameter:
  • arg (Real): a value
Example:
var x = sqrt(64); // 8
tan ( arg )
Returns the tangent of an angle of arg radians.
Parameter:
  • arg (Real): a value
6.1.1.3. Other
exit ( value )
Terminates the current thread and passes a value to a handler
Parameter:
  • value (Integer): a value (optional)
Example:
if (error)
{
     exit(-1);
}
If the thread was alone, terminates the execution of the script. In this case, the returned value is written to ERRORLEVEL and can be analyzed by the calling script.
clock ( )
Returns current system time in nanoseconds.
Example:
var wait = $(time)
{
     var begin = clock();
     var diff = 0;
     do
     {
         diff = clock() - begin;
     } while(diff < time * 1000000000);
};

var i;
for (i = 5; i > 0; i--)
{
     print("" + i + "\n");
     wait(1);
}
The example shows a simple implementation of delay and countdown using the 'clock' function. The function returns the time span value between the begin of the 'system epoch' (it depends from the platform) and the current time point. In itself, this value is useless, as a rule, the difference between the two clock values is used.
range ( begin | count, end, step )
Returns a collection representing a range of integer numbers.
Parameters:
  • begin | count (Integer): A starting value of a range (if ending value is defined), or count of items of the range (starting from 0)
  • end (undefined): An ending value (optional, range does not include this value)
  • step (undefined): A step, i.e. increment of the next item (optional, default 1)
Example:
for (var i in range(5)) print(i); // 01234
for (var i in range(5, 10)) print(i); // 56789
for (var i in range(0, 10, 3)) print(i); // 0369
for (var i in range(9, 0, -2)) print(i);....// 97531
If step > 0 but end < begin , and vice-versa, the function returns an empty collection (contains 0 values).
uid ( )
Returns an instance of UId class, which is a unique object (contains a 128-bit value that never repeats).
Example:
print(uid()); // an output something like "8fb959ea0198df83" but unique each time
The likelihood of collision (matching of UId with other identifiers generated at other times) is very low. A unique identifier can be used as a key in some data types.
6.1.2. Classes
6.1.2.1. Input/output
6.1.2.1.1. File
The class for file reading/writing.
Files are opened by the open function (see above). The open function returns an object of File type, or null if the file could not be found or could not be open. The File class contains methods for reading/writing and some predefined fields, used in open and seek methods.
Methods
read ( count )
Reads a file and returns a ByteArray object with data (see also: ByteArray ).
Parameter:
  • count (Integer): number of bytes to read
Example:
var f = open("data.txt", File.Mode.READ);
var a = f.read(1024); // read first 1024 bytes
If the number of bytes exceeds the file size, the method will return as many bytes as it could read. The position indicator of the file is advanced by the total amount of bytes read. The method throws the Exception.IllegalOperation exception if the file can not be read (opened for writing or closed).
getc ( )
Reads one byte from the file and returns it (as Integer ), or null if reading unsuccessful.
Example:
var f = open("data.txt", File.Mode.READ);
var byte = f.getc(); // read the first byte
write ( data )
Writes data to the file, to the current position. Returns number of bytes that was actually written.
Parameter:
  • data (ByteArray): data for writing
Example:
var f = open("data.txt", File.Mode.WRITE);
var t = "This string will be written to the file.";
f.write(t.encode("utf8"));
The position indicator of the file is shifted and points after the last written byte. The method throws the Exception.IllegalOperation exception if the file can not be written (opened for reading or closed).
flush ( )
Flushes all data from the write buffer to disc, i.e. physically write data.
Example:
var f = open("data.txt", File.Mode.WRITE);
var t = "This string will be immediately written to the file.";
f.write(t.encode("utf8"));
f.flush();
eof ( )
Checks whether the end of file indicator associated with file is set, returning true if it is.
Example:
var f = open("data.txt", File.Mode.READ);
while (!f.eof())
{
     // read the file in chunks of size 1024 bytes
     var a = f.read(1024);
     // ...
}
position ( )
Returns the current value of the position indicator of the file.
Example:
var f = open("data.txt", File.Mode.READ);
f.seek(0, File.Origin.END);
var len = f.position(); // length of file
seek ( offset, origin )
Sets the position indicator associated with the file to a new position.
Parameters:
  • offset (Integer): number of bytes to offset from origin
  • origin (File.Origin): origin, one of: File.Origin.BEGIN, File.Origin.END or File.Origin.CURRENT
Example:
var f = open("data.txt", File.Mode.READ);
f.seek(0, File.Origin.END); // go to end of the file
var len = f.position(); // take position (position at the end is the length of the file)
f.seek(0, File.Origin.BEGIN); // now, go to begin
var data = f.read(len); // read the whole file
close ( )
Closes the file. All data flushes to the disc and the file descriptor is cleared. After closing, the file cannot be reading or writing.
Example:
var f = open("data.txt", File.Mode.WRITE);
var t = "This string will be written to the file.";
f.write(t.encode("utf8"));
f.close();
This is an optional operation. All files are closes anyway: when you lose the last reference to the File instance, the garbage collector cleans it; if not - the file will be closed at the end of the script execution. But each opened file takes some resources, and if you want to save memory, close the file manually if it is not needed more.
Fields
File.Mode
The object contains constants for file access mode, is used as an argument for open function.
File.Mode =
{
     READ : ?,
     WRITE : ?,
     APPEND : ?,
     FULL : ?
};
Usage:
var f = open("data.txt", File.Mode.READ);
The question mark ? means that in fact a constant is assigned a value (this is usually a string), but it depends on the implementation. Never use a value ("magic string" or "magic number") instead of a constant!
Very bad example, please do not repeat it:
var f = open("data.txt", "READ"); // yes, it works now... but can fail later
File.Origin
The object contains constants for origin, is used as an argument for File.seek method.
File.Origin =
{
     BEGIN : ?,
     END : ?,
     CURRENT : ?
};
6.1.2.2. Sequences
6.1.2.2.1. ByteArray
The class for storing an array of bytes.
The Goat interpreter does not have a separated type for bytes representing. The Integer type is used for this purpose. However, each Integer object takes much more memory than 1 byte. If you need to store an array of bytes, do not create an array of integers, use ByteArray class instead.
ByteArray class is used in files read/write operations.
Methods
length ( )
Returns length of the byte array.
push ( byte )
Appends a byte to the byte array.
Parameter:
  • byte (Integer): byte, valid values [0...255]
Example:
var a = new ByteArray();
a.push(0);
decode ( encoding )
Decodes the byte array as text and returns a string.
Parameter:
  • encoding (String): encoding; now only "utf8" is supported
Example:
// open the file and decode it as UTF-8
var file = open("data.txt", File.Mode.READ);
file.seek(0, File.Origin.END); // go to end of the file
var len = file.position(); // take the length of the file
file.seek(0, File.Origin.BEGIN); // now, go to begin
var raw = file.read(len); // read the whole file
var text = raw.decode("utf8"); // decode
Operators
Operator [ ]
Access to a separate byte by index.
Example:
var a = new ByteArray();
a.push(0);
a.push(7);
a.push(11);

print(a[1]); // 7
6.1.2.2.2. StringBuilder
The class for strings constructing.
The Goat programming language has immutable strings. It prevents many errors, but in some cases constructing of long string takes a lot of time, because for each iteration Goat creates a new string. For example:
// some coordinates:
var c = { x: 10, y: 20, z: 30};

// build string:
var str = "X=" + c.x + ", Y=" + c.y + ", Z=" + c.z;
It works, yes, but it is not a better solution. Goat splits the long expression and creates a new string (which, in turn, involves the creation of a new array of characters, and copying of the original array) on each step:
"X=" + c.x
-> "X=10"
... + ", Y="
-> "X=10, Y="
... + c.y
-> "X=10, Y=20"
... + ", Z="
-> "X=10, Y=20, Z="
... + c.z
-> "X=10, Y=20, Z=30"
So, five strings will be constructed. What about thousands of strings? Say you have an array and you need to make a string from it. A lot of time, a lot of memory! Or, you can use StringBuilder.
// some coordinates:
var c = { x: 10, y: 20, z: 30};

// build string:
var b = new StringBuilder();
b << "X=" << c.x << ", Y=" << c.y << ", Z=" << c.z;
var str = b.toString();
Much better.
StringBuilder has an array to hold characters. This array grows when new items (characters, strings, etc) added. This class does not create a new string for each addition. Thus, the construction of a long string takes much less time and memory.
Methods
add ( object )
Appends string representation of an object to the sequence.
Parameter:
  • object (any type): an object
Example:
var b = new StringBuilder();
b.append("test");
b.append('#');
b.append(123);
print(b); // output: "test#123
If there are multiple arguments, each argument is converted to a string and added to the sequence.
string ( )
Returns a string representing the data in this sequence.
Example:
var b = new StringBuilder();
b.append("hello");
b.append(", ");
b.append("world");
var s = b.string(); // contains "hello, world"
data ( )
Synonym for the string method.
length ( )
Returns the length of the sequence.
Operators
Operator <<
Appends string representation of object to the sequence.
Example:
var b = new StringBuilder();
b << "test" << '#' << 123;
print(b); // output: "test#123"
This is a synonym for the append method, but using the operator instead of the method is more convenient.
6.1.3. Constants
PI
The π (pi) constant (3.14159...)
print(PI);
6.2. External library
6.2.1. Algorithms
These are common functions that can be applied to various structures of data. All algorithms are defined in the lib\algorithm.goat file.
indexOf ( array, searchElement )
Returns index of the element of array (or array-like object, it should support index access). If the element is not found, the method returns -1.
Parameters:
  • array (ArrayLike | String): an array or array-like object
  • searchElement (any type): an element
Example:
import "algorithm.goat";
var a = [0,"test",true];
print(indexOf(a, "test"); // 1
6.2.2. Input/output
6.2.2.1. Methods
All metods are defined in the lib\io.goat file.
load ( )
Loads the whole file and returns a ByteArray object contains data, or null if the file can not be loaded.
Example:
import "io.goat";
var data = load("data.txt");
6.2.3. Collections
Collections are used to store data. Each collection saves data in some special order. Base prototypes (see diagram) contain methods common to each collection.

Fig. 15. Collections

6.2.3.1. Big O notation
One of the features of collections is the different execution times of the same operations for different collections. For example, inserting at the beginning of a linked list is faster than inserting at the beginning of a vector, but getting a vector element by its index is faster than a similar operation in the list. Programmer must choose a suitable collection based on his goals.
To describe the execution time of methods, the "Big O notation" ( https://en.wikipedia.org/wiki/Big_O_notation ) is used here.
Let me try to briefly describe a few commonly used examples of such notation.
  • O(1) means that regardless of the number of elements in the collection, the method will always execute the same time;
  • O(n) means that the method will be executed in proportion to the number of elements in the collection. For example, a linear search: if the collection contains 10 elements, then to find the one you need to look at a maximum of 10 elements;
  • O(n²) means that the method will be executed proportionally squared the number of items in the collection. For example, bubble sorting: if the collection contains 10 elements, then for sorting you need to compare 10 times for 10 elements, that is 100;
  • O(log(n)) is a logarithmic complexity, and we like it very much. For example, binary search: if the collection contains 1000 elements, then the search requires no more than 10 comparisons;
  • O(n!) - we don’t like it at all, strange why?
6.2.3.2. Collection
The base class for all collections. It defined in the lib\collection.goat file. Each collection should provide at least these methods:
size ( ) → O(1)
Returns size of the collection, i.e. count of elements.
empty ( ) → O(1)
Returns true if the collection is empty.
iterator ( ) → O(1)
Creates an iterator to enumerate all elements.
Defining the iterator method means you can use for..in operator for all collections.
Example:
var collect = getCollection(); // some method that returns an instance of Collection (List, Array, etc)
for (var element in collect)
{
     // do something
}
contains ( element )
Returns true if the collection contains the element.
Parameter:
  • element (any type): an element
Complexity: Depends on implementation.
toArray ( ) → O(n)
Returns an array contains all elements of the collection.
6.2.3.3. IndexedCollection
The base class for a collection, elements of which can be accessed by integer index. It defines, in additional to the Collection class, these methods:
indexOf ( element ) → O(n)
Returns index of the element of the collection. If the element is not found, the method returns -1.
Parameter:
  • element (any type): an element
get ( index )
Returns element by index or throws IndexOutOfBounds exception if the index out of bounds.
Parameter:
  • index (Integer): an index
Complexity: Depends on implementation.
Defining the get method means you can use the [ ] operator for reading elements by index.
6.2.3.4. AssociativeCollection
The base class for a collection, elements of which can be accessed by key. Any object can be a key. The class defines, in additional to the Collection class, these methods:
get ( key )
Returns element by key or undefined if the key is not found.
Parameter:
  • key (Any object): a key
Complexity: Depends on implementation.
Defining the get method means you can use the [ ] operator for reading elements by key.
6.2.3.5. MutableCollection
The base class for a collection that can be modified (elements can be added or removed).
clear ( ) → O(1)
Removes all elements from the collection. Returns true if the operation was successful.
add ( element )
Adds the element to the collection. Returns true if the operation was successful.
Parameter:
  • element (any type): an element
Complexity: Depends on implementation.
delete ( element )
Removes the element from the collection. Returns true if the operation was successful.
Parameter:
  • element (any type): an element
Complexity: Depends on implementation.
6.2.3.6. List
The doubly linked list ( https://en.wikipedia.org/wiki/Doubly_linked_list ) implementation. It defined in the lib\list.goat file.
A feature of such a collection is that the addition and removal of an element to any place in the list (even in the middle) is performed in constant time, regardless of the length of the list.

Fig. 16. A linked list structure

size ( ) → O(1)
Returns size of the list, i.e. count of elements.
Example:
import "list.goat";

var list = new List();
list.push(0);
list.push(1);
list.push(2);
print(list.size()); // 3
empty ( ) → O(1)
Returns true if the list is empty.
iterator ( ) → O(1)
Creates an iterator to enumerate all elements.
contains ( element ) → O(n)
Returns true if the list contains the element.
Parameter:
  • element (any type): an element
toArray ( ) → O(n)
Returns an array contains all elements of the list.
clear ( ) → O(1)
Removes all elements from the list.
indexOf ( element ) → O(n)
Returns index of the element of the list. If the element is not found, the method returns -1.
Parameter:
  • element (any type): an element
get ( index ) → O(n)
Returns element by index or throws IndexOutOfBounds exception if the index out of bounds.
Parameter:
  • index (Integer): an index
delete ( element ) → O(n)
Removes the element from the list. Returns true if the operation was successful.
Parameter:
  • element (any type): an element
find ( element ) → O(n)
Searches for an item in the list. If found, returns a ListItem object that contains element and pointer to the previous and the next items; if not, returns null .
Parameter:
  • element (any type): an element
addFirst ( element ) → O(1)
Adds the element to the beginning of the list.
Parameter:
  • element (any type): an element
pushf ( element ) → O(1)
Synonym for addFirst .
Parameter:
  • element (any type): an element
addLast ( element ) → O(1)
Adds the element to the end of the list.
Parameter:
  • element (any type): an element
push ( element ) → O(1)
Synonym for addLast .
Parameter:
  • element (any type): an element
add ( element ) → O(1)
Synonym for addLast but always returns true .
Parameter:
  • element (any type): an element
insertBefore ( element, before ) → O(1)
Inserts the element before another. If another element is not specified, inserts the element to the end of the list.
Parameters:
  • element (any type): an element
  • before (ListItem): an item that contains an element before which the new element should be inserted
Example:
import "list.goat";

var list = new List();
list.push(0);
list.push(1);
list.push(2);
list.insertBefore('#',list.find(2));
print(list.toArray()); // [0,1,'#',2]
The item can be found previously by calling the find method or/and by moving through the item's chain.
insertAfter ( element, after ) → O(1)
Inserts the element after another. If another element is not specified, inserts the element to the beginning of the list.
Parameters:
  • element (any type): an element
  • after (ListItem): an item that contains an element after which the new element should be inserted
The item can be found previously by calling the find method or/and by moving through the item's chain.
All insert operations ( addFirst , pushf , addLast , push , insertBefore , insertAfter ) returns a ListItem object. This object can be used later as a reference for insertBefore , insertAfter , remove methods.
removeFirst ( ) → O(1)
Returns the first element from the list and removes it from the list.
popf ( ) → O(1)
Synonym for removeFirst .
removeLast ( ) → O(1)
Returns the last element from the list and removes it from the list.
pop ( ) → O(1)
Synonym for removeLast .
remove ( item ) → O(1)
Removes the item from the list.
Parameter:
  • item (ListItem): an item
The item can be found previously by calling the find method or/and by moving through the item's chain.
getFirst ( ) → O(1)
Returns the first element from the list without deleting it.
peekf ( ) → O(1)
Synonym for getFirst .
getLast ( ) → O(1)
Returns the last element from the list without deleting it.
peek ( ) → O(1)
Synonym for getLast .
6.2.3.7. Vector
The vector data structure implementation. It defined in the lib\vector.goat file.
The vector is a superstructure over an array. The vector supports all methods of the MutableCollection class, that is, it allows add and remove elements. A feature of the vector is quick access by index. In other words, vector elements are always next to each other.
size ( ) → O(1)
Returns size of the vector, i.e. count of elements.
Example:
import "vector.goat";

var vec = new Vector();
vec.push(0);
vec.push(1);
vec.push(2);
print(vec.size()); // 3
empty ( ) → O(1)
Returns true if the vector is empty.
iterator ( ) → O(1)
Creates an iterator to enumerate all elements.
contains ( element ) → O(n)
Returns true if the vector contains the element.
Parameter:
  • element (any type): an element
toArray ( ) → O(n)
Returns an array contains all elements of the vector.
clear ( ) → O(1)
Removes all elements from the vector.
indexOf ( element ) → O(n)
Returns index of the element of the vector. If the element is not found, the method returns -1.
Parameter:
  • element (any type): an element
get ( index ) → O(1)
Returns element by index or throws IndexOutOfBounds exception if the index out of bounds.
Parameter:
  • index (Integer): an index
set ( index, element ) → O(1)
Sets element by index or throws IndexOutOfBounds exception if the index out of bounds.
Parameters:
  • index (Integer): an index
  • element (any type): an element
Defining the set method means you can use the [ ] operator for writing elements by index.
delete ( element ) → O(n)
Removes the element from the vector. Returns true if the operation was successful.
Parameter:
  • element (any type): an element
addFirst ( element ) → O(n)
Adds the element to the beginning of the vector.
Parameter:
  • element (any type): an element
This is a very slow operation for vectors.
pushf ( element ) → O(1)
Synonym for addFirst .
Parameter:
  • element (any type): an element
addLast ( element ) → O(1)
Adds the element to the end of the vector.
Parameter:
  • element (any type): an element
push ( element ) → O(1)
Synonym for addLast .
Parameter:
  • element (any type): an element
add ( element ) → O(1)
Synonym for addLast but always returns true .
Parameter:
  • element (any type): an element
removeFirst ( ) → O(n)
Returns the first element from the vector and removes it from the vector.
This is a very slow operation for vectors.
popf ( ) → O(1)
Synonym for removeFirst .
removeLast ( ) → O(1)
Returns the last element from the vector and removes it from the vector.
pop ( ) → O(1)
Synonym for removeLast .
remove ( index ) → O(n)
Removes the element from the vector by the index. Returns the removed element.
Parameter:
  • index (Integer): an index
getFirst ( ) → O(1)
Returns the first element of the vector without deleting it.
peekf ( ) → O(1)
Synonym for getFirst .
getLast ( ) → O(1)
Returns the last element of the vector without deleting it.
peek ( ) → O(1)
Synonym for getLast .
6.2.3.8. Stack
The stack data structure ( https://en.wikipedia.org/wiki/Stack_(abstract_data_type) ) implementation. It defined in the lib\stack.goat file.
The stack works on a first-in-last-out basis. However, index access is also possible, that is, it is possible to read not only the first element of the stack.
size ( ) → O(1)
Returns size of the stack, i.e. count of elements.
Example:
import "stack.goat";

var stack = new Stack();
stack.push(0);
stack.push(1);
stack.push(2);
print(stack.size()); // 3
empty ( ) → O(1)
Returns true if the stack is empty.
iterator ( ) → O(1)
Creates an iterator to enumerate all elements.
contains ( element ) → O(n)
Returns true if the stack contains the element.
Parameter:
  • element (any type): an element
toArray ( ) → O(n)
Returns an array contains all elements of the stack.
clear ( ) → O(1)
Removes all elements from the stack.
indexOf ( element ) → O(n)
Returns index of the element of the stack. If the element is not found, the method returns -1.
Parameter:
  • element (any type): an element
get ( index ) → O(n)
Returns element by index or throws IndexOutOfBounds exception if the index out of bounds. The top of the stack is the first element.
Parameter:
  • index (Integer): an index
delete ( element ) → O(n)
Removes the element from the stack. Returns true if the operation was successful.
Parameter:
  • element (any type): an element
push ( element ) → O(1)
Puts the element to the top of the stack.
Parameter:
  • element (any type): an element
add ( element ) → O(1)
Puts the element to the top of the stack and returns true.
Parameter:
  • element (any type): an element
pop ( ) → O(1)
Retrieves the top element from the stack or returns undefined if the stack is empty.
peek ( ) → O(1)
Returns the top element from the stack or returns undefined if the stack is empty.
6.2.3.9. Queue
The queue data structure ( https://en.wikipedia.org/wiki/Queue_(abstract_data_type) ) implementation. It defined in the lib\queue.goat file.
The queue works on a first-in-first-out basis. However, index access is also possible, that is, it is possible to read not only the last element of the queue.
size ( ) → O(1)
Returns size of the queue, i.e. count of elements.
empty ( ) → O(1)
Returns true if the queue is empty.
iterator ( ) → O(1)
Creates an iterator to enumerate all elements.
contains ( element ) → O(n)
Returns true if the queue contains the element.
Parameter:
  • element (any type): an element
toArray ( ) → O(n)
Returns an array contains all elements of the queue.
clear ( ) → O(1)
Removes all elements from the queue.
indexOf ( element ) → O(n)
Returns index of the element of the queue. If the element is not found, the method returns -1.
Parameter:
  • element (any type): an element
get ( index ) → O(n)
Returns element by index or throws IndexOutOfBounds exception if the index out of bounds. The head element of the queue is the first element.
Parameter:
  • index (Integer): an index
delete ( element ) → O(n)
Removes the element from the queue. Returns true if the operation was successful.
Parameter:
  • element (any type): an element
push ( element ) → O(1)
Puts the element at the end of the queue.
Parameter:
  • element (any type): an element
add ( element ) → O(1)
Puts the element at the end of the queue and returns true.
Parameter:
  • element (any type): an element
pop ( ) → O(1)
Retrieves the head element from the queue or returns undefined if the queue is empty.
peek ( ) → O(1)
Returns the head element from the queue or returns undefined if the queue is empty.
6.2.3.10. Set
The set data structure ( https://en.wikipedia.org/wiki/Set_(abstract_data_type) ) implementation. It defined in the lib\set.goat file.
The set is associative structure. It can store unique values, without any order. The complexity of adding and searching operations is logarithmic (O(log(n)) - is even faster than linear.
A less costly implementation of the set is the use of a regular Goat object. However, the object does not support the counter of elements and does not allow to delete elements.
size ( ) → O(1)
Returns size of the set, i.e. count of elements.
empty ( ) → O(1)
Returns true if the set is empty.
iterator ( ) → O(1)
Creates an iterator to enumerate all elements.
contains ( element ) → O(log(n))
Returns true if the set contains the element.
Parameter:
  • element (any type): an element
toArray ( ) → O(n)
Returns an array contains all elements of the set.
clear ( ) → O(1)
Removes all elements from the set.
get ( element ) → O(log(n))
Works as the contains method.
Parameter:
  • element (any type): an element
delete ( element ) → O(log(n))
Removes the element from the set. Returns true if the operation was successful.
Parameter:
  • element (any type): an element
set ( element ) → O(log(n))
Puts the element to the set.
Parameter:
  • element (any type): an element
add ( element ) → O(log(n))
Puts the element to the set and returns true.
Parameter:
  • element (any type): an element
6.2.3.11. Map
The map data structure ( https://en.wikipedia.org/wiki/Associative_array ) implementation. It defined in the lib\map.goat file.
The map is associative structure. It composed of a collection of (key, value) pairs, such that each possible key appears at most once in the collection The complexity of adding and searching operations is logarithmic (O(log(n)).
A less costly implementation of the map is the use of a regular Goat object. However, the object does not support the counter of elements and does not allow to delete elements.
Example:
import "map.goat";

var m = new Map();

m["one"] = 1;
m["two"] = 2;
m["three"] = 3;

println(m.size());
println(m["one"]);
println(m["two"]);
println(m["three"]);
size ( ) → O(1)
Returns size of the map, i.e. count of elements.
empty ( ) → O(1)
Returns true if the map is empty.
iterator ( ) → O(1)
Creates an iterator to enumerate all keys .
You can use the operator [ ] for getting a value from a map using a key.
contains ( key ) → O(log(n))
Returns true if the map contains the key.
Parameter:
  • key (any type): a key
toArray ( ) → O(n)
Returns an array contains all elements of the map.
clear ( ) → O(1)
Removes all elements from the map.
get ( key ) → O(log(n))
Returns a value by the key.
Parameter:
  • key (any type): a key
delete ( key ) → O(log(n))
Removes a pair found by the key from the map. Returns true if the operation was successful.
Parameter:
  • key (any type): a key
set ( key, element ) → O(log(n))
Puts the element to the map.
Parameters:
  • key (any type): a key
  • element (any type): an element
add ( key, element ) → O(log(n))
Puts the element to the map and returns true.
Parameters:
  • key (any type): a key
  • element (any type): an element
6.2.4. Multithreading
6.2.4.1. Atomic
Atomic types are types that encapsulate a value whose access is guaranteed to not cause data races and can be used to synchronize memory accesses among different threads. The Atomic class is a wrapper, the value of that can be changed safely in a multi-thread script.
Example:
import "atomic.goat";

// Create an atomic object and init this with integer
var a = new Atomic(0);

// The thread that increments atomic value
var t = $$()
{
     for (var k = 0; k < 1000; k++)
     {
         a.inc();
     }
};

// Now run 10 such threads
var rr = [];
for (var k = 0; k < 10; k++)
{
     rr.push(t.run());
}

// Join each thread (wait until all them finish)
for (var r in rr)
{
     r.join();
}

println(a.get()); // output: "10000"
Methods
init ( value )
The constructor.
Parameter:
  • value (any type): an initial value
Example:
var a = new Atomic(0);
set ( value )
Sets a new value to the atomic object.
Parameter:
  • value (any type): a new value
Example:
var a = new Atomic(false);
// do some action, and then (maybe even in another thread):
a.set(true);
get ( )
Returns the current value of the atomic object.
inc ( )
Increments the current value of the atomic object, i.e. performs the ++ operator. This method works only for objects that supported increment: Integer , Real , Char and objects that redefined ++ .
dec ( )
Decrements the current value of the atomic object, i.e. performs the -- operator.
add ( summand )
Adds another value to the value of the atomic object, i.e. performs the + operator.
Parameter:
  • summand (any object): a value to add
6.2.4.2. Mutex
Mutex is primitive of synchronization. Like critical sections, it locks executing a code block by two threads at the same time. However, there is a difference: in critical section, the interpreter does not switch threads (it can be painful for some applications), mutex in contrary only suspends concurrent threads but other threads continue to execute. Suspended threads placed to queue and resume one by one as soon as thread that locks mutex released it.
Mutex is a complex wrapper around of critical section, it takes more resources, but anyway it is preferable construction if a critical block of code has more than several instructions.
Example:
import "mutex.goat";

var x = 0;
var m = new Mutex();
var k = 0;

var t = thread()
{
     var i;
     for (i = 0; i < 1000; ++i)
     {
         m.lock();
         ++x;
         m.unlock();
     }
};

var r1 = t.run();
var r2 = t.run();
var r3 = t.run();
var r4 = t.run();
var r5 = t.run();
var r6 = t.run();
var r7 = t.run();
r1.join();
r2.join();
r3.join();
r4.join();
r5.join();
r6.join();
r7.join();
println(x);
Methods
tryLock ( )
Tries to lock the mutex, returns false if the mutex is already locked by another thread, true if the mutex was locked.
lock ( )
Tries to lock the mutex. If the mutex is not locked, the method locks it and continues executing. If the mutex already locked by the current thread, the method increases the count of locks and continues executing. If the mutex already locked but by another thread, the method suspends the current thread and places it to the queue.
unlock ( )
Unlocks the mutex. The mutex can be unlocked only by the thread which locked it. If the mutex queue contains suspended threads, the method resumes the first thread taken from this queue.
6.2.5. Timer
Implementation of methods that once (after a specified time) or periodically start the execution of code in a separate thread. The classes and methods are defined in the lib\timer.goat file.
6.2.5.1. Methods
Timer.setTimer ( callback, duration )
Starts a callback in a separate thread after the specified time.
Parameters:
  • callback (Function | Thread): a callback
  • duration (Timer.Duration): a duration
Example:
import "timer.goat";

Timer.setTimer($()
{
     println("time has passed");
}, new Timer.Milliseconds(50));

println("the timer has been set");
If a function is passed as a callback parameter, it will be converted to a thread. A callback will be called immediately after the time runs out, and after current instruction executed. A callback always starts as a separate thread, that is, it will be executed simultaneously with other threads if they are not completed. If there is no active thread left, but a timer has been started, the interpreter will be in an idle state (do nothing) until the timer expires.
Timer.setInterval ( callback, period )
Starts a callback in a separate thread periodically.
Parameters:
  • callback (Function | Thread): a callback
  • period (Timer.Duration): a period
Example:
import "timer.goat";

var x = 0;

println("start");
var i = Timer.setInterval($()
{
     x++;
     println(x);
     if (x == 10)
     {
         i.stop();
         println("stop");
     }
}, new Timer.Milliseconds(100));
Returns an instance of Timer.Interval (see below). If a function is passed as a callback parameter, it will be converted to a thread. A callback always starts as a separate thread. A callback is called periodically, but it is not called if the previous thread has not yet completed. Thus, the callback is called not more often than the system can allow. The number of ticks is calculated, that is, how many times a thread has been created, also calculated the number of skips, that is, how many times a thread has not been created due to the fact that the previous thread has not yet completed. All this data is written periodically to the returned Timer.Interval object. The algorithm always tries to align the time so that the gap between the start of separated threads is the same.
6.2.5.2. Classes
Timer.Interval
The object of this type returns by the Timer.setInterval method. It has the method stop() that stops periodic code execution.
Also, it has fields periodically recorded by the timer:
  • count - the number of timer ticks, i.e. how many times a new thread has been created;
  • skipped - the number of timer skips, i.e. how many times a new thread creation has been skipped because old one has not finished yet.
Timer.Duration
Base class that defines a duration (amount of elapsed time between two events). Has the method getNanoseconds() that returns the duration converted to nanoseconds.
Timer.Seconds
Derived from Timer.Duration , determines time in seconds.
Timer.Milliseconds
Derived from Timer.Duration , determines time in milliseconds.
Timer.Microseconds
Derived from Timer.Duration , determines time in microseconds.
Timer.Nanoseconds
Derived from Timer.Duration , determines time in nanoseconds.
6.2.6. Data formats
6.2.6.1. Xml
Simple XML parser. For more info about the XML format, please visit https://en.wikipedia.org/wiki/XML .
The parser takes a string that contains the source document. If you need to parse the file, you must first read and decode it using other methods. The document is recognized as a whole, the output is a tree of XML elements. If the document contains an error, the parser throws an appropriate exception.
Classes
Xml.Element
The class that contains the data of one XML element. An XML element can contain attributes and child elements, thus, each element is the root of the element tree. The XML parser returns one root element that contains the whole document as a tree of elements.
Fields
tag
String. The element's tag. For example, after parsing the element:
<root>...</root>
the tag field will contain the value "root".
attrib
Object, contains attributes. For example, after parsing the element:
<rectangle width="300" height="200">...</rectangle>
the attrib field will contain the object {width:300,height:200} .
If the element does not have attributes, this field will contain an empty object.
data
A child element, or an array containing child elements, or null . A child element can be a string or an Xml.Element type. For example, after parsing the element:
<list><elem_1>...</elem_1>Some text between elements<elem_2>...</elem_2></list>
the data field will be contain the array:
  • item 0: Xml.Element containing "elem_1" tag and child elements;
  • item 1: string "Some text between elements";
  • item 2: Xml.Element containing "elem_2" tag and child elements.
Methods
toString ( indent )
Converts XML tree to a string.
Parameter:
  • indent (String): if specified, this indentation will be added before each child element, for better readability of the document. If not specified, a compact document will be generated without indentation.
For example, let's сreate a simple XML tree:
<root>
     <first>Data of the first element</first>
     <second/>
     <third>
         <child>Data of the child element</child>
     </third>
</root>
To do this, write the following code:
import "xml.goat";

var root = Xml.parse("<root><first>Data of the first element</first><second/><third><child>Data of the child element</child></third></root>");
Now convert the tree back into a string without indentation:
print(root.toString());
Output is:
<root><first>Data of the first element</first><second/><third><child>Data of the child element</child></third></root>
Сonvert the tree to a string again, but indented into two spaces:
print(root.toString(" "));
Output is:
<root>
   <first>Data of the first element</first>
   <second/>
   <third>
     <child>Data of the child element</child>
   </third>
</root>
Indentation can be not only spaces but also any other characters. Now let's try an indent, consisting of a vertical line and space ( | ):
print(root.toString("| "));
Output is:
<root>
| <first>Data of the first element</first>
| <second/>
| <third>
| | <child>Data of the child element</child>
| </third>
</root>
findByTag ( tag )
Returns an array contains children with the specified tag(s).
Parameter:
  • tag (String | Array): A tag or an array of tags
If no children found, returns an empty array.
findFirstByTag ( tag )
Returns the first child with the specified tag, or null if child not found.
Parameter:
  • tag (String | Array): A tag or an array of tags
Xml.Error
The class contains a description of the error that occurred in the case of parsing a non-valid document.
Consists of two fields:
type
Error type, string. The parser usually selects the type of error from the predefined set of strings:
Xml.Error.INVALID_TOKEN : "invalid token",
Xml.Error.EXPECTED_TAG_NAME : "expected tag name",
Xml.Error.UNEXPECTED_END : "unexpected end",
Xml.Error.END_TAG_MISMATCH : "end tag does not match the start tag",
Xml.Error.UNCLOSED_END_TAG : "end element was missing the character \'>\'",
Xml.Error.MISSING_EQUALS : "missing \'=\' sign between attribute and attribute value",
Xml.Error.MISSING_STRING : "a string literal was expected",
Xml.Error.DUPLICATE_ATTRIBUTE : "duplicate attribute",
Xml.Error.UNKNOWN_ENTITY : "unknown entity",
Xml.Error.INVALID_CHARACTER : "invalid character",
Xml.Error.EXPECTED_CDATA_SEQUENCE : "expected <![CDATA[ sequence",
Xml.Error.INVALID_SEQUENCE: "invalid sequence"
index
Integer, the number (index) of character on which the error occurred in the source string.
Methods
parse ( str )
Parse the string and returns an XML tree.
Parameter:
  • str (String): the source string
Example:
import "xml.goat";

var root = Xml.parse("<root><item>Data of the item</item></root>");
If XML document is not valid, throws Xml.Error exception. If valid, returns Xml.Element object contains root element.
7. Appendix
7.1. In comparison with JavaScript
The Goat programming language based in general on JavaScript syntax, but it has some differences.
Some samples are below.
7.1.1. Identifiers
JavaScript
The first character of an identifier must be a letter, or an underscore ( _ ), or a dollar sign ( $ ). Subsequent characters may be letters, digits, underscores, or dollar signs.
Goat
The first character must be a letter or an underscore ( _ ). Subsequent characters may be letters, digits or underscores.
Dollar sign used as a short replacement of function keyword:
var f = $(a, b) { };
it's the same as:
var f = function(a, b) { };
7.1.2. Keywords
The Goat programming language reserves several additional keywords:
Keyword Description
thread Declares a thread
lock Declares a critical section (this is a synchronization primitive)
import Imports a source file
debug (instead of debugger ) Stops the execution of Goat script, and switch the interpreter to debug (step-by-step) mode
7.1.3. Primitive types
JavaScript
A primitive data type is data that is not an object and has no methods. There are 6 primitive data types: string, number, boolean, null, undefined, symbol. All primitives are immutable.
Goat
There are no primitive types. All data represented as objects. Each object include undefined has some methods. There are some predefined objects which are prototypes for primitive data, such as numbers or strings: Char , String , Integer , Real , Boolean , Void , Undefined and Null .
This programming language clearly distinguishes between strings (the prototype is String ) and individual characters (the prototype is Char ), as well as integers ( Integer ) and floating-point numbers ( Real ). These types have a different set of methods and operators, but if necessary, a type can be converted to another:
var c = 'a'; // prototype of c is Char
var s = String.valueof(c); // conversion to String
All other structures, for example, functions, threads, arrays, etc have own prototypes ( Function , Thread , Array ).
7.1.4. Scope
JavaScript
There are two types of scopes: global and local. Variables defined inside a function are in the local scope. Variables defined inside of a block statement will remain in the scope they were already in. ECMAScript 6 introduced the let keyword. Contrary to the var keyword, the let keyword supports the declaration of local scope inside block statements.
var func = function()
{
     var v = 0;
     // do something...
     if (true)
     {
         let v = 1; // local declaration
     }
};
If you re-declare a JavaScript variable in the same block, it will not lose its value.
Goat
There is no global scope. You can re-declare variable with the same name in inner block statement, it will be used only in this block and its inner blocks.
var func = $()
{
     var v = 0;
     if (true)
     {
         var v = 1;
         print(v); // output: "1"
     }
     print(v); // output: "0"
};
But, if you re-declare a Goat variable in the same block, it will lose old value.
7.1.5. The 'this' keyword
JavaScript
You must use the this keyword to refer to the field of own object:
var MyClass = function()
{
     this.x = 0;
};

MyClass.prototype.getX = function()
{
     return this.x;
};
Goat
You can use the this keyword to refer to the field of own object, but you must not do it in all cases. You can skip this keyword in the methods. But in some cases, this keyword cannot be avoided, for example, if you already have a local variable or an argument with that name, but you want to explicit read or write the property of the object, or, you can add new properties to own object (which are not yet there):
var MyClass =
{
     init : $()
     {
         this.x = 0; // with 'this'
     },
    
     getX : $()
     {
         return x; // without 'this'
     }
};
7.1.6. Operators
The Goat language has no comparison operators === (equal value and equal type) and !== (not equal value or not equal type). Operators == and != works in most cases as === and !== operators in JavaScript.
The Goat language has not typeof and instanceof operators. Use instanceof method instead:
print(13.instanceof(Integer)); // output: "true"
The Goat language provides several new operators:
  • -> that means inheritance;
  • # for write protecting (after that, an object cannot be changed);
  • ?. as null conditional operator.
7.1.7. Operators overloading
JavaScript
Doesn't support.
Goat
You can use the operator as method name:
var Vector =
{
     init : $(x, y)
     {
         this.x = x; this.y = y
     },
    
     toString : $()
     {
         return "X: " + x + ", Y: " + y;
     },
    
     "+" : $(vec)
     {
         return new Vector(x + vec.x, y + vec.y);
     },
    
     "*" : $(val)
     {
         return new Vector(x * val, y * val);
     }
};

var v1 = new Vector(100, 200);
var v2 = new Vector(200, 400);

println((v1 + v2).toString()); // output: "X: 300, Y: 600"
println((v1 * 5).toString()); // output: "X: 500, Y: 1000";
7.1.8. Multithreading
JavaScript
Doesn't support. There are some workarounds, say web workers, and, of course, functions setTimeout() and setInterval() .
Goat
There is thread keyword. It possible to declare any function as a separate thread.
var t0 = thread()
{
     while(true)
     {
         print('A');
     }
};

var t1 = thread()
{
     while(true)
     {
         print('B');
     }
};

t0.run();
t1.run();

// Output: "ABABABABABABAB...."
7.1.9. The 'new' keyword and constructors
JavaScript
Constructors are like regular functions, but we use them with the new keyword. If you inherit your object and the parent has a constructor, you need to call parent constructor to perform initialization logic.
var A = function()
{
     // init something...
};

var B = function()
{
     A.apply(this);
     // init something else...
};
B.prototype = new A();
Goat
There is special method init() . If method defined, interpreter call it. If method also defined in base object, interpreter call it first (the order in which constructors are called is determined by the inheritance topology).
var A =
{
     init : $()
     {
         // init something...
     }
};

var B = A ->
{
     init : $()
     {
         // init something else...
     }
};

var obj = new B(); /* both init method will be called,
                       first from A, second from B */
7.1.10. Inheritance
JavaScript
var A = function()
{
     this.x = 0;
};

var B = function()
{
     A.apply(this);
     this.y = 1;
};
B.prototype = new A();

var C = function()
{
     B.apply(this);
     this.z = 2;
};
C.prototype = new B();
Nearly all objects in JavaScript are instances of Object , a typical object inherits properties (including methods) from Object.prototype .
Goat
The syntax is much simpler. Use operator -> :
var A =
{
     x : 0
};

var B = A ->
{
     y : 1
};

var C = B ->
{
     z : 2
};
Goat language has also has class (prototype) named Object , is the root of the class hierarchy. Any object has prototype; if it created from literal (for example, strings), or it created by new keyword, or if prototype(s) is explicitly specified when creating an object:
var A = { }; // the prototype of 'A' is 'Object'
var S = "hello"; // the prototype of 'S' is 'String'
var B = new A(); // the prototype of 'B' is 'A'
var C = B->{ }; // the prototype of 'C' is 'B'
7.1.11. Multiple inheritance
JavaScript
Is not supported. You can use some tricks (say mixins) but it is not true multiple inheritance.
Goat
Why not.
var A =
{
     x : 0
};

var B =
{
     y : 1
};

var C = [A, B] ->
{
     z : 2
};
The prototype traversal order for multiple inheritance is determined by the topological sorting of the prototype tree.
7.1.12. Syntactic sugar
7.1.12.1. Null conditional operator
JavaScript
Doesn't support. Currently, it is proposal options, it will be supported later.
Goat
Operator ?. is added. Operator ?. read a property (calls a method) only if a left object is not void, otherwise returns undefined:
var value = user?.address?.street;
7.2. Command line options and environment variables
Here is the full list of command line options.
--lib
Path (paths) to external libraries (to importable files), for example, a path to the Goat standard library. Several paths should be separated by a semicolon.
Example, for Windows:
goat.exe program.goat --lib=c:\goat\lib;c:\project
Example, for Linux:
./goat program.goat --lib=/work/goat/lib;/work/project
The search for the included file is performed in the order specified in the list. In the example above, the list contains two items:
  • c:\goat\lib
  • c:\project
Say the script contains the line:
import "xml.goat";
The interpreter first tried to open the file c:\goat\lib\xml.goat , and if it was not found, the file c:\project\xml.goat .
The current folder where the script was launched from has the highest priority; the search starts from it. If you need to include a file from a specific folder, specify the full path in the import directive:
import "project/xml.goat";
This option can be set as an environment variable GOAT_LIBRARY_PATH . Example, for Windows:
set GOAT_LIBRARY_PATH=c:\goat\lib;c:\project
goat.exe program.goat
Example, for Linux:
export GOAT_LIBRARY_PATH=/work/goat/lib;/work/project
/work/goat program.goat
If both the environment variable and the command line option are set, then the command line option is preferred. This means that both lists will be used, but first, the search will be performed in the list defined in the command line.
--language= or --lang=
Set language for compiler output messages. Supported languages are:
  • english (en) - default
  • russian (ru)
This option can be set as an environment variable GOAT_LANGUAGE .
--debug and --run
After starting, you switch to debug mode, where you can add breakpoints and execute the program line by line. This mode is described in the Step-by-step debugging section.
Example:
goat.exe program.goat --debug
This option can be set as an environment variable GOAT_DEBUG .
After starting with the --debug option, the interpreter immediately enters debug mode. You should add breakpoints, and then enter r command to run the script. However, you can pre-set breakpoints directly in the script using the debug statement. If you have such statements and if you don't want to enter r command to run the script, add --run option and the script will be executed after launching until the first debug statement:
goat.exe program.goat --debug --run
--compile
Compile the script into bytecode, but do not execute it.
Example:
goat.exe program.goat --compile
As a result, a binary file <program_name>+.bin (in this case: program.goat.bin ) will be written. The binary is compressed to save space and is unpacked at each loading. To leave the file uncompressed (speeds uploading), use option --do-not-compress :
goat.exe program.goat --compile --do-not-compress
--bin
Run a previously compiled script.
Example:
goat.exe --bin program.goat.bin
Since the compilation procedure was performed earlier, loading prepared bytecode is faster. This will reduce the overall program execution time.
--stdin
Reads the original text of the program from standard input instead of a file. This option allows, for example, to execute short programs directly from the command line:
C:\>echo for (var i in range(10)) print(i); | goat.exe --stdin
0123456789
--gc
One of the four modes of garbage collection.
  • --gc=serial enable serial mode, it means that the garbage collector periodically stops all threads (but it takes low processor resources for collection and has small memory overhead);
  • --gc=parallel does not stop threads (but it constantly uses some processor resources and also it uses some extra memory), this mode enabled by default;
  • --gc=disabled completely disables garbage collection. All memory is cleared only after the script is finished;
  • --gc=debug used for debugging purposes for interpreter developer, it calls collector after each statement of a script and this is very slow.
If you don't know what "garbage collection" means, please do not use this parameter, the parallel collector is okay for most purposes.
--heap-size=
Limit memory used by a script. The value is specified in megabytes.
Example. Limit memory usage to one megabyte:
goat.exe program.goat --heap-size=1
By default, the script uses all available RAM. Limiting memory can lead to a more frequent garbage collector operation and, as a result, to slower work. If there is not enough memory due to a large number of objects, the script will end with an error.
--dump-memory-usage-report
Write memory usage report to <program_name>+.memory.txt file.
Example:
goat.exe program.goat --dump-memory-usage-report
A possible output ( program.goat.memory.txt ):
MEMORY USAGE REPORT

heap size, bytes: 268435456
peak usage, bytes: 19240301
gc algorithm: 'serial'
count of gc launches: 834
total objects: 986649
    actually created: 96828
    reused: 889821 (90.1 %)
--dump-abstract-syntax-tree
As a first step, the compiler parses the source code of the script into tokens and generates an abstract syntax tree ( https://en.wikipedia.org/wiki/Abstract_syntax_tree ). This option dumps abstract syntax tree of tokens to <program_name>+.tokens.txt file as a graph in DOT format (see https://en.wikipedia.org/wiki/DOT_(graph_description_language) ). To visualize it, use an appropriate tool, for example, graphwiz ( http://graphviz.org ).
Example. The script:
println(2 + 3 * 4);
Command line:
goat.exe program.goat --dump-abstract-syntax-tree
dot -Tsvg program.goat.tokens.txt -o ast.svg
Result:

Fig. 17. Abstract syntax tree

--dump-parse-tree
This option dumps parse tree to <program_name>+.ptree.txt file as a graph in DOT format. Parse tree ( https://en.wikipedia.org/wiki/Parse_tree is generated from an abstract syntax tree as a second compilation step.
--dump-assembler-code
Write compiled bytecode to <program_name>+.asm file as list of assembler instructions for the virtual machine. Bytecode is generated from the parse tree as the last compilation step.
Example. The script:
println(2 + 3 * 4);
Command line:
goat.exe program.goat --dump-assembler-code
A possible output ( program.goat.asm ):
.data
   0 println

.code
     integer 4
     integer 3
     mul
     integer 2
     add
     load 0 ; println
     call 1
     pop
     end