Type System
The types
Bosscript has the following types built into the language:
broj
- numberstekst
- stringslogicki
/logički
- booleansobjekat
- objectsniz
- arraysbajt
- byteBajtNiz
- ByteArrayfunkcija
- functionsnedefinisano
- null and undefinedReadonlyObject
- an extension ofobjekat
used only internally
Broj
The broj
type represents all numbers, both integers and floating-point numbers. It is the equivalent of the number
type in JavaScript. The maximum value a broj
holds is 3.4028235 * 1038. Under the hood, it uses the double
type from the JVM. Below are some examples:
var x = 10; var y = 1.234; var z = 0;
broj
also supports adding underscores as separators, for readability purposes:
var x = 1_000_000 // valid, holds 1000000 (one million) var z = 1_00_00_00 // bad readability, but still valid, holds 1000000 (one million)
The separators can be placed however the user likes - the Bosscript lexer just ignores them when handling numeric literals. However, we do recommend using them consistently and in a way that is readable.
All commonly used operators are supported by broj
, including +
, -
, *
, /
, and %
. There is also the ^
operator,
which is used for exponentiation:
ispis(5^3); // prints 125
Tekst
The tekst
type represents strings. It is a direct equivalent of the String
type from the JVM. The only difference
between Bosscript’s tekst
and most other string representations in other programming languages is the delimiter. The only
valid delimiter for tekst
are double quotes. Single quotes are not allowed:
var name = "Bosscript"; var version = '1.0';
Other than that, tekst
behaves exactly the same as other string implementations. It comes with various utility methods
built in. Read more about them in the tekst api page
Logički
The logički
/ logicki
type represents booleans. Both spellings are supported and treated equally by the interpreter,
as is the case for all keywords with bosnian-specific letters. It is built on top of JVM Boolean
and behaves exactly
the same. The only difference is the literals themselves, which are Bosnian words:
var t1 = tačno; var t2 = tacno; var nt1 = netačno; var nt2 = netacno;
As you can see, even the literals support spelling with or without the letter č. All four variable declarations are valid.
The type has no built-in methods itself.
Objekat
The objekat
type is very similar to JavaScript objects. It is a collection of related data, which is stored as key-value
pairs. Under the hood, it is implemented as a HashMap
. The keys of an objekat
are identifiers, while the value can be
of any type supported by Bosscript. Consider the following example:
var empty = {}; var obj = { a: "a", b: 1, c: tacno, d: [1, 2], e: { isNested: tacno, prop: "prop" }, f: funkcija(){ ispis("fn"); } }
The obj
object holds data of various types. To access any of the properties, use the dot syntax:
ispis(obj.b); // prints 1
Trying to access a property that doesn’t exist will result in an error:
obj.rand;
Property 'rand' does not exist on object {a: "a", b: 1, ...}
Properties can also be accessed with the bracket indexing operator, where the property is referenced as a string literal:
obj["c"] // evaluates to tačno
Trying to access a property that doesn’t exist with the bracket operator also results in an error:
obj["rand"]
However, it is possible to assign to properties that don’t already exist:
obj.notDefinedYet = "NOW DEFINED"; obj["notDefined"] = "NOW DEFINED TOO";
Both expressions above are valid and will create new properties on the obj
object.
An object property can also be a function. We see that obj.f
is a function expression. Here is how to use it:
obj.f(); // prints 'fn' to the console
When defining an object function, you can reference other object properties within the function, via @
:
var o = { name: "Bosscript", greet: funkcija(){ ispis("Hello, my name is " + @name); } } o.greet(); // Prints 'Hello, my name is Bosscript' to the console
The @
symbol is a reference to the object itself. It is the equivalent of the this
keyword in most programming languages.
Using @
, you can access any object property within object functions. You cannot use @
outside of object methods. Consider
this example:
var o = { x: 1, y: 5, z: @x + @y }
Code like the example above will cause an error @ does not exist.
. So, only use @
in functions.
Note: @
is also used in models. Read more here.
Niz
The niz
type represents arrays. It behaves similarly to JavaScript’s array
or Kotlin’s ArrayList
, which it uses under the hood.
In Bosscript, an array is dynamic, meaning it can hold data of different data types at once. An array literal is written
as a comma separated list of values between brackets. Consider the following example:
var empty = []; var a = [1, 2, 3, 4, 5]; var b = [1, "2", 3, "4", tačno]; var c = [1, [2, [3, 4]], 5];
All four declarations above are valid, and they demonstrate the flexibility of niz
.
A niz
is indexable using the bracket indexing operator, just like arrays in most programming languages:
var arr = ["A", "B", "C"]; ispis(arr[0]); // prints 'A'
Indexes are 0-based, like in most other programming languages.
There are two ways to loop over a niz
, either manually, or with the zaSvaki
property, which is built into niz
:
var arr = ["A", "B", "C"]; za svako (i od 0 do arr.zadnji()){ ispis(arr[i]); } // prints A B C to the console
var arr = ["A", "B", "C"]; arr.zaSvaki(ispis); // also prints A B C to the console
niz
has many more built in properties like zaSvaki
, which you can read more about here.
Bajt and BajtNiz
A bajt
represents a byte, while BajtNiz
is just an array of bytes. Bosscript v1.0 doesn’t support any byte literals.
Instead, bajt
is only used within BajtNiz
, which itself is only used for input and output stream objects. You will only
encounter BajtNiz
when working with the telnet
standard library package.
BajtNiz
has built in functionality, which you can read more about here.
Funkcija
A funkcija
represents a function. Just like in JavaScript and some other languages, a function can be passed around as
an argument. Refering back to the zaSvaki
example from before,
var arr = ["A", "B", "C"]; arr.zaSvaki(ispis); // also prints 'A B C' to the console
we can see that ispis
is being passed as an argument to the zaSvaki
function. It is also possible to build anonymous
lambda functions in-place in situations like this:
var arr = ["A", "B", "C"]; arr.zaSvaki(funkcija(str){ ispis(str.malimSlovima()); }); // prints 'a b c' to the console
To learn more about functions, refer to the functions article. It goes into depth on how functions work in Bosscript. This section was just an overview of functions as a type.
Nedefinisano
The nedefinisano
type is a special type which represents null
and undefined
. More precisely, Bosscript doesn’t distinguish
between null
and undefined
in the way that Javascript does. Nedefinisano
covers both. The word nedefinisano itself
is a translation of undefined, and it was chosen because the Bosnian language doesn’t have an appropriate word for null
.
nedefinisano
can be used to initialize variables, but there is no need, since not providing any initial value does exactly that:
var nd = nedefinisano; var x; ispis(nd); ispis(x); // prints nedefinisano twice
It doesn’t have any built-in functionality and attempting to access a property of a nedefinisano
variable will result in
an error:
var str = getValueOrNull() ispis(str); // prints nedefinisano str.malimSlovima(); // ^---------------------- Cannot read property malimSlovima of nedefinisano
ReadonlyObject
The ReadonlyObject
is a type that is only used internally. It is an extension of the objekat
type, with the only difference being
the fact that its properties cannot be changed. Since many of the standard library packages provide objects, a special type
was built to make sure the user doesn’t reassign any of their properties accidentally. Below is an example:
var klijent = TelnetKlijent(); klijent.ulazniTok = netačno;
Error: ulazniTok is readonly!
Other than that, you will not notice any difference when working with ReadonlyObject
, when compared to regular objekat
.
Even printing its typename will yield “objekat”.
Typing
You will not need to think a lot about types when working with small Bosscript programs. Variables are fully dynamic. You will need to consider types in the context of functions, type definitions (which are used for quick user-defined types), and models. Find out more in the respective articles.