do
do(Expr, ..., Expr)
{ Expr; ...; Expr }
Do evaluates to the value of it's final argument, all other arguments are evaluated for side effect. Each do block aside from the toplevel one introduces a new lexical scope, let variables defined in such a scope are not visible outside it.
e.g.
{
let foo <- "Hello world!";
store("/tmp/foo", foo);
foo
}
evaluates to "Hello world!", but also sets the variable "foo", and stores it's value to "/tmp/foo".