> -- Илья Ермаков писал(а):
> Тут же к вопросу об обработке исключений - мне кажется, что конструкции try-except (в полезности которых многие давно сомневались) совершенно бесполезны в параллельных приложениях. Т.к. искать обработчик исключительной ситуации раскруткой стека текущего потока бессмысленно, этот поток не может и не должен ничего знать об обработке исключений (а если всё-таки должен, то достаточно обычных кодов ошибок).Обработчики исключений должны быть обычными callback-объектами, с соотв. конкретным возможным проблемам интерфейсами. Приложение описывает эти обработчики и регистрирует их в соотв. службе. Т.е. никаких спец. языковых механизмов, только обычные ОО-паттерны.
Я тут подумал -- а зачем ещё и паттерны ООП привлекать-то? :о))

Вот возьмём (ну конечно же) тот же Хаскелл. В нём нет специальной языковой конструкции тип try-except, есть просто несколько стандартных функций: catch, try, bracket, finally для обработки исключений и ioError -- для их генерации...

Простейший пример:## Код:
```
main = do
    print $ 1 `div` 0
```
Как и следовало ожидать, при выполнении образуется исключение: divide by zero. Как его перехватить? Ну, например, вот так:## Код:
```
import Control.Exception as CE

main = do
    print $ 1 `div` 0
  `CE.catch` \err -> print $ "Oops! Something wrong: " ++ show err
```
А если надо просто попытаться выполнить какой-то код, игнорируя возможные ошибки, то можно сделать так:## Код:
```
import Control.Exception

main = do
    try $ print $ 1 `div` 0
```

Функции try и finally являются аналогом оператора try-finally в Дельфях. Позволяют делать так:## Код:
```
import Control.Exception

main =
  try $ do
    open_resources              -- открываем какие-нибудь файлы или прочие ресурсы
    do_something                -- делаем что-то, что может привести к исключению
 `finally`
    close_resources             -- закрываем открытые ресурсы
```
Или более продвинуто -- с обработкой возникших неприятностей:## Код:
```
import Prelude hiding (catch)
import Control.Exception

main =
  do
    open_resources              -- открываем какие-нибудь файлы или прочие ресурсы
    do_something                -- делаем что-то, что может привести к исключению
 `finally`
    close_resources             -- закрываем открытые ресурсы

 `catch` \err -> case err of    -- Обрабатываем возникшие исключения
    ArithException DivideByZero -> print "Oops! Division by Zero"
    Deadlock                    -> print "Oops! All threads are blocked"
    others                      -> print $ "Oops! " ++ show others
```

Функция bracket чем-то похожа на оператор using из C#. Можно делать, например, так:## Код:
```
main = do
    bracket
        (openFile "filename" ReadMode)  -- открываем файл
        (hClose)                        -- закрываем его, что бы ни случилось
        (\handle -> do { ... })         -- если открылся нормально, работаем с ним
```
Любимый лисперами макрос with-file будет выглядеть так:## Код:
```
withFile name mode = bracket (openFile name mode) hClose
```
и все дела! Вот она, сила функционального программирования! :о) Новая продвинутая (для каких-нить там джавистов или сишарперов) языковая конструкция задаром, просто в виде функции!

С одной стороны, такой набор гибких функций, а не жёстких операторов, может выглядеть моментами как привносящий некоторый синтаксический оверхед (типа `catch` \err -> case err of), что не очень приятно, но вполне терпимо.

С другой стороны, это позволяет при необходимости вносить в логику обработки исключений свои собственные поправки/изменения/дополнения, не затрагивая компилятор или стандартные библиотеки...
Например, Булат Зиганьшин в своём архиваторе FreeArk легко сделал такие поправки, что бы перехватывать нажатие на Ctrl-C и корректно закрывать все файлы и прочие дела при этом...

ЗЫ. А вот интересно, как будет выглядеть использование подобных процедур в таких языках (с библиотечной поддержкой исключений), как тот же Оберон? ;о) Небось, нечто жуткое и невообразимое? :о))