Skip to content

Brainstorming the user-facing experience #69

@Arlen22

Description

@Arlen22

This issue is primarily for condensing technical ideas into practical ones. If you want to discuss something you see here, feel free to open a new issue.

The try operator

  • like any operator,

    • it takes a value and gives a value
    • it can be used pretty much anywhere
    • its result can be ignored
    • it cannot contain a statement
  • like the yield operator,

    • it takes the highest precedence without a comma
    • it can contain itself, yield, or anything else
  • like the try block,

    • it catches anything that throws inside it, including the await and yield keywords.
    • it transparently supports generator and async functions.
    • it clearly indicates whether or not the code it protects ran to completion.
  • To maintain equivalence,

    • try {}: It must catch any exception thrown by a specific section of code.
    • catch (e) {}: It must allow different code to execute if an exception was caught and provide a reference to the exception thrown.
    • finally {}: It must allow code to execute regardless of whether or not an exception was caught.
    • It must not allow any value from that section of code to change or spoof these constraints.
  • this gives us two more invariants

    • it must return a result that clearly indicates whether this is the normal completion (perhaps a boolean). Checking undefined is not enough since both normal and abrupt completions may return undefined.
    • it must not flatten its result. If the expression it protects returns or throws a Result, it must still wrap it in a new Result regardless. Otherwise, the user could not distinguish between returning Result(false) and actually throwing, or between throwing Result(true) and actually returning.
/**
 * (   try       something())
 * (<operator>  <expression>)
 */
operator try(expression) {
  try { 
    return TryResult.ok(exec(expression));
  } catch (inner) {
    return TryResult.error(inner);
  }
}

does this

const a = try something()
const [[ok, err, val]] = [try something()]
const [ok, err, val] = try something()
files.map(file => try JSON.parse(file))
yield try something()
try yield something()
try await something()
try a instanceof b
(try a) instanceof TryResult
const a = try try try try try try 1

Metadata

Metadata

Labels

BrainstormDiscussions about possible new features

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions