## @std/seq to express Sequential Algorithms in Alan

Alan does not allow arbitrary, or classical, loops or recursion and the preferred way to do iteration is with arrays. However, there are algorithms people need to write that are inherently sequential, and often non-deterministic on the number of steps needed to take, such as with numeric approximation algorithms like Newton-Raphson, or anything written as a recursive function call. Most of the problems developers need to solve do not require this linearity, but for when it really is required, we are reintroducing this power in a controlled manner that still allows the AVM to be able to plan around these algorithms and provide the guarantee of termination. The `@std/seq` syntax was designed to not feel like classical control flow in order to nudge developers to find better, more deterministic and more parallelizable mechanisms, instead.

Here are the function signatures of the sequential functions that `@std/seq` provides:

``````fn next(seq: Seq): Result<int64>
fn each(seq: Seq, func: function): void
fn while(seq: Seq, condFn: function, bodyFn: function): void
fn doWhile(seq: Seq, bodyFn: function): void
fn recurse(seq: Seq, recursiveFn: function, arg: any): Result<anythingElse>
``````

### `Seq` type

`@std/seq` provides functions for accomplishing many different sequential patterns that depend on a special, built-in `Seq` type with opaque internals to avoid manipulation after construction:

``````type Seq {
counter: int64,
limit: int64,
}
``````

### `next_loop.ln`

``````from @std/app import start, print, exit
from @std/seq import seq, next
on start {
let s = seq(2);
print(s.next());
print(s.next());
print(s.next());
emit exit 0;
}
``````

`next` is the simplest to explain: each time you call it, it returns the current counter value wrapped in a Result and then increments it. If you call past the limit, it returns an Error Result.

### `each_loop.ln`

``````from @std/app import start, print, exit
from @std/seq import seq, each
on start {
let s = seq(3);
s.each(fn (i: int64) = print(i));
emit exit 0;
}
``````

`each` is almost as simple as `next`: It simply runs the side-effect function however many times is in the limit of the seq instance. The function provided may or may not take the current iteration counter and must be the following signature:

``````fn func(): void
fn func(i: int64): void
``````

### `while_loop.ln`

``````from @std/app import start, print, exit
from @std/seq import seq, while
on start {
let s = seq(100);
let sum = 0;
s.while(fn = sum < 10, fn {
sum = sum + 1 || 0;
});
print(sum);
emit exit 0;
}
``````

`while` runs the `bodyFn` up to the `limit` number of times, but can abort early if `condFn` returns `false`. The signatures of these two functions must match:

``````fn condFn(): bool
fn bodyFn(): void
``````

### `doWhile_loop.ln`

``````from @std/app import start, print, exit
from @std/seq import seq, doWhile
on start {
let s = seq(100);
let sum = 0;
// TODO: Still need type inference working for multi-line closures
s.doWhile(fn (): bool {
sum = sum + 1 || 0;
return sum < 10;
});
print(sum);
emit exit 0;
}
``````

`doWhile` always runs at least once (unless the `seq` has reached its `limit` or it was constructed with an initial `limit` of `0`) and uses the return value of the function to determine if it should continue or not, so its `bodyFn` has the following signature:

``````fn bodyFn(): bool
``````

### `recurse_fib.ln`

``````from @std/app import start, print, exit
from @std/seq import seq, Self, recurse
on start {
print(seq(100).recurse(fn fibonacci(self: Self, i: int64): Result<int64> {
if i < 2 {
return ok(1);
} else {
const prev = self.recurse(i - 1);
const prevPrev = self.recurse(i - 2);
if prev.isErr() {
return prev;
}
if prevPrev.isErr() {
return prevPrev;
}
return ok((prev || 1) + (prevPrev || 1));
}
}, 8));
emit exit 0;
}
``````

`recurse` allows recursive functions to be defined in `alan`. This is impossible in `alan`'s grammar, so what is done is special trickery to make it possible. The `recursiveFn` has the following function signature:

``````fn recursiveFn(self: Self, arg: any): Result<anythingElse>
``````

The `Self` type is a special type that the recursive function can use to trigger a controlled recursive call, like so:

``````const recursiveResult = self.recurse(someNewArg);
``````

`Self` is another opaque type that the AVM can use to keep track of the function to be called recursively and how deep the recursion has gone so far. The `recursiveFn` must wrap its value in a `Result` type because `alan` may interject and bubble up an error if the recursion limit is reached.