# The Gobba Programming Language Basics

## Comments

Comments are treated by gobba as whitespace and consequently ignored. Comments can be nested and are multi-line by default, and can be written as following:

```
(* This is a comment *)
```

## Numbers, Arithmetics and the Numerical Tower

Gobba supports 3 kinds of numbers: integers, floats and complex numbers.
Floating point numbers' decimal part can be omitted if it is 0. Floats also
support the scientific notation in literal values. Complex numbers literals are
"allocated" from other two numbers with the `:+`

operator. The number
on the left will be the real part and the one on the right will be allocated as
the imaginary part.

```
(* Integer literals *)
1 ;
0 ;
10350156 ;
(* Floating Point Literals *)
1.2e-3 ;
0.0 ;
0.123 ;
34. ;
4.3e9 ;
(* Complex Number Literals *)
12.1 :+ 1.23;
0 :+ 1.12;
```

Arithmetical operations are straightforward. If an arithmetical operation
is called on different types of numbers, the result is "raised" to the "most inclusive" type of numbers.
For example, Integer division returns an integer if the modulo is 0, and returns a float
otherwise.
Floating point numbers can use the power syntax using `e`

.

```
(* Addition, multiplication and subtraction *)
1 + 2 + 3 * (4 - 1) ;
(* *)
1. / 2.315 ;
```

## Boolean literals and arithmetic

The boolean literals in gobba are `true`

and `false`

. There are also operators
for the logical AND and OR: `&&`

and `||`

. The comparison operators return
boolean values and are:

`a = b`

: True if and only if the two objects are the same`a > b`

and`a >= b`

: Greater and greater or equal`a < b`

and`a <= b`

: Less and less or equal

Here's an example:

```
true && false || (1 < 2) && (1 = 1) ;
```

## Character literals.

The same as all the other languages: Single characters enclosed in `'`

are character literals,
such as `'a'`

or `'\n'`

. UTF-8 support is planned for a future release.

## Strings

Strings are values enclosed in double quotation marks. Here is how to concatenate strings

```
"hello " ++ "world"
(* It is the same as *)
String:concat "hello " "world"
```

To convert any value to a string you can use the `show`

primitive.

## Lists

Lists are enclosed in square brackets and values are separated by commas. Lists are heterogeneous, so any value in a list can have a different type from the other elements of the list.

```
[1, 2, "ciao", 4, 5] ;
```

`::`

is the classic `cons`

operator. It inserts the element on the left at the beginning of the list.
This is done in `O(1)`

time.
The `++`

operator is used for list and string concatenation.

```
1 :: [2] ++ [3]
```

To access the n-th value of a list, use the `@`

operator, called "at". List indexes begin from 0.

```
[1, 2, 3, 4] @ 0 (* => 1 *)
[1, 2, 3, 4] @ 2 (* => 3 *)
```

In gobba, the classic functional programming functions and morphisms on lists
are defined in the `List`

module:

Get the length of a list (done in `O(n)`

time).

```
List:length [1, 2, 3, 4] ;
```

Get the element at the beginning of a list

```
List:head [1, 2, 3, 4] ;
```

Get another list with the first element removed

```
List:tail [1, 2, 3, 4] ;
```

Iterate a function over every list value and return a new list

```
List:map (fun x -> x + 1) [1, 2, 3, 4] ;
```

List folding: see the Wikipedia Page

```
List:foldl (fun x y -> x - y) 10 [1, 2, 3, 4] ;
List:foldr (fun x y -> x - y) 10 [1, 2, 3, 4] ;
```

## Declarations

Local declaration statements are purely functional and straightforward:

```
let x = 4 and y = 1 in x + y
```

Global declaration statements create new, purely functional environments in both
programs and the REPL. Omitting `in`

is syntax-sugar, subsequent blocks will
be evaluated in the resulting new environment.

```
let a = 2 ;
a + 3 ;
```

You can declare lazily evaluated
variables by prefixing the name of the variables with the `lazy`

keyword.

```
let x = 2 and lazy y = (3 + 4) ;
```

## Toplevel Directives

Toplevel directives can be used in both files and the REPL. Like in OCaml, they
start with a `#`

symbol. Note that toplevel directives are not expressions and
they can only be used in a file (or REPL) top level, and cannot be used inside expressions.

`#include`

loads a file at a position relative to the current directory (if in
the REPL) or the directory containing the current running file (in file mode).
The declarations in the included file will be included in the current toplevel environment:

```
#include "examples/fibonacci.mini" ;
```

`#module`

loads a file like `#include`

but the declarations in the included file
will be wrapped in a dictionary, that acts as a module:

```
#module "examples/fibonacci.mini" ;
(* Declarations will be available in module *) Fibonacci
```

`#open`

takes a module name and imports everything that is contained in that module into the
toplevel environment:

```
#open Math;
```

`#verbosity n`

sets verbosity level to`n`

. There are "unit" directives:`#dumpenv ()`

and`#dumppurityenv ()`

dump the current environments.`#pure ()`

,`#impure ()`

and`#uncertain ()`

set the globally allowed purity level.

## Functions and recursion

For parsing simplicity, only the OCaml anonymous function style of declaring
functions is supported. The keyword `fun`

is interchangeable with `lambda`

.

```
(fun x -> x + 1) 1;
let fib = fun n -> if n < 2 then n else (fib (n - 1)) + fib (n - 2)
```

Functions are abstracted into a single parameter chain of functions, and they can be partially applied:

```
(fun x y z -> x + y + z) = (fun x -> fun y -> fun z -> x + y + z) ;
(* result: true - bool - This is true!! *)
let f = (fun x y z -> x + y + z) in f 1 2 3 ;
(* result: 6 - int - Function application *)
let f = (fun x y z -> x + y + z) in f 1 2 ;
(* result: (fun z -> ... ) - fun - Partial application *)
```

## Dictionaries and modules.

Dictionary (object) values are similar to Javascript objects. The difference from javascript is that the keys of an existing dictionary are treated as symbols, and values can be lazy.

You may have noticed that dictionary fields are syntactically similar to the
assignments in `let`

statements. This is because there is a strict approach
towards simplicity in the parsing logic and language syntax. A difference from
`let`

statements, is that values in dictionaries can only access the
lexical scope **outside** of the dictionary.

```
let n = {hola = 1, lazy mondo = 2, somefunc = fun x -> x + 1 } ;
let m = Dict:insert "newkey" 123 n ;
m = {newkey = 123, hola = 1, mondo = 2, somefunc = fun x -> x + 1 } (* => true *)
Dict:haskey "newkey" m (* => true *)
(* => {newkey = 124, hola = 2, mondo = 3} *)
```

An element of a dictionary can be accessed using the `:`

infix operator.

```
m:hola (* returns 1 *)
```

Some morphisms are defined in the `Dict`

module.

```
Dict:map (fun x -> x + 1) m;
Dict:foldl (fun x y -> x + y) 0 m;
Dict:foldr (fun x y -> x - y) 10 m;
```

## Haskell-like dollar syntax

Too many parens?

```
f (g (h (i 1 2 3)))
```

Is equivalent to

```
f $ g $ h $ i 1 2 3
```