Ключевое слово X/exception



В 11l присутствует два [[вида/]типа/]рода исключений:
  1. Нефатальные/дешёвые исключения. Обязательны к перехвату в исходном коде, компилятор должен проверить, что все такие исключения перехватываются.
    Их необходимо указывать в ‘спецификаторах исключений’\‘exception specifications’. Поведение аналогично checked исключениям в Java, а реализация — аналогична ошибкам в Rust и Swift — т.е. просто как дополнительное [скрытое] возвращаемое значение у функции.
  2. Фатальные/дорогие исключения, отсутствие которых гарантировать невозможно и которые нельзя проверить на этапе компиляции. Поведение аналогично тому, как реализованы исключения в самых популярных языках программирования (C++, Python, C#, unchecked исключения в Java).

Исключения первого рода используют синтаксис
X <объект_исключения>
для порождения и
X.handle <тип_исключения>
для обработки.
Исключения второго рода используют синтаксис
X.throw <объект_исключения>
для порождения и
X.try
/
X.catch
для обработки.

Почему `X.handle`?

Пример исключения первого рода:
T StopIteration {}

T RangeIterator
   Int cur, end

   F (start, end)
      .cur = start - 1
      .end = end

   F __next__() X(StopIteration)
      .cur++
      I .cur == .end
         X StopIteration()
      R .cur

V it = RangeIterator(1, 10)
L
   V i = it.__next__()
   X.handle StopIteration
      L.break
   print(i)
(Обратите внимание, что код, порождающий исключения первого рода, не обязательно заключать в блок
X.try
{}, т.к. такие исключения гарантированно должны быть обработаны.)

Пример исключения второго рода:
T Error
   String message
   F (message)
      .message = message

X.try
   print(‘1’)
   X.throw Error(‘error message’)
   print(‘never printed string’)
X.catch Error e
   print(‘Error: ’e.message)
Этот код выведет:
1
Error: error message