Skip to content

Instantly share code, notes, and snippets.

@m93a
Last active January 28, 2023 18:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save m93a/831da556cb061dfaceb883a965560483 to your computer and use it in GitHub Desktop.
Save m93a/831da556cb061dfaceb883a965560483 to your computer and use it in GitHub Desktop.

Intro

The academic language Effekt has so-called effects. They are a generalization of throw, yield and await which allow an executed function to "stop" in the middle of its execution, and then optionally continue. This would be a great feature for Gunpowder.

Categorization

  • throw<E>: E → never

    • interrupts with any value – it will act as the error
    • never resumes
    • not consuming is equivalent to a try{} block
  • (suffix after function call) ?: T / throw<T> → T

    • unwraps a value or re-throws an error
    • equivalent to yield* for yield
  • yield<T>: T → void

    • interrupts with any value – it will act as the "next" value in iterable
    • user code can resume without any value
    • doesn't need to be consumed
  • yield*<T>: void / yield<T> → void

    • iterrupts with an iterable, re-yields all values
    • user code wantint to resume will consume the re-yielded iterable first, only then it will resume the function which used yield*
    • equivalent to the ? suffix for throw
  • await: T / await → T

    • interrupts with a promise, resumes with its result
    • resumed by an asynchronous runtime
    • must be consumed in order to ever finish execution

Syntax

fn divide(a: i32, b: i32): Fraction / throw<DivisionByZero> {
  if b == 0 {
    throw DivisionByZero();
  } else {
    return a / b;
  }
}

fn fibonacci(): yield<i32> {
  let a: i32 = 1;
  let b: i32 = 1;
  loop {
    yield a;
    [a, b] = [b, a + b];
  }
}

fn wikiFeaturedArticle(): string / await / throw<NetworkError> {
  const url = "https://en.wikipedia.org/w/api.php?feed=featured";
  const response = await fetch(url);
  if not response.ok { throw NetworkError(response.status); }
  return await response.text();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment