Си диез / Говнокод #26533 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
  36. 36
  37. 37
  38. 38
  39. 39
  40. 40
  41. 41
  42. 42
  43. 43
using System;
 
namespace Test
{
    public class HttpException : Exception
    {
        public HttpException(int status)
        {
            StatusCode = status;
        }
 
        public int StatusCode { get; set; }
    }
 
    class Program
    {
        static void TestCatch(int status)
        {
            try
            {
                throw new HttpException(status);
            }
            catch (HttpException ex) when (ex.StatusCode == 404)
            {
                Console.WriteLine("Not Found!");
            }
            catch (HttpException ex) when (ex.StatusCode >= 500 && ex.StatusCode < 600)
            {
                Console.WriteLine("Server Error");
            }
            catch (HttpException ex)
            {
                Console.WriteLine("HTTP Error {0}", ex.StatusCode);
            } 
        }
        static void Main(string[] args)
        {
            TestCatch(404);
            TestCatch(501);
            TestCatch(101);
        }
    }
}

https://ideone.com/zXstg3
Именно поэтому я за «C#».

Запостил: gost gost, (Updated )

Комментарии (176) RSS

  • enum DaError: Error {
        case some(Int)
    }
            
    func testThrow(value: Int) throws {
        do {
            throw DaError.some(value)
        } catch {
            switch error {
            case let DaError.some(value) where value < 4:
                print("SMALL")
            case let DaError.some(value) where value == 4:
                print("DA GOOD")
            case let DaError.some(value) where value > 4:
                print("BIG")
            default:
                throw error
            }
        }
    }
            
    for val in [1, 4, 100500] {
        try? testThrow(value: val)
    }


    https://ideone.com/yaYl9Y

    А ваш язык так что, не умеет?
    Ответить
  • Агаа, и при этом эксепшены не checked, так что заставить пользователя писать эту цепочку ты не можеш
    говно!
    Ответить
    • > заставить обработать

      Обработай ещё этих ебучих JSONException'ов да выпей джавы.
      Ответить
      • Борманд, знаешь загадку про лес хуёв и море говна?
        Вот тут тоже самое.

        JSONException'ов и RPCExceptionов я наобрабатывал всласть, но приведенный гостом пример, к сожалению, не юзабелен: ничто не заставит клиента функции GetPetuhByHttp() написать эту цепочку. А джава могла бы заставить

        Так что оба хуже.
        Ответить
        • > заставить

          Ну что за жабья философия... Программист - это ребёнок, которого надо водить за ручку и заставлять есть кашу?

          Есть куча вполне разумных кейсов, когда исключения достаточно "обработать" в одной точке - цикле обработки сообщений, main'е и т.п. И я не хочу обмазывать все функции этими throws Exception, только чтобы дотащить этот сраный JSONException до этой точки. Даже в крестах это уже осознали и выкинули все спецификации исключений помимо "не кидает ничего" и "что-то может кинуть".
          Ответить
          • >которого надо водить за ручку и заставлять есть кашу?


            Эмм.. ты против того, чтобы компилятор заставлял тебя проверять ошибки?
            Тогда тебе должен нравится PHP: там вообще ничего проверять не обязательно.

            >Есть куча вполне разумных кейсов, когда исключения достаточно "обработать" в одной точке
            Да.

            >я не хочу обмазывать весь код этими throws Exception
            Я же сказал: говно и то, и другое.

            Засирать весь код "throws PetuhException, ScriptuhException" -- плохо.

            Разрешать пользовтаелю не проверять эксепшены -- тоже плохо, потому что как тогда ошибку вернуть?

            "Этот метод возвращает или ответ, или одну из вот этих трех ошибок. Не забудьте их проверить пожалуйста. А если забудете -- то программа просто упадет, а комплиятор вам не поможет, потому что мы не в жабе". Так чтоли?
            Ответить
            • Этот метод возвращает ответ либо кидает исключение. В документации к методу описано какие исключения вы можете захотеть обработать чтобы улучшить user experience. Однако этот список не исчерпывающий и метод может кинуть и другие исключения в зависимости от реализации.

              Всё. Если программист хочет сделать что-то полезное для юзера при каких-то конкретных исключениях - он прочитает о них в документации и обработает (какие-нибудь FileNotFound или NetworkIsDown, к примеру).

              Остальные исключения обрабатывать нет никакого смысла - либо catch all + log либо terminate.

              > компилятор вам не поможет

              Он уже помог разделить код на успешный путь (вернули результат) и неуспешный путь (вернули исключение). И даже прокинул неуспешный путь через весь коллстек, в отличие от той же сишки где каждый вызов надо обмазывать проверками. И даже дал возможность прикрепить какую-то полезную инфу и строчку для лога. Что ещё надо то?
              Ответить
              • > В документации
                Еще раз: ты против проверки компилятором?

                И что должна делать программа если NetworkIsDown?
                Ответить
                • Да, я против проверки конкретных типов исключений компилятором. Разраб либы не знает, в каком контексте её будут юзать, поэтому он не должен принимать решение за других. Ошибочный путь от успешного он отделил, инфу о проблеме он приложил, дальше - не его дело.

                  > что должна делать программа если NetworkIsDown

                  А я ебу? Это конкретная программа решает. Выйти с ошибкой, попросить юзера подключить сеть если мы на мобиле, отложить в очередь до появления сети и т.п.
                  Ответить
                  • То-есть ты за то, чтобы тупо передать ошибку наверх например, а там пускай с ней разберутся? А ее там никто не знает.

                    В итоге будет как в винде: "ошибка 0xDEADBEEF, обратитесь к системному адменистратору". Очень прекрасно.
                    Ответить
                    • Вся засада в том, что чем больше ты обрабатываешь конкретные ошибки, тем больше приходится обрабатывать конкретные ошибки... А в итоге юзер всё равно не поймёт их. Да и даже ты сам не поймёшь без ковыряния в логах. Поэтому, имхо, лучше вложиться в логи чем в этот сизифов труд.

                      Важен факт ошибки, и конпелятор не даёт его проебать.

                      Важны простые и популярные ошибки, которые юзер реально может исправить. А они, внезапно, обычно находятся в самом первом исключении - "нет доступа", "файл не найден", "неожиданный символ {". И чем меньше ты заворачиваешь эти исключения, тем легче их выловить на верхнем уровне и показать на понятном для юзера языке, возможно даже с локализацией.

                      А для автономных сервисов выбор между логами и обмазыванием трайкетчами вообще очевиден.

                      > тупо передать ошибку наверх

                      Именно так. Если сразу с ошибкой ничего придумать не удалось - значит пусть с ней разбирается generic обработчик аля Залогировать и Сдохнуть™. В середине цепочки вызовов она нахуй никому не нужна.
                      Ответить
                      • https://www.multicians.org/unix.html

                        > We went to lunch afterward, and I remarked to Dennis that easily half the code I was writing in Multics was error recovery code. He said, "We left all that stuff out. If there's an error, we have this routine called panic(), and when it is called, the machine crashes, and you holler down the hall, 'Hey, reboot it.'"

                        А то пишут, пишут... исключения, трайкетчи какие-то... Голова пухнет. Взять всё, да и завершить...
                        Ответить
                        • Не надо ничего писать, разве что летопись, где увековечат мои подвиги по выкашиванию антропов.
                          Ответить
                      • Иногда я могу хотеть передать их наверх, иногда -- обработать сразу, иногда вообще хочу "залогировать и сдохнуть", потому что знаю, что такого не может быть (ну или я не знаю как это обработать).

                        Но CheckExceptions мне права выбора не дают, их надо явно заворачивать в RunTime или засирать ими все сигнатуры по стеку вызова.

                        Потому я предлагаю такой синтаксис.
                        Допусти, есть
                        void Petuh getPetih(String jsonFileWithPetuh) throws InvalidJson, FileNotFound;


                        Вот использование
                        var petuh = getPetuh("c://pethu.json") ignore (InvalidJson, FileNotFound);

                        тут я явно отказался от обработки эксепшенов. По сути они стали RunTime, улетели на верх стека, и там завалили программу с трейсом, или их поймал местный доктор вацон, или они выдали 500-ю ошибку итд.

                        А может это вообще write and throw script.

                        А вот тут другое дело
                        try {
                          var petuh = getPetuh(askUserForFile());
                        }
                         catch (FileNotFound) {
                           System.stderr.print("Извините, такого файла нету, попробуйте снвоа");
                           doSomeUsefullLogic();
                           return RETRY;
                        } catch (BadJson) {
                           System.stderr.print("Извините, ваш json говно");
                           return FAIL;
                        }

                        Я явно выразил желание обработать исключения.

                        То-есть компилятор мне говорит: "чувак, вот эти три ошибки может вернуть фукнция"
                        А я ему: "вот эти две хочу обработать, а на эту пойху, можеш упасть".

                        Как тебе идея?
                        Ответить
                        • while (1) {
                            try {
                              var petuh = getPetuh(askUserForFile());
                            } catch (...) {
                               System.stderr.print("Ты питух");
                            }
                          }

                          Упростил логику, проверь.
                          Ответить
                              • понятно
                                ты заедушный анскилябр, который до такой степени не может в программирование, что даже не опнял, о чем тут речь

                                иди на ответы мейл ру, маня
                                https://otvet.mail.ru/question/67424596
                                Ответить
                                  • у меня за щекой чисто.
                                    Вероятно ты опять перепутал щеку своей мамы с моей щекой
                                    Ответить
                        • Х.з., во-первых ignore - не самый подходящий кейворд, больше о собачке напоминает чем о перевбросе.

                          Во-вторых - это же просто сахар для try-с-перевбросом.

                          Лучше уж возвращать Either с паттерн-матчингом в тех случаях, где это реально надо. И да, IoException и JsonException - это не те случаи, где это реально надо.
                          Ответить
                          • > - это же просто сахар
                            да
                            >Лучше уж возвращать Either с паттерн-матчингом
                            возможно, но мы же про эксепшены

                            >IoException и JsonException - это не те случаи,
                            да ну? и вот тут не надо? а как надо?
                            while (userWantsToContinue()) {
                             val petuh = getPetuh(askUserForFilePath());
                             print(petuh);
                            } catch (IOException ex) {
                               showError("Не удалось открыть файл:" + ex.getReason());
                            } catch (JSonException ex) {
                               showError("ваш файл невалиден на строке:" +  ex.getLine());
                            }
                            }
                            Ответить
                            • Ну и что теперь из-за редких случаев, где такая обработка нужна, заставлять всех, вообще всех её делать?

                              Хочешь ли ты показывать юзеру на какой строке сломан жсон в твоём описании пакета обновлений или ответе от сервера. Да нет конечно, он все равно ничего не сможет с этим сделать. Записать по catch-all в лог да и всё.

                              А JsonException примечателен тем, что полезный кейс у него ровно один. В момент парсинга. Во всех остальных местах, откуда его кидают, это просто ошибка программиста, которая не должна быть checked. В этом и вред cheched исключений.
                              Ответить
                              • Всё так.

                                Потому знание о том, должен-ли быть exception checked это не свойство класса, а семантика использования.

                                Сегодня он checked, завтра -- нет. Всё зависит от использования.

                                Вот тут это НЕ чекд эксепшен, а ошибка программиста
                                fromJson(getResource("manifest.json"));


                                А вот тут очень даже checked
                                fromJson(askUserForUrl());


                                Потому-то я и предложил определять это на уровне вызова функции посредством слова ignored.

                                Ну ок, давай назовём его unchecked.
                                Ответить
                                • > семантика использования

                                  Вот именно 🙂

                                  Если я поставил try - значит мне интересно это исключение. Если не поставил - значит нет.

                                  И тут мы приходим к выводу, что спецификации исключений не нужны.
                                  Ответить
                                  • Вопрос в том, как мне узнать какие вообще бывают исключения, и как случайно не проаебать интересное?

                                    И вот тут-то как раз спецификация нужна: нет ничего плохого в том, что я явно заигнорю неитересные мне исключения. А могу и не игнорить, а прокинуть
                                    Ответить
                                    • > случайно не проебать

                                      Ну это ж не сишка - солнце не потухнет, луна не наебнётся. Ну задаст тебе юзер вопрос о "неизвестной ошибке", ну разберёшь её по логу и добавишь обработчик.

                                      Х.з., имхо фича, которая заставляет писать и поддерживать бойлерплейт, должна приносить в замен очень много пользы. Иначе она тупо вредна и её не надо включать в язык.
                                      Ответить
                                      • Однажды я спросил питониста: как ему живется с утиной типизацией и отсутствием статической типизации? Не страдает ли он от проблем с неверными типами в рантайме?
                                        Не плохо ли ему от того, что IDE не может подсказать все методы объекта?

                                        Не напрягает ли его то, что "age + 2" может упасть в рантайме от того, что age это строка?

                                        Он ответил:

                                        Ну это ж не сишка - солнце не потухнет, луна не наебнётся. Ну задаст тебе юзер вопрос о "неизвестной ошибке", ну разберёшь её по логу и добавишь явный int().

                                        Х.з., имхо фича, которая заставляет писать и поддерживать бойлерплейт (явные касты, кучу интерфейсов, адаптеры итд), должна приносить в замен очень много пользы. Иначе она тупо вредна и её не надо включать в язык.
                                        Ответить
                                        • Ну собственно поэтому языки без статической типизации вполне себе живы и популярны. Если бы всё было так однозначно - их бы уже давно обоссали и сожгли.

                                          Но ты слишком высоко замахнулся.

                                          Checked exceptions - это мелкая фича на уровне "а давайте выкинем из крестов auto и и будем писать все типы явно, вдруг функция вернёт не тот тип, что мы ожидали". В общем-то порядок пользы и бойлерплейта совпадает.
                                          Ответить
                                          • Если бы всё плохое обссыкали и сжигали, то кругом был бы сплошной ocaml, а не электрон с джаваскриптом.

                                            Вывод типов -- не оч удачный пример, всё таки он проверяется статически: нельзя получить char, и вызвать у него метод foo();
                                            Да и IDE скорее всего выведет тебе тип.

                                            А где я могу узнать список возможных исключений? А как я убеждюсь, что я всё проверил?
                                            По документации?

                                            Это всё равно, как узнавать список методов по документации в скриптовых языках
                                            Ответить
                                            • > по документации

                                              Да, по документации. Как и кучу других констрейнтов на аргументы, результаты и сайд-эффекты которые большинство систем типов не позволяют описать.
                                              Ответить
                                              • >большинство систем типов не позволяют описать.

                                                И это плохо. Я мечтаю, например, о языке с системой эффектов.

                                                @Slow
                                                void slowMethod();
                                                
                                                void uiMethod() {
                                                 slowMethod()// не скомпилируется
                                                }
                                                
                                                @Accepts(@Slow)
                                                void runOnBackground(); 
                                                
                                                void uiMethod() {
                                                 runOnBackground( lambda{slowMethod()})// компилируется
                                                }


                                                О языках с явной обработкой ThreadSafe итд.

                                                Но если этого нет, то это не повод отказываться от того, что есть.

                                                Типа у нас и так нассано в подъезде, давайте я суда и насру еще?
                                                Ответить
                                            • Именно поэтому я за генерацию этой информации посредством IDE или специальных утилит.
                                              Ответить
                                            • З.Ы. Суть же не в том, чтобы все проблемы отловить. Суть в том, чтобы отловить максимум типичных проблем при минимуме бойлерплейта.

                                              /thread

                                              Пойду в дум ебашить.
                                              Ответить
                                • > unchecked
                                  ИМХО, такой подход не исправляет Фатальный Недостаток checked-исключений: если вдруг вызываемый метод отрефакторится и начнёт кидать ещё одно исключение, тебе придётся лазить по всем цепочкам вызовов и править все методы из цепочек. Это, мягко говоря, неудобно.
                                  Ответить
                                  • > и править все методы из цепочек.
                                    зачем?

                                    если я пометил unchecked, то вызывающий его метод может вообще ничего о нем не знать
                                    Ответить
                                    • Ничего не понял, приведи реальный пример.

                                      Вот есть метод A, который кидает TyHujException, есть метод B, который вызывает метод B:
                                      A() throws TyHujException:
                                          ...
                                      
                                      B():
                                          a = A()

                                      Тогда при checked-исключениях программист обязан либо поймать TyHujException на моменте вызова A(), либо не ловить, но добавить к сигнатуре B() «throws TyHujException». А как предлагаешь ты?
                                      Ответить
                                        • То есть проигнорированные («ignore (InvalidJson, FileNotFound)») исключения улетают наверх, но при этом в сигнатуру метода их добавлять не нужно? Как-то смысл тогда теряется: любой метод в итоге может выкинуть любое исключение, а чтобы понять какое — надо читать его код.
                                          Ответить
                                          • нет, не нужно.

                                            >Как-то смысл тогда теряется
                                            Почитай примеры из моего коммента.

                                            При вызове метода я могу выбрать одно из трех:
                                            * Передать обработку ошибок выше (написать throws)
                                            * Обработать их на месте (написать catch)
                                            * Сказать, что такой ошибки быть не может при нормальной работае программы. А если она случилась, то надо залогировать и сдохнуть. Для меня эта ошибка ничем не отличается от NPE. Это ignore.

                                            Такие ошибки ловить не нужно.
                                            >юбой метод в итоге может выкинуть любое исключение, а чтобы понять какое

                                            Не надо этого понимать. Если метод не сообщил через throws что он кидает -- то и ловить это отдельно не нужно.
                                            Ответить
                                              • Что ты про это думаешь?

                                                Боманду вон всё равно лениво писать везде "ignores"
                                                Ответить
                                                • Не знаю, голова плохо работает. С поверхностной точки зрения действительно выглядит как бойлерплейт. К тому же, малость туманны перспективы написания устойчивого кода, который вообще никогда не должен падать.
                                                  Ответить
                                                  • >устойчивого кода, который вообще никогда не должен падать.

                                                    Ну там жеж был пример.
                                                    У меня в ресурах .jar файла лежит файл petuh.json.

                                                    Я в коде пишу:
                                                    parseJson(getResource("petuh.json"));


                                                    Ты реально считаешь, что я должен обрабатывать как-то ошибку отсутсвия в моем джарнике файла?
                                                    Может, мне еще и ClassNotFound обработать?
                                                    Ответить
                                                    • Задачи разные бывают. К тому же, падать тоже можно по-разному: показать пользователю красивое окошко с телефоном саппорта и диагностической информацией, например. То есть нужен механизм, который бы позволял отлавливать все исключения, включая проигнорированные.
                                                      Ответить
                                                      • Разумеется, такой смеханизм есть.

                                                        Ты можешь сделать catch(Exception) наверху стека или явно зарегистрировать хендлер исключений у потока.

                                                        И там показать 500ю, или красивое завершение программы с телефоном суппорта, или писнуть в лог, или упасть со стектрейсой если это твой райт-н-сроу.

                                                        Как моя идея этому мешает?

                                                        ignores это просто сахар для оборачивания checked в Runtime без засирания cause
                                                        Ответить
                                                        • Тогда такая система разрушает основное преимущество checked исключений: мы не знаем, какая ошибка может вылететь из очередного getPetuh(): это может быть либо то, что у него в throws, либо какое-то внутреннее исключение, которое он проигнорировал. Чтобы понять какое — надо копать либо исходники, либо документацию.
                                                          Ответить
                                                          • Блин, я не знаю уже как объяснить)

                                                            getPetuh разумеется сообщает о вылетающих ошибках посредством "throws", а его клиент может их тут же задавать через ignore.

                                                            Генеральная мысль такая: любое checked исключение в любой момент можно начать считать НЕ checked не засирая им сигнатуры по стеку вызовов)

                                                            > либо какое-то внутреннее исключение, которое он проигнорировал.

                                                            зачем? зачем это знать?
                                                            не надо этого знать

                                                            если проигнорировал -- значит он считает, что как-то особо обрабатывать это не надо

                                                            ты всегда читаешь код метода в поисках NPE чтобы его поймать?
                                                            Ответить
                                                            • Почему именно petuh? Это священное животное? И почему гендерная несправедливость?
                                                              Ответить
                                                            • > getPetuh разумеется сообщает о вылетающих ошибках посредством "throws", а его клиент может их тут же задавать через ignore.
                                                              Я рассматриваю не два уровня, а три. getPetuh() сообщает об ошибке InternalPetuhError посредством throws, getKuryatnik() вызывает getPetuh() и игнорирует InternalPetuhError (не засирая им свою сигнатуру), doWork() вызывает getKuryatnik() и не может понять, откуда ему прилетело InternalPetuhError.

                                                              Весь смысл check-исключений можно свести к двум утверждениям:
                                                              1) Для любого вызова гарантируется, что он не приведёт к аварийному завершению работы программы;
                                                              2) Для любого вызова гарантируется, что программист рассмотрел все возможные ошибки и решил, что с ними делать.
                                                              Таким образом, сочетание двух этих гарантий позволяет создавать максимально надёжный код: любая возможная ошибка в конце концов будет где-то обработана программистом. При этом благодаря второму утверждению программисту удобнее обработать ошибку как можно раньше.

                                                              А с возможностью проигнорировать какие-то исключения получается, что обе этих гарантии перестают работать: любой вызов может выкинуть какую-то левую фигню, не указанную в throws.
                                                              Ответить
                                                              • >и не может понять, откуда ему прилетело InternalPetuhError.
                                                                Зачем ему это понимать?

                                                                А вдруг ему прилетит NPE? Он тоже должен его как-то особо обрабатывать?

                                                                >Для любого вызова гарантируется, что программист рассмотрел все возможные ошибки и решил, что с ними делать

                                                                Не все ошибки. Например, ошибку OutOfMemory программист не рассматривает. И NPE Тоже.
                                                                Любая функция может их выкинуть.
                                                                Понимаешь?
                                                                Ответить
                                                                • > А вдруг ему прилетит NPE? Он тоже должен его как-то особо обрабатывать?
                                                                  Конечно, почему нет?

                                                                  > Не все ошибки. Например, ошибку OutOfMemory программист не рассматривает. И NPE Тоже.
                                                                  А не надо решать за программиста, что ему нужно рассматривать, а что не нужно. Программа вполне может при получении OOM попытаться, например, снизить разрешение текстур.

                                                                  > Любая функция может их выкинуть.
                                                                  А какой вообще тогда смысл в checked исключениях? Зачем писать весь этот бойлерплейт, если получившаяся программа ничем не отличается от таковой без бойлерплейта? Что первая, что вторая могут рандомно упасть из-за рандомной необработанной ошибки. Информацию о типах выбрасываемых исключений спокойно можно найти в доке (если это нормальная дока, а не говно) либо вообще заставить это делать конпелятор.
                                                                  Ответить
                                                                  • >Конечно, почему нет?

                                                                    То-есть ты всегда пишешь catch(NPE) вокруг каждого метода?

                                                                    >А не надо решать за программиста, что ему нужно рассматривать, а что не нужно.
                                                                    Ради бога, лови всё, что угодно. Важно, что checked ты должен или явно поймать, или явно сказать, что это не являетчся для тебя проблемой. Что там будут делать наверху не важно.

                                                                    >А какой вообще тогда смысл в checked исключениях?
                                                                    Я вижу, что ты меня вообще не понимаешь((
                                                                    Видимо, у меня проблемы с объяснением идеи (при том что Борманд, кажется, понял)
                                                                    Почитай еще раз
                                                                    https://govnokod.xyz/_26533/#comment-519175

                                                                    * Функция для парсинга JSON может вернуть ошибку что JSON невалиден
                                                                    * Пользователь функции обязан ее обработать или явно сказать, что обрабатывать ее не хочет (потому что json он до этого проверил, например)
                                                                    * Не обработанные исключения ловятся где-то наверху, и приводят к сообщениям об ошибке, записи в логи итд
                                                                    * Но есть так же ошибки, которые обычно не обрабатывают, потому что знают, что в нормальной программе их нет (NPE)
                                                                    * Такие ошибки называютися Runtime
                                                                    * Я утверждаю, что тип (checked или runtime) должен определяться не классом, а использованием.
                                                                    * реальный пример
                                                                    https://govnokod.xyz/_26533/#comment-519209
                                                                    Ответить
                                                                    • > То-есть ты всегда пишешь catch(NPE) вокруг каждого метода?
                                                                      Когда нужно — я и векторные исключения ставлю, чтобы «сегфолты» ловить.

                                                                      Да, я понял, что «одноуровневые» исключения хорошо ложатся на такую систему. Однако уже для двухуровневых (A() вызывает B(), который вызывает C(), который кидает исключение) её смысл по большей части исчезает, и она становится простым бойлерплейтом.
                                                                      Ответить
                                                                      • Да ставь пожалуйста, как мое решение тебе мешает?

                                                                        >трехуровневые
                                                                        и что? ну пиши везде throws, и будет точно так же, как и раньше.

                                                                        Если ты хочешь, что бы клиент твоей функции как-то обработал исключение -- ставь throws.
                                                                        Если не хочешь -- не ставь.

                                                                        Клиент может обработать и без throws, но со throws он обязан или обработать или явно от этого отказаться.

                                                                        Приведи реальный прмиер, где моя система не работает
                                                                        Ответить
                                                                        • >>> getPetuh() сообщает об ошибке InternalPetuhError посредством throws, getKuryatnik() вызывает getPetuh() и игнорирует InternalPetuhError (не засирая им свою сигнатуру), doWork() вызывает getKuryatnik() и не может понять, откуда ему прилетело InternalPetuhError.
                                                                          В этом случае нет абсолютно никакой разницы: что есть checked исключения, что их нет. А бойлерплейт есть.
                                                                          И ты никак, без чтения сорцов, не узнаешь, что автор какой-то говнолибы решил проигнорить какое-нибудь ConnectionTimeout.

                                                                          Беда checked исключений с ignore() в том, что они заставляют писать столько же бойлерплейта, что и checked исключения без ignore(), но при этом обеспечивают гораздо меньше безопасности.
                                                                          Ответить
                                                                          • >и не может понять, откуда ему прилетело InternalPetuhError.

                                                                            Зачем ему это понимать?
                                                                            Он ничего не знает о питухах: Он дергает getKuryatnik.
                                                                            Его вообще не должно ебать что там и откуда прилетает.

                                                                            >только же бойлерплейта
                                                                            нет, не столько же.

                                                                            Ладно, мы по кругу ходим. Видимо мне надо более подробно объяснить мысль, либо дождаться Борманда, и попросить его перевести (раз уж он понял)
                                                                            Ответить
                                                                            • Ну ладно, спать пойду. Спокойной ночи!

                                                                              ДОБРОЕ ИМЯ ДОБРАЯ СЛАВА В ЧЕСТИ 1024--, тебе тоже.
                                                                              Ответить
                        • З.Ы. В сишке необработанная ошибка вызывала UB, продолжала исполнять код успешной ветки и творить хуйню. Поэтому там все дрочат на обработку ошибок.

                          В языках с исключениями, в отличие от сишки, нельзя забыть обработать ошибку - необработанное исключение не триггерит UB. Поэтому пользы от checked exceptions, имхо, меньше чем вреда.
                          Ответить
                        • > То-есть компилятор мне говорит: "чувак, вот эти три ошибки может вернуть фукнция"
                          Если компилятор вычислит это, сам, будет очень хорошо.
                          Я не хочу читать весь список ошибок, а потом ещё сверять его с ошибками, которые могут добавлять внешними питухами.

                          Например, если мы передаём в фукнцию другую функцию или объект, то при вызове этой функции или метода объекта может вылезти исключение, которое функция не бросает. И набор исключений зависит не от того, что написал автор, а от того, что написали автор с пользователем, а также от питушни вроде кодовставок внутри #ifdef.
                          Ответить
                          • было бы хорошо, если бы выводил
                            но увы

                            приведенный тобою пример не решается на той системе, которая есть у джавы, потому что нельзя сказать, что выбрасываемое методом исключение зависит от параметра. А если бы можно было например так
                            (псевдокод)
                            runOnBackground(runnable: [Runnable throws T]) throws T

                            было бы классно, но увы.
                            Ответить
                              • хуйни какой-то написал. короче, в джаве дженерики можно использовать и для выбрасываемых исключений. но всё равно это нихуя не работает, потому что дженерик-то один, а выбрасываешь ты какие-нибудь IOException, OrderException, AdminPetuhException. в юнион-тайпы еще не научились.
                                Ответить
          • Было бы прикольно иметь удобный список типов ошибок, которые могут прилететь (и я сейчас не про документацию, которой обычно нет). А заставлять проверять на каждый чих это конечно странно.
            Ответить
        • З.Ы. Меня тут больше беспокоит, что не заставили написать ToString() для исключения. В итоге в логе будет какая-нибудь хуйня вместо HttPException(500). Или шарп умный и сам все поля исключения вываливает в трейс?
          Ответить
          • ту стринг не поможет

            namespace dotnent_test
            {
                class MyException : Exception
                {
                    public String Name { get; }
            
                    public MyException(String name)
                    {
                        this.Name = name;
                    }
            
                    public override string ToString()
                    {
                        return base.ToString() + Name;
                    }
                }
            
                public class MyClass
                {
            
                    public static void Main(string[] args)
                    {
                        throw new MyException("Foo");
                    }
                }
            }
            
            
            Unhandled Exception: dotnent_test.MyException: Exception of type 'dotnent_test.MyException' was thrown.
               at dotnent_test.MyClass.Main(String[] args) in C:\Users\petuz\source\repos\dotnent_test\dotnent_test\Program.cs:line 23
            Ответить
            • Унылая хуйня этот ваш c#. Почему они не могли залогировать сообщение из исключения?
              Ответить
              • Может, у меня руки кривые
                Я не шарпей так-то
                Ответить
              • > Унылая хуйня этот ваш c#.
                Вот сейчас обидно было. В приведенном выше примере сообщение не залогировалось, потому что никакого сообщения в исключении нет. В консоль вываливается содержимое проперти «Message», ToString() тут вообще никаким боком. Кастомное исключение можно сделать примерно так:
                using System;
                
                namespace ConsoleApp
                {
                    class Program
                    {
                        static void Main(string[] args)
                        {
                            throw new MyException("Foo", "Bar");
                        }
                
                        class MyException : Exception
                        {
                            public MyException(string name, string myMessage) : base($"Name: {name}, message: {myMessage}") { }
                        }
                    }
                }

                Вывод в сосноль:
                Unhandled exception. ConsoleApp.Program+MyException: Name: Foo, message: Bar
                   at ConsoleApp.Program.Main(String[] args) in C:\Users\user\source\repos\ConsoleApp\Program.cs:line 9
                Ответить
                • лол, и правда. Я обосрался довольно сильно: .net же не знает про мои кастомные поля.

                  Спасибо, что исправил.

                  хотя было бы логично выволить туда toString
                  Ответить
  • Почитал тред, и мне как-то больше стал нравиться подход C.
    Исключения либо ещё слишком мало понятны народу (как табы), либо могут использоваться только в очень хорошо спроектированном коде, и не каждый проект может быть того масштаба, когда исключения действительно помогают, а не запутывают.

    Это же банальное нарушение структурного и процедурного программирований, нарушение инкапсуляции. Внутренняя питушня может легальным образом произвольно повлиять на все слои абстракции над ней. Какое-то говно.

    А потом приходят полуборманды и говорят, что не будут ловить исключения, пусть пользователи их библиотек разгребают то, что было кинуто питушнями, которые использовали использованные полубормандами библиотеки.
    А потом приходят борманды и говорят, что не будут ловить эту питушню и попросят уже конечного пользователя сообщить о проблеме 0xCCD3208EF Invalid call.

    То ли дело сишка, где имеем либо кривое говно, либо корректный код, который не может вернуть что-то, что не указано в документации или в определении функции.
    А в языках с исключениями кривое говно называют библиотеками.
    Ответить
    • Обработай ещё раз этот ебучий код возврата да верни его.

      Что с исключениями что без них код работает совершенно одинаково. Просто в варианте с исключениями не надо обмазывать каждый вызов бойлерплейтом. И можно приложить чуть больше инфы, чем просто инт.
      Ответить
    • Возвращаемый код можно случайно забыть проверить. Вроде как все согласны с тем, что лучше всего это момомомомонады с папапапапатернт матчингом.
      Ответить
      • Можно забыть проверить, но это сразу воспринимается как грех.
        А вот исключения постоянно забывают проверить, поэтому наружу лезет какая-то питушня из кишок библиотек. И это считается нормальным.

        Вариант с монадами отличный. Там и пердолиться руками надо много меньше, и забыть проверить невозможно. Ты точно знаешь, что возвращает функция, нет никакого протыкания инкапсуляции.
        Ответить
        • Подтверждаю. Вообще, ситуация, когда я вызываю метод библиотеки A, а мне в ответ прилетают кишки библиотеки B, которую я даже не устанавливал явно — это какое-то ненормальное поведение.
          Ответить
          • Почему кишки, если тебе в любом случае прилетает часть публичного интерфейса (о его качестве сейчас речь не идёт)?
            Ответить
            • Потому что это детали реализации библиотеки A, которые меня ну вообще никак не касаются.
              Более того, если завтра авторы библиотеки A поменяют библиотеку B на библиотеку C — всем клиентам придётся менять catch (B_Exception) на catch (C_Exception) — при том, что публичный интерфейс библиотеки A не меняется никак, меняются детали реализации. И это пиздец.

              UPD: я, как клиент библиотеки A, вообще не должен знать об особенностях её реализации (в частности, какие она там использует библиотеки) ничего. А пробрасываемые исключения этот принцип успешно похеривают.
              Ответить
              • > Более того, если завтра авторы библиотеки A поменяют библиотеку B на библиотеку C — всем клиентам придётся менять catch (B_Exception) на catch (C_Exception) — при том, что публичный интерфейс библиотеки A не меняется никак, меняются детали реализации.

                О_о ну вообще-то публичный интерфейс поменялся. То, что этого тебе не скажет компилятор, говорит просто о том, что компиляторам стоит в этом плане ещё есть куда расти. А так - документация, которая, на мой взгляд, тоже является частью публичного интерфейса.

                > я, как клиент библиотеки A, вообще не должен знать об особенностях её реализации
                - это очень смелое заявление.
                Ответить
                • Поменялся не публичный интерфейс, поменялись детали реализации.

                  > это очень смелое заявление.
                  И совершенно верное. Или я что-то пропустил, и банальная инкапсуляция вышла из моды?

                  Авторы нормальных либ, кстати, эту проблему прекрасно понимают, и исключения из своих кишок не пробрасывают:
                  >>> import requests
                  >>> dir(requests.exceptions)
                  ['BaseHTTPError', 'ChunkedEncodingError', 'ConnectTimeout', 'ConnectionError', 'ContentDecodingError',
                  'FileModeWarning', 'HTTPError', 'InvalidHeader', 'InvalidProxyURL', 'InvalidSchema', 'InvalidURL', 'MissingSchema',
                  'ProxyError', 'ReadTimeout', 'RequestException', 'RequestsDependencyWarning', 'RequestsWarning', 'RetryError',
                  'SSLError', 'StreamConsumedError', 'Timeout', 'TooManyRedirects', 'URLRequired', 'UnrewindableBodyError', ...]


                  Но сама возможность такого — говно.
                  Ответить
                  • > Поменялся не публичный интерфейс, поменялись детали реализации.
                    - у тебя другие исключения могут прилетать. Повторюсь: дока, где это должно быть описано, это тоже часть публичного интерфейса.

                    > Или я что-то пропустил, и банальная инкапсуляция вышла из моды?
                    - это уже не инкапсуляция, это уже изоляция какая-то. Допустим, по поводу обычных типов и методов я с тобой соглашусь. Но исключения они на то и исключения, что они демонстрируют исключительную ситуацию. Зачем мне затенять то место, откуда стрельнуло что-то исключительное?

                    > Авторы нормальных либ
                    > нормальных
                    - пошла вкусовщина.
                    Ответить
                    • > Повторюсь: дока, где это должно быть описано, это тоже часть публичного интерфейса.
                      Значит, в публичный интерфейс пролезли детали реализации. Это тоже эталонное говно.

                      > это уже не инкапсуляция, это уже изоляция какая-то
                      Нет, это в точности инкапсуляция. Сокрытие деталей реализации, алло, это пишут в любой книжке «ООП за 20 минут»!

                      > Зачем мне затенять то место, откуда стрельнуло что-то исключительное?
                      Затем, что это место никак не касается клиентов библиотеки. Если из метода A::F() мне прилетело исключение — это значит, что в исключительную ситуацию попал метод A::F(). Именно A::F(), метод из библиотеки A!

                      > пошла вкусовщина
                      Это не вкусовщина, это реальный пример правильно сделанных исключений.
                      Ответить
                      • > Значит, в публичный интерфейс пролезли детали реализации. Это тоже эталонное говно.
                        - значит, почти любая документация состоит на 90% из эталонного говна (по мнению gost'а).

                        > это место никак не касается клиентов библиотеки.
                        - откуда ты знаешь, касается оно или нет? Ты в курсе тонкостей всех охулиардов проектов на матушке Земле? Ну камон, не будь таким Нарциссом
                        Ответить
                        • > почти любая документация
                          > на 90%
                          [citation needed]

                          > откуда ты знаешь, касается оно или нет?
                          Оттуда, что это самые основы ООП. Оттуда же, откуда знаю, что нельзя дёргать приватные члены чужих классов.

                          > Ты в курсе тонкостей всех охулиардов проектов на матушке Земле?
                          Мне не нужно быть в курсе тонкостей всех охулиардов проектов, чтобы понимать, что раскрытие деталей реализации — это говно. В любом случае говно.
                          Ответить
                          • > [citation needed]
                            https://en.cppreference.com/w/cpp/algorithm/sort

                            1) Elements are compared using operator<


                            деталь реализации? Деталь.

                            See execution policy for details.


                            заходишь, а там

                            If the implementation cannot parallelize or vectorize (e.g. due to lack of resources), all standard execution policies can fall back to sequential execution.


                            Чо, не деталь реализации?

                            > Оттуда же, откуда знаю, что нельзя дёргать приватные члены чужих классов.
                            - а чего ты вдруг заговорил про приватные члены, если типы исключений у нас публичные?

                            > раскрытие деталей реализации — это говно
                            - даже если это не противоречит здравому смыслу, но противоречит книжке "ООП за двадцать минут"?
                            Ответить
                            • > деталь реализации? Деталь.
                              Вовсе нет. Это описание публичного интерфейса элементов, который ожидает эта функция. С тем же успехом деталью реализации можно назвать типы входных параметров.

                              > Чо, не деталь реализации?
                              И опять нет. Здесь описывается наблюдаемое поведение политик.

                              Впрочем, ладно: детали реализации действительно могут быть добавлены в документацию. Однако это должны быть просто справочные материалы, на которые никак нельзя опираться при разработке программы-клиента. Например, как здесь: https://en.cppreference.com/w/cpp/algorithm/for_each (раздел «Possible implementation»).

                              > а чего ты вдруг заговорил про приватные классы, если типы исключений у нас публичные?
                              Потому что приватные члены класса — это детали его реализации, и используемые внутренние библиотеки — тоже детали реализации библиотеки.

                              > даже если это не противоречит здравому смыслу
                              Это противоречит здравому смыслу. Чем больше деталей реализации раскрывается клиентам библиотеки (причём раскрывается так, что клиенты становятся зависимы от них) — тем труднее становится детали реализации поменять. А простота смены внутренней реализации — это самое главное преимущество, которое обеспечивает инкапсуляция.
                              Ответить
                              • > Вовсе нет. Это описание публичного интерфейса элементов, который ожидает эта функция.
                                - это ты сам придумал, в доке такого нет. Там написано, что сравнение происходит при помощи такого-то оператора и гуляйте.

                                > наблюдаемое поведение
                                - поведение это не реализация?

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

                                А безболезненная смена внутренней реализации, при которой мы кишки поменяли и никто не заметил, бывает только на проектах на 10 файлов.
                                Ответить
                                • > это ты сам придумал, в доке такого нет. Там написано, что сравнение происходит при помощи такого-то оператора и гуляйте.
                                  В мире «C++» это и есть описание публичного интерфейса, потому что перегруженные операторы — это его часть.

                                  > поведение это не реализация?
                                  Поведение — это не реализация.

                                  > Библиотека может оборачивать исключения
                                  Хорошая библиотека.

                                  > а может не оборачивать
                                  Говно.

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

                                  > мы живём в неидеальном мире хаков, костылей и всяких трюков
                                  Да. Хаки, костыли и «всякие трюки» — это говно. Говно, от которого надо избавляться и которое уж точно не надо плодить. В точности следуя твоей логике, все члены любых классов должны быть публичными — ведь мы же живём в неидеальном мире хаков, костылей и всяких трюков, и своей приватностью их все ломаем!
                                  Проводя аналогии, мы живём в неидеальном мире фастфуда, колы и всяких чипсов. Означает ли это, что здоровое питание нинужно?

                                  > А безболезненная смена внутренней реализации, при которой мы кишки поменяли и никто не заметил, бывает только на проектах на 10 файлов.
                                  Нет. Если внутренняя реализация не пролазит в публичный интерфейс — её можно спокойно менять. В таком случае, даже если какой-то говнокодер завязал на неё свой код — это будут исключительно его проблемы, у нормальных людей всё будет работать.
                                  Ответить
                                  • > Поведение — это не реализация.
                                    - а что тогда?

                                    > И таким образом он намертво себя прикручивает к деталям реализации библиотеки.
                                    - ну и хер с ним. Мне сидеть дрожать 10 лет над тем, что у моих зависимостей сменятся зависимости, или иметь ништяки уже сегодня?

                                    Ну и так-то конечный код всё равно придётся перекомпилировать, если речь про кресты etc.
                                    Культ карго какой-то.

                                    > Проводя аналогии
                                    - не надо, пожалуйста, проводить аналогии, потому что обычно, как и в этом случае, они хуёвы и абсолютно неуместны. Здоровое питание это такая же маркетинговая хуета, как и оопэшные мантры про повсеместную инкапсуляцию.

                                    > все члены любых классов должны быть публичными
                                    - да, потому что инкапсуляция должна быть на уровне модулей, а не типов, но это отдельный разговор.

                                    > Нет.
                                    - хватит троллировать. Ладно бы ты был каким-то рандомным неосилятором, а серьёзному кабальеро писать такую ересь должно быть стыдно.
                                    Ответить
                                    • > Ну и так-то конечный код всё равно придётся перекомпилировать, если речь про кресты etc.
                                      - ну хотя тут я немного напиздел для случаев динамической линковки.
                                      Ответить
                                    • > - а что тогда?
                                      Поведение.

                                      > ну и хер с ним. Мне сидеть дрожать 10 лет над тем, что у моих зависимостей сменятся зависимости, или иметь ништяки уже сегодня?
                                      То есть ты за написание неподдерживаемого говнокода, главное — шоб побыстрее? Ну ок, предлагаю тебе переехать на «PHP» и писать перед каждым методом собачку.

                                      > Ну и так-то конечный код всё равно придётся перекомпилировать, если речь про кресты etc.
                                      Зачем? Зачем? В случае крестов придумали «pimpl».

                                      > не надо, пожалуйста, проводить аналогии, потому что обычно, как и в этом случае, они хуёвы и абсолютно неуместны
                                      Нет, это абсолютно точная аналогия.

                                      > Здоровое питание это такая же маркетинговая хуета
                                      Что, прости?! То есть все вот эти вот биологи с диетологами, которые занимаются темой здорового питания — маркетинговая хуета? И рекомендации ВОЗ — тоже? И даже, например, https://thl.fi/documents/189940/1496849/north_karelia_project.pdf/bb7ba7aa-1dc2-4319-90b9-d2c3ddc10d5e?

                                      > да
                                      А, ну понятно. Тогда тебе точно стоит перейти на «PHP».

                                      > хватит троллировать
                                      По-моему, троллирую тут не я, а человек, называющий инкапсуляцию культом карго.
                                      Ответить
                                      • Поведение основано на реализации, оно и есть реализация.

                                        Да, диетологи это по большей части хуета (но не все, разумеется). ВОЗ шаражкина контора про отмывание бабла в глобальных масштабах. Инкапсуляция без повода это культ карго. PHP - говно, сам на него переходи 🙂

                                        > А, ну понятно.
                                        - нет, не понятно, потому что комментарии лучше читать целиком. На этом откланиваюсь, потому что разговор потерял последние остатки конструктива.
                                        Ответить
                                        • > Поведение основано на реализации
                                          Да.

                                          > оно и есть реализация
                                          Нет. Наблюдаемое поведение зависит от реализации, но не является ею. Точно так же, как результат выполнения функции зависит от её реализации, но не является ею.

                                          > Да, диетологи это по большей части хуета (но не все, разумеется). ВОЗ шаражкина контора про отмывание бабла в глобальных масштабах.
                                          Ну то есть ты считаешь, что рацион человека никак не сказывается на его, человека, здоровье?

                                          > Инкапсуляция без повода это культ карго.
                                          Не бывает «повода» для инкапсуляции. Бывают детали реализации, их надо скрывать — всё. Детали реализации, просачивающиеся в публичный интерфейс — априори говно, такого надо избегать.
                                          Ну да, разумеется, в нашем неидеальном мире не всегда получается делать всё так, как надо. Однако это совсем не означает, что к этому не надо стремиться. Если есть выбор между говном и не говном — нужно выбирать не говно. Нет выбора — увы, придётся писать говно. Только говно от этого не станет нормой.
                                          Ответить
                                          • Я всё же воспользуюсь принципом "уходя уходи" и покину дискуссию. Когда все подостынут, можно будет продолжить более продуктивно, если возжелается.
                                            Ответить
                                            • Как можно остыть и выкинуть в мусорку инкапсуляцию?

                                              Допустим, все наши познания - предрассудки. Но тогда нужен хотя бы хороший пример того, как написали успешную программу без инкапсуляции, которая пережила все правки, и вообще поддерживается без проблем.

                                              Я (говнокодер-с) только недавно правил питушню, которая была более-менее инкапсулирована, но всё равно вылезла в 3 дополнительных места. Только попердолился больше с кодом, никаких плюсов от недостатка инкапсуляции не получил.
                                              Ответить
                                          • >> ВОЗ шаражкина контора про отмывание бабла в глобальных масштабах.
                                            > Ну то есть ты считаешь, что рацион человека никак не сказывается на его, человека, здоровье?
                                            Кстати, может быть два варианта сразу.
                                            1. Бабло массово отмывается на питушне, которая на 0.0001% полезнее обычного питухания.
                                            2. Если кто-то жрёт радий или регулярно пьёт колу, умирает от неправильного питания.
                                            Ответить
                                          • > Ну то есть ты считаешь, что рацион человека никак не сказывается на его, человека, здоровье?
                                            - я тебе так отвечу: Стив Джобс был лучший диетолог ЕВПОЧЯ
                                            Ответить
                                            • Это который решил лечиться альтернативной медициной и умер в 56?
                                              Ответить
                                              • И это тоже.

                                                Но вообще это который всем рассказал, какой телефон им нужен и как правильно его держать.
                                                Ответить
                                                • Это несколько из другой оперы. Какой мне нужен телефон — это чистый субъективизм, какой хочу — такой и нужен. А вот человеческое тело нифига не субъективно. Человек — это сложный биологический механизм, который, тем не менее, вполне себе подчиняется определённым физическим, химическим, биологическим и так далее законам. И вот над выведением этих самых законов и работают биологи, диетологи, анатомы, патологоанатомы и прочие хорошие люди. Работают они достаточно успешно, например, как говорит нам «Википедия»,
                                                  Первым полномасштабным исследованием, подтвердившим, что
                                                  здоровое питание может значительно снизить проблемы с
                                                  сердечно-сосудистыми заболеваниями, ожирением и диабетом,
                                                  стал проект «Северная Карелия», проведение которого стартовало
                                                  в Финляндии в 1973 году. За 35 лет у населения области Северной
                                                  Карелии смертность от сердечно-сосудистых заболеваний снизилась
                                                  в 7 раз. Этот результат лёг в основу общеевропейской Стратегии
                                                  по здравоохранению 2020.

                                                  — ссылку на подробное описание этого проекта я кидал выше.

                                                  Но в общем-то да, никто не может сказать тебе, какое питание тебе нужно. Зато вполне успешно могут сказать, что если (условный) ты будешь регулярно кушать жареное мясо на ночь, то в итоге получишь определённые… осложнения.
                                                  Ответить
                                        • Что такое поведение?

                                          f(x) = 2*x
                                          f(x) = x+x

                                          f(2) == 4 - это поведение? Если да, то поведение одно, а реализации две, поведение отходит к интерфейсу, реализация забивается в угол.
                                          Ответить
                                          • > f(2) == 4 - это поведение?
                                            - это вореции.

                                            Поведение у двух функций разное, разумеется. Иначе тебе придётся доказывать, что сложение и умножение это одно и то же.
                                            Ответить
                                  • Помнишь, тут была недавно история про rust-ера, который выпилил свою репу из-за травли? Вот твой безапелляционный спич мне напоминает тех растофанатиков, которые его доебали. Потому что надо делать не так, чтобы оно работало, а так, как кому-то нравится, правда?
                                    Ответить
                                    • > Потому что надо делать не так, чтобы оно работало, а так, как кому-то нравится, правда?
                                      В идеале, надо делать так, чтобы было правильно. В реальности — правильно настолько, чтобы уложиться в сроки.
                                      Инкапсуляцию, SOLID и вот эти вот все «баззворды» придумали не просто так. Их проектировали умные люди специально для того, чтобы менее умные люди (или просто те, кому лень тратить время на переизобретение одного и того же) могли писать корректный, расширяемый и поддерживаемый код. Увы, но попытки забить на всё и говнокодить как придётся, «шоб работало», приводят только к созданию неподдерживаемого говнокода.
                                      Ответить
                                      • Если код не писать, а только делать кодревью и умничать, то все баззворды конечно принимают новое звучание. А так-то умные люди сначала спроектировали инкапсуляцию, а потом решили добавить friend classes, а другие умные люди решили, что вообще ничего проектировать не надо, а достаточно naming convention добавить 😀 А вы мне ещё насыпьте, пожалуйста, этих французских булок, потому что я смотрю бинарное мышление достигло апогея и теперь выражается как "как сказал gost, то есть, правильно" - "как gost не говорил, то есть, говно и шоб работало".
                                        Ответить
                                        • Одно дело - инкапсуляция, которая в большем количестве случаев полезна и действует не только с C и Java, но и в JS. Она действует и в ПП, и в ФП, и в ООП. Это общий принцип. И он проверен настолько же хорошо, насколько закон Ома.

                                          Другое дело - конкретная реализация в языке, где держат обратную совместимость, вставляют фичи средним арифметическим разумом комитета.
                                          Ответить
                                        • Честно говоря, я крайне удивлён, что мне приходится кому-то объяснять, что нарушение инкапсуляции — это плохо. Это же самые базовые принципы проектирования систем. Дальше-то что — доказывать вред god-object'ов? Или магических констант? Или на реальных примерах показывать, что нужно писать тесты?

                                          И не надо во всём обвинять бедного Госта. Инкапсуляцию придумали совсем другие люди — я тогда ещё не родился.
                                          Ответить
                                          • Хз, я тоже не понимаю, зачем ты уже два десятка комментариев настрочил вместо того, чтобы просто согласиться, что пробрасывать исключения наверх это ок.

                                            А остальной снобизм свой оставь пожалуйста для учеников на уроке информатики или первокурсников, которым ты возможно втираешь эту дичь.
                                            Ответить
                                            • Проброс наверх чужих исключений, являющихся частью внутренней либы — это нарушение инкапсуляции. Нарушение инкапсуляции — это плохо. Проброс наверх чужих исключений, являющихся частью внутренней либы — это плохо.
                                              По-моему, это достаточно очевидная цепочка.

                                              Ты правда считаешь, что перечисленные мной god-object'ы и магические константы — это ОК, тесты писать не нужно, а кто утверждает обратное — тот сноб?
                                              Ответить
                                              • Что ты будешь делать, если не все исключения из зависимости надо пробрасывать 1-в-1? Городить какой-то ArbitraryException? А как ты будешь передавать метаданные туда? Напишешь на каждом уровне, где добавляется обёртка, по дополнительной структуре? А что, если у тебя глубина дерева зависимостей больше единицы? Ты построишь целый фреймворк, который будет обёртывать исключения?

                                                И потом ты собираешься это поддерживать, правда?

                                                > Ты правда считаешь, что перечисленные мной god-object'ы и магические константы — это ОК, тесты писать не нужно, а кто утверждает обратное — тот сноб?

                                                - нет, я так не считаю. God object это плохо, магические константы это тоже плохо, тесты писать конечно нужно, но тут уж как получается. Объясни только, пожалуйста, какое отношение это имеет к инкапсуляции? Она от констант и богообъектов вроде никак не спасает.
                                                Ответить
                                                • > Что ты будешь делать, если не все исключения из зависимости надо пробрасывать 1-в-1?
                                                  Их не надо «пробрасывать». Их надо обрабатывать согласно логике моего кода. Потому что если в моём методе появилось исключение, то это значит, что какая-то часть моего метода работает неправильно, и сообщить клиенту нужно именно об этом — соответствующим исключением, со всеми нужными метаданными.

                                                  > А что, если у тебя глубина дерева зависимостей больше единицы? Ты построишь целый фреймворк, который будет обёртывать исключения?
                                                  Нет, я буду обрабатывать исключительные ситуации в моём коде. В этом и состоит сила инкапсуляции: мне совершенно безразлично, какая там у используемой мной библиотеки глубина зависимостей. Я обращаюсь к библиотеке за каким-то результатом — и абсолютно не важно, как она его считает и какие либы вызывает. С исключительными ситуациями должна быть та же картина: я обращаюсь к библиотеке и ожидаю, что именно она мне скажет, что у неё произошла ошибка. А произошедшую ошибку я обработаю и выдам своему клиенту уже свою ошибку, которая будет описывать исключительную ситуацию в моём коде.

                                                  Да, это идеальная картина. В реальности же авторы либ* зачастую нарушают инкапсуляцию, в результате чего их клиентам приходится городить хаки и костыли, пихая в код совершенно ненужную для решения задачи информацию.
                                                  *И я тоже не безгрешен, разумеется, и тоже пишу говнокод. Увы, идеала не бывает — но это не значит, что к нему не надо стремиться.

                                                  > Объясни только, пожалуйста, какое отношение это имеет к инкапсуляции?
                                                  God-object'ы, магические константы, нарушения инкапсуляции — это сущности одного порядка, антипаттерны.
                                                  Ответить
                                                  • > Потому что если в моём методе появилось исключение, то это значит, что какая-то часть моего метода работает неправильно

                                                    - почему это неправильно работает часть твоего метода? Эксепшн-то кинул не он. Ну, то есть, наверное, в условном идеальном ФП без побочек виноват будет твой метод, но обычно стрелять может откуда угодно и кто угодно.

                                                    Я правильно понимаю, что ты рассматриваешь любую исключительную ситуацию как исключительную ситуацию в твоём коде? Ну, это тоже подход, наверное.

                                                    > мне совершенно безразлично, какая там у используемой мной библиотеки глубина зависимостей.
                                                    - вопрос был скорее про случай, когда ты сам и есть автор этих зависимостей. То есть, когда из цепочки A <- B <- C <- D ты автор A, B и C.
                                                    Ответить
                                                    • > почему это неправильно работает часть твоего метода?
                                                      Потому что если мой метод получил исключение и не может продолжать нормальную работу, то это значит, что он оказался в исключительной ситуации и должен сообщить о ней клиенту. К ФП и чистоте такой подход малость отношение имеет: его практиковали ещё наши деды, которые в «C» код возврата проверяли.

                                                      > вопрос был скорее про случай, когда ты сам и есть автор этих зависимостей. То есть, когда из цепочки A <- B <- C <- D ты автор A, B и C.
                                                      Тут, в принципе, не особо важно, кто автор этих библиотек. Если я соблюдаю принцип DRY, то каждая библиотека из этой цепочке делает разные вещи. Соответственно, и исключения у них тоже будут разными. С другой стороны, если библиотеки A, B и С — это части единого целого, какой-то более общей библиотеки, и их использование по отдельности не предполагается, то, думаю, вполне разумно будет ввести для них какой-либо общий набор исключений. Впрочем, такое решение само по себе пованивает, так что it depends.
                                                      Ответить
                                                  • > нарушения инкапсуляции
                                                    - тогда всё же прошу пояснить мне по поводу friend class и пистона, а то вот непонятно, как умные дядьки и так обосрались.
                                                    Ответить
                                                    • А что по их поводу пояснять? «Friend class» — это просто костыль, появившийся из-за того, что мы живём в несовершенном мире (ну и потому что ООП в крестах весьма кривое само по себе). А в «Питоне» инкапсуляция обеспечивается не языком, а конвенцией (причём как на уровне классов, так и на уровне модулей) — и не то чтобы я был против такого подхода.
                                                      Ответить
                                                  • > я обращаюсь к библиотеке и ожидаю, что именно она мне скажет, что у неё произошла ошибка
                                                    - так если она произошла не у неё?
                                                    Ответить
                                                    • Но в исключительную-то ситуацию попал метод именно этой библиотеки. Это он не смог выполнить задачу, которую я ему поручил — и он же и должен объяснить мне, почему.
                                                      Ответить
                                              • Кстати, разве обёртка, которая перехватывает все попавшиеся исключения и херячит на них врапперы, это не такой себе детёныш god object'а?
                                                Ответить
                                                • Разумеется, такая обёртка будет говном. Возникшее в коде исключение должно быть осмысленно обработано, преобразовано в исключение, описывающее, что пошло не так, в него должны быть добавлены соответствующие метаданные — и уже в таком его можно отдавать клиентам.
                                                  Ответить
                                                  • Вся эта энциклопедичность, конечно, на словах прелестна, но по факту приводит к оверинжинирингу и горьким слезам, когда все написанные красоты приходится выпиливать уже в следующем релизе из-за изменившихся требований.

                                                    Один из важнейших принципов, который приходит с опытом: не делать больше работы, чем требуется.

                                                    Если тебе сейчас не нужен 100% loose coupling, то и не нужно сидеть и задрачивать его, у бизнеса есть требования, да и технический долг растёт не только в этом месте.
                                                    Ответить
                                                    • Это не энциклопедичность и не оверинжиниринг. Это всего лишь избегание антипаттернов: то, что всегда должен иметь в виду любой разработчик (если он пишет не на «PHP», конечно[‎/color]). Более того, грамотная инкапсуляция приводит к уменьшению количества слёз после изменения требований, поскольку чем меньше зацепление в проекте — тем меньше приходится перелопачивать навоза. И, разумеется, от необходимости выпиливать написанное не застрахован никакой код.

                                                      YAGNI — хороший принцип, и тоже придуман умными людьми. А вот применение этого принципа на практике, увы, хромает, поскольку точного определения «лишней функциональности» нет и вряд ли появится. В результате, при чрезмерно усердном его применении мы можем придти к отказу от, например, форматирования кода или грамотного именования переменных — ведь это же лишняя работа, программа прекрасно работает, даже если в ней названия всех переменных состоят из одной буквы!

                                                      Сравни, например, вот эти два исходника (оба всплывали на ГК, кстати): https://github.com/vk-com/kphp-kdb/blob/master/bayes/bayes-data.c и https://github.com/openbsd/src/blob/master/sys/netinet/ipsec_input.c. Как думаешь, который из них был написан людьми, не считавшими нужным стараться делать правильно, как пишут в умных книжках? И в который из них будет легче вносить изменения, когда понадобится рисовать не синию линию в виде кота, а оранжевый овал в виде кролика?
                                                      Ответить
                                                      • Я о том и говорю: лихорадочное избегание антипаттернов приводит к избыточному коду (если конечно это не какие-то примитивные вещи вроде всем известной проверки индекса в цикле).

                                                        Если кодом пользуешься только ты, то можешь его и не форматировать и переменные называть huiPizda. И что, мало такого кода? Сам же знаешь, что есть такое понятие, как write-and-throw скрипты.

                                                        > Сравни, например, вот эти два исходника
                                                        - второй выглядит попричёсаннее, но я не настолько хорошо понимаю здоровые портянки на си, а потому на вопрос, какой из исходников я бы раскурил быстрее, ответить не могу.
                                                        Ответить
                                                        • …А столь же лихорадочное отрицание их существования приводит к тому, что write-and-throw код оказывается в продакшене.

                                                          Да, разумеется, код, который кроме тебя никто не увидит, можно писать вообще как угодно, и сам я тоже такое делаю. Главное в этом — чтобы такой код внезапно не начал на постоянной основе решать задачи бизнеса.

                                                          Да, причёсан, оформлен, декомпозирован и снабжён подробными комментариями (хотя казалось бы — вот где абсолютно бессмысленная работа, никак не помогающая задачам бизнеса!). И благодаря этому даже человек, не знакомый с портянками, сможет достаточно быстро понять, о чём там идёт речь (конечно, если ему это будет нужно, я ни к чему не призываю :-). А вот первый код, который писался олимпиадниками в их фирменном говностиле, понять и, главное, простить изменить смогут только его авторы (и то только в первые пару недель/месяцев). И тому несчастному, которого посадят разгребать эти конюшни, останется только дунуть, плюнуть и переписать всё с нуля. И это печально.
                                                          Ответить
                                    • > Потому что надо делать не так, чтобы оно работало, а так, как кому-то нравится, правда?
                                      Интересные вопли, но лабу не приму. Приходите на пересдачу.

                                      Вот реально вся эта питушня про маркетинговое здоровое питание инкапсуляцией и питушню уровня "работает - значит сделано" напоминает бугурт школьника, которого пытаются обучить чему-то, а он думает, что печальный многолетний опыт и просьбы не кормить орланов с рук, чтобы предотвратить новые случаи - лишь брюзжание стариков.
                                      Ответить
                                      • Ну так расскажи про свой печальный многолетний опыт. Как, например, из-за автора библиотеки, автор которой пренебрегал инкапсуляцией, ты лишился месячной премии. А то может там действительно какая-то катастрофа, которую за гулом брюзжания легко не заметить?
                                        Ответить
                                        • Какой багор )))

                                          Я просто трачу больше времени на лишнее обсасывание своего кода, когда надо что-то изменить. Если там недостаток инкапсуляции, код разлагается и превращается в растекающуюся кашицу. Потом её нужно долго соскребать в баночки и тратить на это время вместо того, чтобы сделать что-то полезное.
                                          Ответить
                                          • Верным путем идешь. Главное, перед обсасыванием не забыть не помыть рук.
                                            Ответить
                                            • Потому что когда код не говно, а конфетка — его и обсасывать приятно!
                                              Ответить
                                          • В итоге ты или соскребаешь в баночки и не делаешь ничего полезного, или обсасываешь код и тоже не делаешь ничего полезного.

                                            Как это потом оформляется на performance review?
                                            Ответить
                                  • > В мире «C++» это и есть описание публичного интерфейса, потому что перегруженные операторы — это его часть.

                                    - сепульки и вореции.
                                    Ответить
                                    • Какой багор )))

                                      Функции, процедуры, методы, операторы - это операции над своими аргументами. В ООП операции и первые аргументы слили вместе, сделав набор операций интерфейсом значений типа первых аргументов.
                                      Ответить
      • Нет, это
        int functionWithError(resultValue *outValue);


        Или, в идеале,
        struct Result { resultValue value; int error; }
        Result functionWithError();


        Или вообще как в «Go»:
        ret, err = functionWithError();
        Ответить
        • Ну, сделать как в Go, в Си нельзя, потому что Си не Go, так что это к вопросу не относится.

          int functionWithError(resultValue *outValue);


          - и как ты метаинформацию об ошибке будешь возвращать, если она тебе нужна?
          Ответить
          • > Ну, сделать как в Go, в Си нельзя, потому что Си не Go
            Можно, реальный пример я привёл перед примером с «Go». Да, синтаксис отличается, но суть — одна и та же.

            > - и как ты метаинформацию об ошибке будешь возвращать, если она тебе нужна?
            Как деды ещё до нашего рождения возвращали: http://man7.org/linux/man-pages/man3/errno.3.html. Да, это «подход C».
            Ответить
            • Вообще не одна и та же суть. В Go err это не сраный int, во-первых, а, во-вторых, компилятор форсит проверку.

              > Как деды ещё до нашего рождения возвращали
              - а где здесь метаинформация?

              Вот есть у тебя функция
              int innerFunction(sometype value)

              И есть
              int outerFunction()
              , которая в цикле обрабатывает пачку value при помощи innerFunction и которая должна, когда innerFunction возвращает что-то не то, вернуть код возврата с метаинформацией про объект, на котором всё сломалось (представим, что это, например, имя файла). И куда мне эту метаинформацию записать?
              Ответить
              • > В Go err это не сраный int, во-первых, а, во-вторых, компилятор форсит проверку.
                Мелкие детали. Разве что с компайл-тайм проверками — да, беда. Но, повторюсь, сама суть подхода — явный возврат ошибки — абсолютно одинакова.

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

                EINVAL хватит всем.
                Ответить
      • Подход Си это записывать ошибку в глобальной переменной.
        Ответить
  • Объясните: не лучше делать HTTPNotFoundException(HTTPException)? И какой кейс должен быть в HTTP?
    Ответить

Добавить комментарий

Переведи на "PHP", guest!

    А не использовать ли нам bbcode?


    8