beps/docs/proposals/BEP-001-exceptions/legacy-ignore/story_outline.md
We'll evaluate each attempt against two common scenarios:
ExtractResume (defining an LLM call).ProcessBatch (looping over items).The Base Cases:
// 1. Declarative
function ExtractResume(text: string) -> Resume {
client "gpt-4o"
prompt #"..."#
}
// 2. Imperative
function ProcessBatch(urls: string[]) -> Resume[] {
// If this fails, we still want to process resumes!
let aggregator = MetricsAggregator.new()
let results = []
for (url in urls) {
let resume = ExtractResume(url)
aggregator.record(resume)
results.append(resume)
}
return results
}
Attempt 1: The Classic try/catch Statement
aggregator failing, you must declare let aggregator; outside, then try { aggregator = ... }, then check if (aggregator) { ... } inside the loop.Attempt 2: Result Types (Result<T, E>)
MetricsAggregator.new() returns Result. You must match or unwrap it.ExtractResume now returns Result.Attempt 3: Expression-Oriented Try (let x = try { ... })
let aggregator = try { ... } (Great for this case!).let resume = try { client ... } (Confusing).Attempt 4: Function Modifiers (function ... try)
Attempt 5: Wrapper Functions
catch is an operator that can be attached to ANY block.catch to handle a timeout. Zero indentation change.catch to the loop body to prevent one failure from crashing the batch.catch { _ => null } on a single expression.try { ... } block for the risky part to signal intent.