<commit_before>#+TITLE: Buzz Language Reference
#+OPTIONS: H:3

#+LATEX_HEADER_EXTRA: \lstdefinelanguage{buzz}{
#+LATEX_HEADER_EXTRA:   keywords={unit, int, real, type, append, signal, let, in, if, while, map, reduce, filter, lift, smap, sreduce, sfilter, neighbors},
#+LATEX_HEADER_EXTRA:   otherkeywords={., \{, \}, (, ), [, ], \\, \:, ->, |},
#+LATEX_HEADER_EXTRA:   sensitive=true,
#+LATEX_HEADER_EXTRA:   comment=[l]\#,
#+LATEX_HEADER_EXTRA:   string=[b]",
#+LATEX_HEADER_EXTRA:   morestring=[b]',
#+LATEX_HEADER_EXTRA:   basicstyle=\ttfamily\scriptsize,
#+LATEX_HEADER_EXTRA:   keywordstyle=\color{black}\bfseries,
#+LATEX_HEADER_EXTRA:   identifierstyle=\color{black},
#+LATEX_HEADER_EXTRA:   commentstyle=\color{black!55}\itshape,
#+LATEX_HEADER_EXTRA:   showstringspaces=false
#+LATEX_HEADER_EXTRA: }
#+LATEX_HEADER_EXTRA: \lstset{frame=single}
#+LATEX_HEADER_EXTRA: \newcommand{\bzz}{\lstinline[language=buzz,basicstyle=\ttfamily\normalsize]}

* Variables
  :PROPERTIES:
  :CUSTOM_ID: variables
  :END:
  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
   :PROPERTIES:
   :CUSTOM_ID: primtypes
   :END:
   Buzz supports the following primitive types:
   - ~nil~ :: encodes an unknown value for a variable, or a ~false~
        [[#contrstruct][condition]]
   - integer :: a 32-bit signed integer (e.g., ~90~)
   - float :: a 32-bit floating-point value (e.g., ~1.0~, ~0.25~,
        ~.5~)
   - string :: a [[#strings][string]] of characters (e.g., ~"hello,
        world!"~)
   - table :: a structured type to encode various kinds of data
        structures (see [[#tables][Tables]])
   - closure :: a [[#funpoint][function pointer]]
   - user data :: a pointer to a user-defined memory region managed
        externally to Buzz. See [[#userdata][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 [[#functions][function]]), you
  need to prepend its first definition with the keyword ~var~:
  #+BEGIN_SRC buzz
  # 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
  #+END_SRC
  To declare a /global/ variable, you simply assign its value without
  using the ~var~ keyword:
  #+BEGIN_SRC buzz
  # A global variable definition
  j = 5
  #+END_SRC

* Control Structures
  :PROPERTIES:
  :CUSTOM_ID: contrstruct
  :END:

** ~if~ Statement
   :PROPERTIES:
   :CUSTOM_ID: if
   :END:

** ~while~ Statement
   :PROPERTIES:
   :CUSTOM_ID: while
   :END:

** ~for~ Statement
   :PROPERTIES:
   :CUSTOM_ID: for
   :END:

* Tables
  :PROPERTIES:
  :CUSTOM_ID: tables
  :END:
  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:
  #+BEGIN_SRC buzz
  t = {}
  #+END_SRC

  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:
  #+BEGIN_SRC buzz
  t = { .x = 1, .2 = 5.6, .4.5 = "k" }
  #+END_SRC
  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:
  #+BEGIN_SRC buzz
  # 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"
  #+END_SRC

  To read the value of a table, the same syntax as above applies:
  #+BEGIN_SRC buzz
  # 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)
  #+END_SRC

  Finally, to erase an element from a table it is enough to set it to
  ~nil~:
  #+BEGIN_SRC buzz
  t[1.0] = nil
  #+END_SRC

  Table contents can be handled through a number of dedicated
  commands.

  - ~size(t)~ :: returns the current number of elements in table ~t~:
       #+BEGIN_SRC buzz
       t = { .x = 4 }
       print(size(t)) # prints 1
       #+END_SRC
  - ~foreach(t,f)~ :: applies a function ~f(key,value)~ to each
       element of table ~t~:
       #+BEGIN_SRC buzz
       t = { .x = 4, .y = 5, .z = 6 }
       foreach(t,
         function(key,value) {
           print("(", key, ", ", value, ")")
         })
       # prints
       #   (x, 4)
       #   (y, 5)
       #   (z, 6)
       #+END_SRC
       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 of ~t~ and use its values in a read-only
       fashion. If you want to modify the elements of a table, use
       ~map(t,f).~
  - ~map(t,f)~ :: applies a function ~f(key,value)~ to each element
       of table ~t~ and returns a new table. For each element,
       function ~f~ must return a value, which is used to populate
       the new table. For instance:
       #+BEGIN_SRC buzz
       t = { .x = 1, .y = 2 }
       u = map(t,
             function(key,value) {
               return value + 100
             })
       # now u contains:
       #   ("x", 101)
       #   ("y", 102)
       #+END_SRC
  - ~reduce(t,f,a)~ :: applies a function ~f(key,value,accumulator)~
       to each element of table ~t~. Function ~f~ must accept three
       parameters: the current key, the corresponding value, and an
       accumulator. Function ~f~ must also return a value, that is
       passed as accumulator to the invocation of ~f~ on the next
       table element. Parameter ~a~ of ~reduce(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:
       #+BEGIN_SRC buzz
       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
       #+END_SRC

* Functions
  :PROPERTIES:
  :CUSTOM_ID: functions
  :END:

** Function Definition
   :PROPERTIES:
   :CUSTOM_ID: fundef
   :END:

** Function Pointers
   :PROPERTIES:
   :CUSTOM_ID: funpoint
   :END:

* Math
  :PROPERTIES:
  :CUSTOM_ID: math
  :END:
** Basic Math Operations
   Math works similarly to most programming languages you are used
   to. The basic math operations, in decreasing order of precedence,
   are:
   1. Unary minus (e.g., ~-5~)
   2. Power (e.g., ~3^5~)
   3. Modulo (e.g., ~10 % 4~)
   4. Multiplication and division (e.g., ~2 * 3 / 4~)
   5. Addition and subtraction (e.g., ~2 + 3 - 4~)
   Analogously to other languages, parentheses are used to modify the
   natural precedence of the operators:
   #+BEGIN_SRC buzz
   x = 5^(4%(3*(2+1)))
   # x = 5^(4%(3*3))
   # x = 5^(4%9)
   # x = 5^4
   # x = 625.0
   #+END_SRC
   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 of ~x~. The type of the
     result is the same as the type of ~x~.
   - ~math.log(x)~ returns the natural logarithm of ~x~ as a float.
   - ~math.log2(x)~ returns the base 2 logarithm of ~x~ as a float.
   - ~math.log10(x)~ returns the base 10 logarithm of ~x~ as a float.
   - ~math.exp(x)~ returns _e_ to the power of ~x~ as a float.
   - ~math.sqrt(x)~ returns the square root of ~x~ as a float.
   - ~math.sin(x)~ returns the sine of ~x~ as a float.
   - ~math.cos(x)~ returns the cosine of ~x~ as a float.
   - ~math.tan(x)~ returns the tangent of ~x~ as a float.
   - ~math.asin(x)~ returns the arc sine of ~x~ as a float.
   - ~math.acos(x)~ returns the arc cosine of ~x~ as a float.
   - ~math.atan2(y,x)~ returns the arc tangent of ~y,x~ as a float.
   - ~math.min(x,y)~ returns the minimum between ~x~ and ~y~. The
     type of the return value corresponds to the type of the minimum
     value: ~min(1.0, 2)~ is ~1.0~, and ~min(1,2.0)~ is ~1~.
   - ~math.max(x,y)~ returns the maximum between ~x~ and ~y~. The
     type of the return value corresponds to the type of the maximum
     value: ~max(1.0, 2)~ is ~2~, and ~max(1,2.0)~ is ~2.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 well-known 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 and ~x~. The
         type of the returned value matches the type of ~x~.
    - ~math.rng.uniform(x,y)~ :: returns a value between ~x~ and
         ~y~. If both ~x~ and ~y~ 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 deviation ~x~.
    - ~math.rng.gaussian(x,y)~ :: returns a float from a Gaussian with
         mean ~y~ and standard deviation ~x~.

*** 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
  :PROPERTIES:
  :CUSTOM_ID: strings
  :END:
** Built-in String Operations
   - ~string.length(s)~ returns the length of string ~s~
   - ~string.sub(s,...)~ returns a substring of the given string. Two
     signatures are possible: ~string.sub(s,n)~ returns the substring
     starting at character ~n~ (~0~ is the first character);
     ~string.sub(s,n,m)~ returns the substring starting at character
     ~n~ and ending at ~m~.
   - ~string.concat(s1,s2,...)~ returns a new string that is the
     concatenation of the given strings.
   - ~string.tostring(o)~ transforms object ~o~ into a new string.
   - ~string.toint(x)~ converts a string into an integer. If the
     conversion fails, this function returns ~nil~.
   - ~string.tofloat(x)~ converts a string into a float. If the
     conversion fails, this function returns ~nil~.

** 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 /non-protected/ strings---protected strings are
   stored permanently, while non-protected 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
   non-protected.

   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
  :PROPERTIES:
  :CUSTOM_ID: files
  :END:
  To handle files, Buzz offers a number of built-in functions
  collected in the ~io~ table.
  - ~f = io.fopen(path,mode)~ opens a file located at ~path~. Parameter
    ~mode~ encodes how the file is opened:
    - ~"r"~ opens the file read-only;
    - ~"w"~ opens the file write-only and truncates the file;
    - ~"a"~ opens the file write-only 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 file ~f~.
  - ~f.size()~ returns the size of file ~f~.
  - ~f.fforeach(fun)~ executes function ~fun~ for each line of file ~f~.
  - ~f.fwrite(s1, s2, ...)~ writes the concatenation of strings ~s1~,<commit_msg>More work on the API<commit_after>#+TITLE: Buzz Language Reference
#+OPTIONS: H:3

#+LATEX_HEADER: \usepackage[margin=2cm]{geometry}
#+LATEX_HEADER_EXTRA: \lstdefinelanguage{buzz}{
#+LATEX_HEADER_EXTRA:   keywords={unit, int, real, type, append, signal, let, in, if, while, map, reduce, filter, lift, smap, sreduce, sfilter, neighbors},
#+LATEX_HEADER_EXTRA:   otherkeywords={., \{, \}, (, ), [, ], \\, \:, ->, |},
#+LATEX_HEADER_EXTRA:   sensitive=true,
#+LATEX_HEADER_EXTRA:   comment=[l]\#,
#+LATEX_HEADER_EXTRA:   string=[b]",
#+LATEX_HEADER_EXTRA:   morestring=[b]',
#+LATEX_HEADER_EXTRA:   basicstyle=\ttfamily\scriptsize,
#+LATEX_HEADER_EXTRA:   keywordstyle=\color{black}\bfseries,
#+LATEX_HEADER_EXTRA:   identifierstyle=\color{black},
#+LATEX_HEADER_EXTRA:   commentstyle=\color{black!55}\itshape,
#+LATEX_HEADER_EXTRA:   showstringspaces=false
#+LATEX_HEADER_EXTRA: }
#+LATEX_HEADER_EXTRA: \lstset{frame=single}
#+LATEX_HEADER_EXTRA: \newcommand{\bzz}{\lstinline[language=buzz,basicstyle=\ttfamily\normalsize]}

* Variables
  :PROPERTIES:
  :CUSTOM_ID: variables
  :END:
  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
   :PROPERTIES:
   :CUSTOM_ID: primtypes
   :END:
   Buzz supports the following primitive types:
   - ~nil~ :: encodes an unknown value for a variable, or a ~false~
        [[#contrstruct][condition]]
   - integer :: a 32-bit signed integer (e.g., ~90~)
   - float :: a 32-bit floating-point value (e.g., ~1.0~, ~0.25~,
        ~.5~)
   - string :: a [[#strings][string]] of characters (e.g., ~"hello,
        world!"~)
   - table :: a structured type to encode various kinds of data
        structures (see [[#tables][Tables]])
   - closure :: a [[#funpoint][function pointer]]
   - user data :: a pointer to a user-defined memory region managed
        externally to Buzz. See [[#userdata][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 [[#functions][function]]), you
  need to prepend its first definition with the keyword ~var~:
  #+BEGIN_SRC buzz
  # 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
  #+END_SRC
  To declare a /global/ variable, you simply assign its value without
  using the ~var~ keyword:
  #+BEGIN_SRC buzz
  # A global variable definition
  j = 5
  #+END_SRC

* Control Structures
  :PROPERTIES:
  :CUSTOM_ID: contrstruct
  :END:

** ~if~ Statement
   :PROPERTIES:
   :CUSTOM_ID: if
   :END:

** ~while~ Statement
   :PROPERTIES:
   :CUSTOM_ID: while
   :END:

** ~for~ Statement
   :PROPERTIES:
   :CUSTOM_ID: for
   :END:

* Tables
  :PROPERTIES:
  :CUSTOM_ID: tables
  :END:
  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:
  #+BEGIN_SRC buzz
  t = {}
  #+END_SRC

  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:
  #+BEGIN_SRC buzz
  t = { .x = 1, .2 = 5.6, .4.5 = "k" }
  #+END_SRC
  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:
  #+BEGIN_SRC buzz
  # 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"
  #+END_SRC

  To read the value of a table, the same syntax as above applies:
  #+BEGIN_SRC buzz
  # 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)
  #+END_SRC

  Finally, to erase an element from a table it is enough to set it to
  ~nil~:
  #+BEGIN_SRC buzz
  t[1.0] = nil
  #+END_SRC

  Table contents can be handled through a number of dedicated
  commands.

  - ~size(t)~ :: returns the current number of elements in table ~t~:
       #+BEGIN_SRC buzz
       t = { .x = 4 }
       print(size(t)) # prints 1
       #+END_SRC
  - ~foreach(t,f)~ :: applies a function ~f(key,value)~ to each
       element of table ~t~:
       #+BEGIN_SRC buzz
       t = { .x = 4, .y = 5, .z = 6 }
       foreach(t,
         function(key,value) {
           print("(", key, ", ", value, ")")
         })
       # prints
       #   (x, 4)
       #   (y, 5)
       #   (z, 6)
       #+END_SRC
       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 of ~t~ and use its values in a read-only
       fashion. If you want to modify the elements of a table, use
       ~map(t,f).~
  - ~map(t,f)~ :: applies a function ~f(key,value)~ to each element
       of table ~t~ and returns a new table. For each element,
       function ~f~ must return a value, which is used to populate
       the new table. For instance:
       #+BEGIN_SRC buzz
       t = { .x = 1, .y = 2 }
       u = map(t,
             function(key,value) {
               return value + 100
             })
       # now u contains:
       #   ("x", 101)
       #   ("y", 102)
       #+END_SRC
  - ~reduce(t,f,a)~ :: applies a function ~f(key,value,accumulator)~
       to each element of table ~t~. Function ~f~ must accept three
       parameters: the current key, the corresponding value, and an
       accumulator. Function ~f~ must also return a value, that is
       passed as accumulator to the invocation of ~f~ on the next
       table element. Parameter ~a~ of ~reduce(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:
       #+BEGIN_SRC buzz
       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
       #+END_SRC

* Functions
  :PROPERTIES:
  :CUSTOM_ID: functions
  :END:

** Defining and Calling Functions
   :PROPERTIES:
   :CUSTOM_ID: fundef
   :END:
To define and call functions in Buzz, use this syntax:
#+begin_src buzz
  # Function definition
  function myadd(x,y) {
    return x + y
  }


  # Function call: z = 1 + 2 = 3
  z = myadd(1,2)
#+end_src

Functions that do not return an explicit value implicitly return ~nil~:
#+begin_src buzz
  function myvoidfunction(x,y) {
    log(x + y)
  }

  # Function call ignoring return value
  # Prints 3
  myvoidfunction(1,2)

  # Function call assigning return value
  # Prints 3
  # z is nil after the call
  z = myvoidfunction(1,2)
#+end_src

Function definitions can be nested:
#+begin_src buzz
  # Outer definition
  function myouter(x) {
    # Inner definition
    function myinner(y) {
      return x + y
    }
    # Call the internally defined function
    return myinner(2)
  }

  # Function call: z = 1 + 2 = 3
  z = myouter(1)
#+end_src

** Function Pointers
   :PROPERTIES:
   :CUSTOM_ID: funpoint
   :END:
Buzz supports function pointers. This means that you can define anonymous
functions and pass them as arguments or assign to variables. To define a
function pointer, use this syntax:
#+begin_src buzz
  # Function definition
  myadd = function(x, y) {
    return x + y
  }

  # Function call: z =  1 + 2 = 3
  z = myadd(1,2)
#+end_src

For all effects and purposes, this is identical to the definition we saw
above:
#+begin_src buzz
  function myadd(x,y) {
    return x + y
  }
#+end_src

Using function pointers allows you pass functions as parameters to higher-level functions:
#+begin_src buzz
  # Some table...
  t = { ... }

  # Print all the table elements
  foreach(t, function(k,v) { log("k=",k,"; v=",v) })
#+end_src

You can mix inner function definition with function pointers:
#+begin_src buzz
# Function definition
function myouter(x) {
  return function(y) {
    return x + y
  }
}

# Function call
f = myouter(1)

# Using the returned function
# z = 1 + 2 = 3
z = f(2)
#+end_src
In the above example, the statement ~myouter(1)~ creates a function in which
 parameter ~x~ of ~myouter(x)~ is bound to 1. This means that the returned function
 sums 1 to the parameter given to it.

** Namespaces
Using tables and function pointers, it is possible to define namespaces. This is
used extensively in the core libraries, such as ~string~ and ~math~. A namespace is
nothing but a table:
#+begin_src buzz
  # Define the namespace
  mynamespace = {}

  # Define a constant
  mynamespace.CONST = 3.14

  # Define a function
  mynamespace.myadd = function(x,y) {
    return x + y
  }

  # Use the namespace
  log(mynamespace.CONST)
  z = mynamespace.myadd(1, 2)
#+end_src

** Classes and methods
:PROPERTIES:
:CUSTOM_ID: classes
:END:
By using tables and function pointers it is also possible to define classes and
methods. In Buzz, the syntax to define namespaces and classes is, effectively,
the same, and internally the virtual machine does not distinguish between these
two scenarios.

However, when a function is meant to be interpreted as a class method, the
keyword ~this~ becomes important. The ~this~ keyword is interpreted upon
function call as shown in this example:
#+begin_src buzz
  # Function definition
  function myfunction() {
    log(this)
  }

  # Using the function standalone
  # Prints nil
  myfunction()

  # Using the function within a table
  t = {}
  t.f = myfunction
  # Prints [table with 1 element]
  t.f()
#+end_src
In other words, the keyword ~this~ points to the context in which the function is
called. When the function is called standalone, there is no context and ~this~ is
~nil~. When a function is called from a table, the ~this~ keyword points to the
table.

Using the ~this~ keyword, you can write methods that access class attributes:
#+begin_src buzz
  # Class definition
  myclass = {
    .myattribute = 1

    .mymethod = function(x) {
      return x + this.myattribute
    }
  }

  # Method call: z = 1 + 2 = 3
  z = myclass.mymethod(2)
#+end_src

You can make full-fledged classes with constructors as follows:
#+begin_src buzz
  # Class definition
  myclass = {

    # Class constructor
    .new = function(x) {
      # Return a new table
      return {
        # Bind the attribute values
        .myattribute = x
        # Bind the methods
        .mymethod = mymethod
      }
    }

    # Method definition
    .mymethod = function(x) {
      return this.myattribute + x
    }
  }

  # Usage
  # Create the object
  myobject = myclass.new(1)
  # Call the method: z = 1 + 2 = 3
  z = myobject.mymethod(2)
#+end_src

* Math
  :PROPERTIES:
  :CUSTOM_ID: math
  :END:
** Basic Math Operations
   Math works similarly to most programming languages you are used
   to. The basic math operations, in decreasing order of precedence,
   are:
   1. Unary minus (e.g., ~-5~)
   2. Power (e.g., ~3^5~)
   3. Modulo (e.g., ~10 % 4~)
   4. Multiplication and division (e.g., ~2 * 3 / 4~)
   5. Addition and subtraction (e.g., ~2 + 3 - 4~)
   Analogously to other languages, parentheses are used to modify the
   natural precedence of the operators:
   #+BEGIN_SRC buzz
   x = 5^(4%(3*(2+1)))
   # x = 5^(4%(3*3))
   # x = 5^(4%9)
   # x = 5^4
   # x = 625.0
   #+END_SRC
   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 of ~x~. The type of the
     result is the same as the type of ~x~.
   - ~math.log(x)~ returns the natural logarithm of ~x~ as a float.
   - ~math.log2(x)~ returns the base 2 logarithm of ~x~ as a float.
   - ~math.log10(x)~ returns the base 10 logarithm of ~x~ as a float.
   - ~math.exp(x)~ returns _e_ to the power of ~x~ as a float.
   - ~math.sqrt(x)~ returns the square root of ~x~ as a float.
   - ~math.sin(x)~ returns the sine of ~x~ as a float.
   - ~math.cos(x)~ returns the cosine of ~x~ as a float.
   - ~math.tan(x)~ returns the tangent of ~x~ as a float.
   - ~math.asin(x)~ returns the arc sine of ~x~ as a float.
   - ~math.acos(x)~ returns the arc cosine of ~x~ as a float.
   - ~math.atan2(y,x)~ returns the arc tangent of ~y,x~ as a float.
   - ~math.min(x,y)~ returns the minimum between ~x~ and ~y~. The
     type of the return value corresponds to the type of the minimum
     value: ~min(1.0, 2)~ is ~1.0~, and ~min(1,2.0)~ is ~1~.
   - ~math.max(x,y)~ returns the maximum between ~x~ and ~y~. The
     type of the return value corresponds to the type of the maximum
     value: ~max(1.0, 2)~ is ~2~, and ~max(1,2.0)~ is ~2.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 well-known 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 and ~x~. The
         type of the returned value matches the type of ~x~.
    - ~math.rng.uniform(x,y)~ :: returns a value between ~x~ and
         ~y~. If both ~x~ and ~y~ 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 deviation ~x~.
    - ~math.rng.gaussian(x,y)~ :: returns a float from a Gaussian with
         mean ~y~ and standard deviation ~x~.

*** 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
  :PROPERTIES:
  :CUSTOM_ID: strings
  :END:
** Built-in String Operations
   - ~string.length(s)~ returns the length of string ~s~
   - ~string.sub(s,...)~ returns a substring of the given string. Two
     signatures are possible: ~string.sub(s,n)~ returns the substring
     starting at character ~n~ (~0~ is the first character);
     ~string.sub(s,n,m)~ returns the substring starting at character
     ~n~ and ending at ~m~.
   - ~string.concat(s1,s2,...)~ returns a new string that is the
     concatenation of the given strings.
   - ~string.tostring(o)~ transforms object ~o~ into a new string.
   - ~string.toint(x)~ converts a string into an integer. If the
     conversion fails, this function returns ~nil~.
   - ~string.tofloat(x)~ converts a string into a float. If the
     conversion fails, this function returns ~nil~.

** 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 a 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 /non-protected/ strings---protected strings are
   stored permanently, while non-protected 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
   non-protected.

   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 than their identifier.

* Files
  :PROPERTIES:
  :CUSTOM_ID: files
  :END:
  To handle files, Buzz offers a number of built-in functions
  collected in the ~io~ table.
  - ~f = io.fopen(path,mode)~ opens a file located at ~path~. Parameter
    ~mode~ encodes how the file is opened:
    - ~"r"~ opens the file read-only;
    - ~"w"~ opens the file write-only and truncates the file;
    - ~"a"~ opens the file write-only 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 file ~f~.
  - ~f.size()~ returns the size of file ~f~.
  - ~f.fforeach(fun)~ executes function ~fun~ for each line of file ~f~.
  - ~f.fwrite(s1, s2, ...)~ writes the concatenation of strings ~s1~,
{'fraction_non_alphanumeric': 0.09904879485956396, 'fraction_numerical': 0.009764583742529252, 'mean_word_length': 2.9750167298683916, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1112072', 'n_tokens_mistral': 11520, 'n_tokens_neox': 10919, 'n_words': 4749}