Nessa is an **imperative**, **strongly-typed** programming language with many common features. Here We will explain the main
ones. All these should be enough to get you started writing basic code, but more complex features will be analyzed later in their
own respective sections.

## Literals

One of the main ways you can create values is by writing down explicit constants that the compiler will understand as **basic types**.
These are called **literals** and are a very important concept in many languages, but more so in Nessa. Here are all the literals that
tthe language supports.   

### Integers

Integers can be inputted in Nessa in a similar way as other languages:

```
881452      // Basic integer (no size limit)
-32         // Negative integers are also literals
0b1000110   // Binary integers (70 in this case)
0xFF1A      // Hexadecimal integers (65306 in this case)
```

All these values are compiled to `Int` values.

### Floating Point numbers

Floating point numbers are more or less the same as in other languages, but only these syntaxes are allowed.

> **Note:** exponential syntaxes might be supported in future versions

```
1.56        // Basic float
-67.2       // Negative floats are also literals
```

All these values are compiled to `Float` values.

### Logical values

The only logical literals Nessa supports are `true` and `false`. They are compiled to `Bool` values.

### Strings

Strings in Nessa are UTF-8 encoded and are inputted by using **double quotes** with the possibility of **escape sequences**.
These would be some examples:

```
"This is an example"

"This is an example with \t tabs and line \n jumps"

"Also, you 
can have
multiline 
strings"
```

All these values are compiled to `String` values.

### Characters

Characters do not exist in Nessa as a class, but they can be used as `Int` code points:

```
'w' // This is equal to 119
```

This can be used when iterating over code points.

## Variables

In contrast to functional languages, Nessa does have support for variables and they are used as much as in any other
imperative language. Constants are not implemented for now, but they might be introduced in a future release.

### Definition

The syntax for variable definitions is as follows:

```
let name: Type = expression;
```

In `let` statements, `name` can be any alphanumeric identifier that **does not begin with a number** ("_" is also allowed), 
`Type` can be any valid type of the ones seen in the **Type System** section and `expression` can be anything that is not a 
statement. These would be some valid examples:

```
let example_1: Int = 3 + 6;     // Simple definition
let example_2 = 3 + 6;          // Here the Int type is inferred
let example_3 = "Test";         // A String type is inferred
```

### Assignment

When you have already defined a variable, you can replace its value by using the `=` operator: 

```
let example: Int = 3 + 6;

example = 5;      // Replace the value by 5
example = true;   // ERROR: Bool is not bindable to Int
```

### Getting values

To get the value of a variable, just use its name in the code. Note that you will get a **Reference** to the value instead of the value
to prevent the user from making unnecessary copies:

```
let big = "Imagine this is a very big string ...";

let big_2: String = big;            // ERROR: @String is not bindable to String
let big_3: @String = big;           // Keeps a reference
let big_4: String = big.deref();    // Copies the original data
let big_5: &String = big.demut();   // Keeps a constant reference
```

### Reference assignment

Sometimes you might need to change the underlying values of a mutable reference. An example of this would be trying to change an element inside an array
or mutating a class instance. For these cases you can use the `:=` operator:

```
/*
    Imagine a class Example that has an Int 
    attribute called attribute_1
*/

let example: Example = some_class_instance;

example.attribute_1() := 5;     // This is only allowed using this operator
example.attribute_1() := "Test" // ERROR: String is not bindable to Int
```

## Functions

You can also use functions in Nessa, as you might expect. Functions are called using the parentheses syntax used in most imperative languages, 
including angle brackets in the case of generics.

## Operations

Just as most programming languages, Nessa has **operators** and **operations**. These encode operations with one, two o even more expressions called **operands**. Nessa supports four kind of operators:

1. **Prefix operators:** the operator comes before a single expression (*example:* `-5`).
2. **Postfix operators:** the operator comes after a single expression (*example:* `5!`).
3. **Binary (infix) operators:** the operator comes betwwen two expressions (*example:* `1 + 2`).
4. **N-ary operators:** the operator has an opening and a closing delimiter. Operands are before and inside the delimiters (*example:* `mat[4, 5]`).

All these operators and operations can be defined in a similar way as functions. The syntax for generics varies depending on the type of operator
and will be explained in their corresponding section.

## Flow control

These are the flow-control operations that are allowed in Nessa.

### If-else

The language supports if-else control flow with the following syntax:

```
// Else ifs and elses are optional
if condition {
    [...]
} else if condition {
    [...]
} else {
    [...]
}
```

conditions must evaluate to `Bool`.

### While

While loops have the following syntax:

```
while condition {
    [...]
}
```

conditions must also evaluate to `Bool`. You can `break` and `continue` in while loops.

### For

For loops are the most complicated of the three. To begin with, you need an `Iterable` object, which is defined as
one that implements the `Iterable` interface (more information about interfaces in their section). After this, you can write
the following:

```
// container must implement Iterable
for i in container {
    [...]
}
```

if you want to make a custom class iterable you have to implement that Interface manually. You can `break` and `continue` in for loops.