Let's create arguably one of the most useful constructs when working with iterable structures:
list comprehensions. This can be done thanks to Nessa's syntax definition features.
## What is *list comprehension*?
List comprehensions are a syntax option in some languages that allow the programmer to
**transform** the values of a list or even filter them without having to create an explicit for loop and
a temporary variable. In this case, we will not deal with filtering the list.
## Creating the syntax
The syntax for list comprehensions then to be something like this:
```
[expr for elem in container]
```
This is problematic for us because Nessa is a strongly typed language. We will have to adapt it like this:
```
[expr for elem: ElemType in container]
```
This can be expressed in *NDL* like this:
```
"["
[s] Arg(<expr>, map) [s] // Map expression
"for" [s] Arg(<ident>, it) [s] ":" [s] Arg(<type>, type) [s] // Element
"in" [s] Arg(<expr>, container) [s] // Container
"]"
```
Note that you need `Arg`s to mark the variables that we will use inside the body.
## Generating the body
Internally, a list comprehension is just a **for loop** with a transformation function. There are multiple ways to do this, but
this is one of them (again, note that we have to escape the for's closing brace):
```
syntax list_comprehension from [...] {
let res = arr<$type>();
let func = ($it: $type) -> $type $map;
for _it_ in $container {
res.push(func(*_it_));
\}
return move(res);
}
```
## Example
Making use of an `Array` initialization syntax, you can build the following code:
```
let array = [i * 2 for i: Int in <Int>[1, 2, 3, 4, 5]]; // [2, 4, 6, 8, 10]
```
This would compile to:
```
let array = do {
let res = arr<Int>();
let func = (i: Int) -> Int i * 2;
for _it_ in <Int>[1, 2, 3, 4, 5] {
res.push(func(*_it_));
}
return *res;
};
```
In this example `<Int>[1, 2, 3, 4, 5]` would also be recursively compiled into a new expression based on a lambda expression, but
the exact compilation is not important.