Standard library · Basics

result

Returning either a value or an error from a function, instead of throwing an exception.

import result
On this page
  1. Types
  2. Functions

Salam has no exceptions. A function that may fail returns a Result rather than throwing: either Ok with a value, or Err with an explanation of what went wrong. The caller checks both cases with match, and the compiler will not let either be forgotten.

Inside a function that returns a Result itself, the ? operator shortens the work: written after a call, it pulls out the successful value, and on an error returns that error straight away. The enums lesson walks through the pattern step by step.

Types

Result

enum Result<T, E>:
    Ok(value: T)
    Err(error: E)
end
A generic enum with two cases. T is the type of the successful value and E the type of the error, which is most often a str. Build one with result.Result.Ok(...) or result.Result.Err(...).
NameTypeDescription
Ok(value: T)The work succeeded, and the value is in value.
Err(error: E)The work did not happen, and the explanation is in error.
result-Result.salam
import result

func age(text: str): result.Result<int, str>:
    n := text.to_int()
    if n <= 0 or n > 150:
        ret result.Result.Err("not a valid age: " + text)
    end
    ret result.Result.Ok(n)
end

func main:
    each text in ["30", "200"]:
        r := age(text)
        println match r:
            Ok(n): "age accepted: " + n end
            Err(message): message end
        end
    end
end
Outputage accepted: 30 not a valid age: 200

Functions

IsOk

func IsOk<T, E>(r: Result<T, E>): bool
Returns true when the result is Ok.
result-IsOk.salam
import result

func divide(a: int, b: int): result.Result<int, str>:
    if b == 0:
        ret result.Result.Err("division by zero")
    end
    ret result.Result.Ok(a / b)
end

func main:
    good := divide(9, 3)
    bad := divide(1, 0)
    println result.IsOk(good), result.IsErr(good)
    println result.IsOk(bad), result.IsErr(bad)
    println result.UnwrapOr(good, -1), result.UnwrapOr(bad, -1)
    println result.Expect(good, "this division should have worked")
end
Outputtrue false false true 3 -1 3

IsErr

func IsErr<T, E>(r: Result<T, E>): bool
Returns true when the result is Err.

The example for this item is shown with the ones above: result-IsOk.salam

UnwrapOr

func UnwrapOr<T, E>(r: Result<T, E>, fallback: T): T
Returns the value when the result succeeded, and the default you supplied when it did not.

The example for this item is shown with the ones above: result-IsOk.salam

Expect

func Expect<T, E>(r: Result<T, E>, msg: str): T
Returns the value of a successful result. If the result is an error, the program stops with the message you gave, so use it only where you are sure an error is impossible.

The example for this item is shown with the ones above: result-IsOk.salam