let loop = func(body, locals) {
let new_locals = locals;
try {
body(locals);
} catch (true) {
loop(body, new_locals);
} catch (false) {
hurl new_locals;
} catch as update {
new_locals = update;
return;
};
};
let for = func(count, body, locals) {
let iter = 1;
let wrapped = func(locals) {
let inner_locals = locals.1;
let new_locals = inner_locals;
try {
body(inner_locals + [iter]);
} catch as update {
new_locals = update;
};
iter = iter + 1;
toss [new_locals];
hurl iter < count + 1;
};
try {
loop(wrapped, [locals, 1, count]);
} catch as retval {
hurl retval.1;
};
};
let until = func(cond, body, locals) {
let wrapped = func(locals) {
let again = false;
try {
body(locals);
} catch as update {
locals = update;
};
try {
cond(locals);
} catch as val {
again = val;
};
toss locals;
hurl ~again;
};
loop(wrapped, locals);
};
let for_each = func(list, body) {
let index = 1;
let chunk_size = 250;
let num_chunks = ceil(len(list) / chunk_size);
try {
until(func(locals) {
hurl index > len(list);
}, func(locals) {
let chunk_index = 1;
try {
until(func(locals) {
hurl (chunk_index > chunk_size) or (index > len(list));
}, func(locals) {
body(at(list, index));
chunk_index = chunk_index + 1;
index = index + 1;
hurl locals;
}, []);
} catch as x {
};
hurl locals;
}, []);
} catch as x {
};
};