LINUX.ORG.RU

Почему в Qt не рекомендуют использовать исключения?

 


2

4

Волею случая сейчас делаю один проект на Qt, после Java хочется жирненько обмазать метод исключениями, а тут опаньки и такое вот написано, почему так?

http://qt-project.org/wiki/Coding-Conventions

Перемещено mono из talks

Ответ на: комментарий от korvin_

И кстати в Scala примерно для того же есть тип Option с паттерн-матчингом.

LongLiveUbuntu ★★★★★
()
Ответ на: комментарий от LongLiveUbuntu

Переведи

Комментарий? Примерно так:

Если вызов lookup "foo" завершится неудачей (вернёт Nothing), то myFunc незамедлительно также вернёт Nothin. То же самое самое произойдет далее с lookup "bar". И только если оба вызова lookup завершатся успешно, результаты их работы будут использованы дале в return $ i * mult + j.

Без монад этот код выглядел бы примерно так:

lookup :: Eq a => a -> [(a, b)] -> Maybe b
-- Looks up a value in a key-value association list

myFunc :: Int -> [(String, Int)] -> Maybe Int
myFunc mult assocList = do
    let mi = lookup "foo" assocList
    case mi of
        Nothing -> Nothing
        Just  i -> do
            let mj = lookup "bar" assocList
            case mj of
                Nothing -> Nothing
                Just  j -> return $ i * mult + j
korvin_ ★★★★★
()
Ответ на: комментарий от LongLiveUbuntu

Монады как таковые - никто. Но do-нотация отсутствует. DSL здесь вроде тоже не запилить нормальный...

anonymous
()
Ответ на: комментарий от Pavval

А чем С++б!@#$тво лучше? Да и к тому же не обязательно монады, достаточно выразительных средств для «сопоставления по образцу». В том же rust можно так писать, вроде по читаемости почти сравнимо с исключениями, зато намного надежнее.

anonymous
()
Ответ на: комментарий от anonymous

достаточно выразительных средств для «сопоставления по образцу»

Средств сопоставления _и_ алгебраических типов.

В том же rust можно так писать, вроде по читаемости почти сравнимо с исключениями

Как «так»? В Rust проверки возвращаемого результата выливаются в лапшу вроде сишной или использование макро try!, который разворачивается в return. Преимущество Rust в том, что проверку результата нельзя пропустить.

tailgunner ★★★★★
()
Ответ на: комментарий от anonymous

А чем С++б!@#$тво лучше?

Ну так давай любой тред в монады скатывать, включая ЕОТ. С++ хоть кто-то пользуется.

Pavval ★★★★★
()
Ответ на: комментарий от korvin_

Это уже (минимум) однажды обсуждали и как контрпример приводили монады, позволяющие не писать портянку проверок возврата.

Они по сути лишь синтаксический сахар над сишным «if (ret) return ret;» после каждой строки, только в сишке можно еще логгирование сделать и массу прочей порой нужной логики навесить.

mix_mix ★★★★★
()
Ответ на: комментарий от Pavval

Зато царь съедет с темы рефкаунтинга в unique_ptr.

anonymous
()
Ответ на: комментарий от mix_mix

Ну в gcc есть __attribute__(__cleanup__(my_cleunup_function)) + локальные функции. Жаль в стандарте нет ничего похожего.

anonymous
()
Ответ на: комментарий от anonymous

Кусок говна обосанного, тупые ублюдки запретили его в тайпдефах - он харен такой не нужен. Какой жопой надо было думать, чтобы такое говно сделать? Плюс ещё хрен передашь лямбду.

Клеанап кусок говна, это наверное самое убогое в гнус.

anonymous
()
Ответ на: комментарий от tailgunner

Средств сопоставления _и_ алгебраических типов.

Ну да, а есть язык с первым, но без второго? Со статической типизацией. А то если примитив - то зачем новый термин заместо switch, а если структура - то уже есть «multiple variable assignment».

В Rust проверки возвращаемого результата выливаются в лапшу вроде сишной

Без промежуточных переменных уже получше смотрится, и однотиповые обертки потенциально можно макросами соединить. А если с исключениями сравнивать, то наверное честнее на том же уровне гибкости, чтоб все отдельно ловить и т.д. Впрочем, не исключаю, что те примеры, что смотрел были слишком простыми.

anonymous
()
Ответ на: комментарий от anonymous

Ну для сишечки ничего лучше нет. В оффтопиковском cl есть __try __finally но это костыль по сравнению с cleanup... Мне кажется, что сишке не повредил бы такой(нормально сделанный) механизм.

anonymous
()

Потому, что qt рассчитан на обезьянок. А обезьянки не умеют исключения в C++. Вернее они могут пытаться, но получается говно. Так что лучше их отгородить от этого. Так же делает Гугл и др.

anonymous
()
Ответ на: комментарий от anonymous

do-нотация здесь называется for-comprehension

Нет, это разные вещи. DSL там есть, я говорил, что do-нотацию не сделать(в смысле я не знаю как).

Не согласен - покажи монады-то. Желательно приведенный выше пример на haskell.

anonymous
()
Ответ на: комментарий от anonymous
def lookup[A, B](key: A, pairs: Seq[(A, B)]) /*: Option[B]*/ = pairs.find(_._1 == key).map(_._2)

def myFunc(mult: Int, accosList: Seq[(String, Int)]) /*: Option[Int]*/ = {
	for {
		i <- lookup("foo", assocList)
		j <- lookup("bar", assocList)
	} yield i * mult + j
}
anonymous
()
Ответ на: комментарий от anonymous

«Навыворот»:

def lookup[A, B](key: A, pairs: Seq[(A, B)]) = for (p <- pairs.find(_._1 == key)) yield p._2

def myFunc(mult: Int, assocList: Seq[(String, Int)]) = {
	lookup("foo", assocList) map { i =>
	  lookup("bar", assocList) map { j =>
	    i * mult + j
	  }
	}
}

Лапша без do-нотации:

def lookup[A, B](key: A, pairs: Seq[(A, B)]) = { 
  pairs.find(_._1 == key) match {
    case Some(k, v) => Some(v)
    case _ => None 
  }
}

def myFunc(mult: Int, assocList: Seq[(String, Int)]) = {
  lookup("foo", assocList) match {
    case Some(i) => lookup("bar", assocList) match {
      case Some(j) => Some(i * mult + j)
      case _ => None
    }
    case _ => None
  }
}

anonymous
()
Ответ на: комментарий от anonymous

Круто! =) Спасибо, понял, был не прав.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.