Variables
Buzz is a dynamically typed language. This means that the type of a variable can change during the execution of a script, and it depends on the type of the value stored by a variable at any moment.
Buzz does not include the concept of constant. Every variable is always mutable.
Primitive Types
Buzz supports the following primitive types:
 integer a 32bit signed integer (e.g.,
90
)  float a 32bit floatingpoint value (e.g.,
1.0
,0.25
,.5
)  string a string of characters (e.g.,
"hello, world!"
)  table a structured type to encode various kinds of data structures (see Tables)
 closure a function pointer
 user data a pointer to a userdefined memory region managed externally to Buzz. See User Data for more information.
Scope
Buzz variables can be global or local. To declare a variable as local to a code block (e.g., a function), you need to prepend its first definition with the keyword var
:
# A local variable  by default its value is nil var x # Another local variable with initialization var i = 5 # Assignment for a local variable x = 7.8
To declare a global variable, you simply assign its value without using the var
keyword:
# A global variable definition j = 5
Control Structures
if Statement
while Statement
for Statement
Tables
Tables are the only structured type available in Buzz. Tables are quite flexible: you can use them both as a hash map or as a classical array.
To create an empty table, use this syntax:
t = {}
Internally, Buzz tables are implemented as hash maps, that is, a collection of (key, value)
pairs. While in principle you could use any Buzz primitive type as key
, the most common types are integers, floats, and strings. In this case, you can use this syntax to populate a table:
t = { .x = 1, .2 = 5.6, .4.5 = "k" }
This syntax creates a table that contains three pairs: ("x",1)
, (2,5.6)
, and (4.5,"k")
. The table is stored in variable t
.
To add new values to a table, or to set new values for existing keys (remember that in hash maps keys can't be duplicated!), use this syntax:
# If the key is an integer t[6] = "six" # If the key is a float t[1.0] = "one point zero" # If the key is a string, the following two lines are equivalent t["hello"] = "this is a greeting" t.hello = "this is a greeting"
To read the value of a table, the same syntax as above applies:
# If the key is an integer print(t[6]) # If the key is a float print(t[1.0]) # If the key is a string, the following two lines are equivalent print(t["hello"]) print(t.hello)
Finally, to erase an element from a table it is enough to set it to nil
:
t[1.0] = nil
Table contents can be handled through a number of dedicated commands.

size(t)
returns the current number of elements in table
t
:t = { .x = 4 } print(size(t)) # prints 1

foreach(t,f)
applies a function
f(key,value)
to each element of tablet
:t = { .x = 4, .y = 5, .z = 6 } foreach(t, function(key,value) { print("(", key, ", ", value, ")") }) # prints # (x, 4) # (y, 5) # (z, 6)
It is important to notice that
foreach(t,f)
is not meant to modify the values of the table. It is only meant to go through the elements oft
and use its values in a readonly fashion. If you want to modify the elements of a table, usemap(t,f).

map(t,f)
applies a function
f(key,value)
to each element of tablet
and returns a new table. For each element, functionf
must return a value, which is used to populate the new table. For instance:t = { .x = 1, .y = 2 } u = map(t, function(key,value) { return value + 100 }) # now u contains: # ("x", 101) # ("y", 102)

reduce(t,f,a)
applies a function
f(key,value,accumulator)
to each element of tablet
. Functionf
must accept three parameters: the current key, the corresponding value, and an accumulator. Functionf
must also return a value, that is passed as accumulator to the invocation off
on the next table element. Parametera
ofreduce(t,f,a)
is the initial value of the accumulator. For instance, if you want to calculate the average of the values in a table, write the following code:t = { .1 = 1.0, .2 = 2.0, 3. = 3.0 } avg = reduce(t, function(key,value,accumulator) { return value + accumulator }, 0.0) / size(t) # avg is now 2.0
Functions
Function Definition
Function Pointers
Math
Basic Math Operations
Math works similarly to most programming languages you are used to. The basic math operations, in decreasing order of precedence, are:
 Unary minus (e.g.,
5
)  Power (e.g.,
3^5
)  Modulo (e.g.,
10 % 4
)  Multiplication and division (e.g.,
2 * 3 / 4
)  Addition and subtraction (e.g.,
2 + 3  4
)
Analogously to other languages, parentheses are used to modify the natural precedence of the operators:
x = 5^(4%(3*(2+1))) # x = 5^(4%(3*3)) # x = 5^(4%9) # x = 5^4 # x = 625.0
As the above example shows, the power operator transforms its operands into float, even if the operands are both integers. The other operators return an integer if both operands are integer, and a float if either or both operands are float. A type error is raised if the operands are not integers nor floats.
The math Library
A wider set of mathematical functions is available. These functions are stored into the math
table. The math
table is set up upon initialization of the Buzz VM, so no include
statement is necessary to use it.
The math
functions work with both integer and float values. The complete list of functions is as follows:
math.abs(x)
returns the absolute value ofx
. The type of the result is the same as the type ofx
.math.log(x)
returns the natural logarithm ofx
as a float.math.log2(x)
returns the base 2 logarithm ofx
as a float.math.log10(x)
returns the base 10 logarithm ofx
as a float.math.exp(x)
returns e to the power ofx
as a float.math.sqrt(x)
returns the square root ofx
as a float.math.sin(x)
returns the sine ofx
as a float.math.cos(x)
returns the cosine ofx
as a float.math.tan(x)
returns the tangent ofx
as a float.math.asin(x)
returns the arc sine ofx
as a float.math.acos(x)
returns the arc cosine ofx
as a float.math.atan(y,x)
returns the arc tangent ofy,x
as a float.math.min(x,y)
returns the minimum betweenx
andy
. The type of the return value corresponds to the type of the minimum value:min(1.0, 2)
is1.0
, andmin(1,2.0)
is1
.math.max(x,y)
returns the maximum betweenx
andy
. The type of the return value corresponds to the type of the maximum value:max(1.0, 2)
is2
, andmax(1,2.0)
is2.0
.
In addition to these functions, the math table also includes the constant math.PI
.
The math.rng Library
The math
library also includes a collection of functions for random number generation. These functions are stored into the math.rng
table and, similarly to math
, do not require an include
statement to be used.
The random number generator is based on the wellknown Mersenne Twister algorithm.
Setting the Seed
Upon initialization, the Buzz VM sets a random seed taken from the current clock. If you wish to set the random seed explicitly to a value s
, use the function math.rng.setseed(s)
. The value of s
must be an integer, or a type error is raised.
Uniform Distribution
To draw numbers from a uniform distribution, use math.rng.uniform(...)
. The behavior of this function depends on the number and type of parameters passed.
math.rng.uniform()
returns an integer between $2^{32}$ and $+2^{31}1$.math.rng.uniform(x)
returns a value between 0 andx
. The type of the returned value matches the type ofx
.math.rng.uniform(x,y)
returns a value betweenx
andy
. If bothx
andy
are integers, the returned value is an integer; if either or both are floats, the returned value is a float.
Gaussian Distribution
To draw numbers from a Gaussian distribution, use math.rng.gaussian(...)
. The behavior of this function depends on the number and type of parameters passed.
math.rng.gaussian()
returns a float from a Gaussian with 0 mean and standard deviation 1.math.rng.gaussian(x)
returns a float from a Gaussian with 0 mean and standard deviationx
.math.rng.gaussian(x,y)
returns a float from a Gaussian with meany
and standard deviationx
.
Exponential Distribution
To draw numbers from an exponential distribution, use math.rng.exponential(x)
, where x
is the mean. The returned value is a float.
The math.vec2 library
When dealing with the robots, it is often useful to manipulate vectors. Buzz offers a library to handle 2D vectors. The library is stored in INSTALL_PREFIX/ share/buzz/include/vec2.bzz
, so to use it a script must first include it. The complete reference of these functions is included in the file.
Strings
Builtin String Operations
string.length(s)
returns the length of strings
string.sub(s,...)
returns a substring of the given string. Two signatures are possible:string.sub(s,n)
returns the substring starting at charactern
(0
is the first character);string.sub(s,n,m)
returns the substring starting at charactern
and ending atm
.string.concat(s1,s2,...)
returns a new string that is the concatenation of the given strings.string.tostring(o)
transforms objecto
into a new string.string.toint(x)
converts a string into an integer. If the conversion fails, this function returnsnil
.string.tofloat(x)
converts a string into a float. If the conversion fails, this function returnsnil
.
Additional String Operations
A number of additional string operations is available as a library that must be included. The library is stored in INSTALL_PREFIX/share/buzz/include/ string.bzz
, so to use it a script must first include it. The complete reference of these functions is included in the file.
String Implementation in Buzz
The Buzz VM maintains a data structure that stores every string that was ever encountered during the execution of a script. Each string is associated with a unique identifier, which is simply a counter of strings created so far. Every time a string is used in a script, only the identifier is used. The actual value of the string is stored only once in the data structure. To make string lookup operations fast, strings are stored in binary tree ordered by identifier.
String manipulation often creates large numbers of intermediate strings, which are used only once over the lifetime of a script. To save memory, the Buzz VM internally distinguishes between protected and nonprotected strings—protected strings are stored permanently, while nonprotected strings are erased during garbage collection if no script variable refers to them. Examples of protected strings are function names, constant names, and other strings that are produced during compilation. Strings that result from manipulation with the string operations are typically nonprotected.
When strings are communicated between robots, they must be serialized. It is not possible to force the string indentifiers to be the same across different robots. This is because (in general) different robots might execute different parts of a script, and strings might be created in different order. Therefore, when two robots exchange strings, the full value of the string must be communicated, rather then their identifier.
Files
To handle files, Buzz offers a number of builtin functions collected in the io
table.

f = io.fopen(path,mode)
opens a file located atpath
. Parametermode
encodes how the file is opened:
"r"
opens the file readonly; 
"w"
opens the file writeonly and truncates the file; 
"a"
opens the file writeonly for appending data; 
"w+"
opens the file for both reading and writing, and truncates the file; 
"a+"
opens the file for both reading and writing, for appending.
This function returns
nil
in case of error, and a table in case of success. The table contains the methods listed in the following. 

f.fclose()
closes filef
. 
f.size()
returns the size of filef
. 
f.fforeach(fun)
executes functionfun
for each line of filef
. 
f.fwrite(s1, s2, ...)
writes the concatenation of stringss1
,s2
, … into filef
.