На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела:
1. Название темы - краткое описание кто/что против кого/чего
2. В первом сообщении - список параметров, по которым идет сравнение.
3. Старайтесь аргументировать свои высказывания. Фразы типа "Венда/Слюникс - ацтой" считаются флудом.
4. Давайте жить дружно и не доводить обсуждение до маразма и личных оскорблений.
Модераторы: Модераторы, Комодераторы
Страницы: (32) « Первая ... 23 24 [25] 26 27 ...  31 32  ( Перейти к последнему сообщению )  
> goto vs break & continue , Кроха-сын пришел к отцу и спросила кроха: "goto - это хорошо?"
    Цитата D_KEY @
    Я помню был какой-то похожий спор с твоим участием (кажется в тематике), где в итоге обнаружилось, что std::function не уступает Dшным замыканиям
    Да, я тоже что-то такое помню, но также помню, что там был некий вырожденный случай, когда весь код в одном файле и компилятору дрступен весь код сразу. Но если вынести код с std::function в другие единицы трансляции, то аллокации в принципе неизбежны.
    Сообщение отредактировано: applegame -
      Цитата applegame @
      Но если вынести код с std::function в другие единицы трансляции, то аллокации в принципе неизбежны.

      А lto не помогает в таких случаях разве?
        Оно?

        https://en.cppreference.com/w/cpp/experimental/scope_exit
        https://en.cppreference.com/w/cpp/experimental/scope_fail
        https://en.cppreference.com/w/cpp/experimental/scope_success

        Хотя как по мне - еще один синтаксический сахар, и не более. можно заменить тем же std::unique_ptr с кастомным делитером.
          Цитата D_KEY @
          Не думаю, что это проблемой будет реальной.
          Костыли далеко не всегда являются реальной проблемой. Но это все равно костыли. Например, std::enable_if - это жутчайший и уродский костыль, но наверняка Qraizer так не считает. Да и реальной проблемой он не является :D

          Добавлено
          Цитата D_KEY @
          А lto не помогает в таких случаях разве?
          lto умеет менять код сгенеренный компилятором?
            Цитата applegame @
            Костыли далеко не всегда являются реальной проблемой.

            Про костыли я тебе выше написал. Это не костыль. Вернее, если это костыль, то и в D - тоже костыль.

            Цитата
            Например, std::enable_if - это жутчайший и уродский костыль

            Вот тут согласен.
            Ну, кстати, if constexpr почти все решает :)
              Цитата applegame @
              Например, std::enable_if - это жутчайший и уродский костыль, но наверняка Qraizer так не считает.
              Я его не использую. Не нужно было просто. Но это и не костыль, это составная часть интерфейса std в части поддержки парадигмы метапограммирования, которая помимо этого средства включает в себя ещё и большое количество других. На основе этой парадигмы ты можешь учить компилятор работать с любыми сущностями на основе их свойств и характеристик, а не только пользоваться предопределёнными и стандартизированными наборами для ограниченного числа сущностей и определёнными в Стандарте. Или ты шейдеры для GPU тоже называешь костылями, тогда как истинно правильными и единственно правоверными считаешь mutlitexturing, еnvironment lighting, mipmapping, T&L и ещё с десяток предопределений?

              Добавлено
              Цитата D_KEY @
              Вернее, если это костыль, то и в D - тоже костыль.
              Костыль, костыль. И то, и это тоже. Негоже управлять ресурсами вручную. Негоже строить безотказность кода на условных конструкциях, не имеющих отношения к инвариантам. За которые и непонятно кто ещё отвечает. И то, и другое, и третье имеет место в scope, как и где его не реализуй.
                использовать scope(exit) в качестве иммитации RAII действительно глупо. Но бывают случаи где сия конструкция вполне уместна.
                Например, я писал обертку для постгресовской родной либы libpq. Она написана на сяшке (как и весь постгрескуль). Там память захватывается самой либой, а освобождается уже клинтским кодом путем вызова соответствующей функции. Это освобождение в моей обертке фигурировало буквально внутри одной функции. Я использовал там scope(exit) так как посчитал абсолютно бесполезным городить отдельный класс вместо одной сраной строчки: scope(exit) PQfree(res).

                Кроме того scope(exit) можно применять не только для освобождения ресурсов. Я пихал в него временный отладочный код вроде изменения счетчиков и всяких логов.
                Сообщение отредактировано: applegame -
                  Цитата applegame @
                  Она написана на сяшке (как и весь постгрескуль). Там память захватывается самой либой, а освобождается уже клинтским кодом путем вызова соответствующей функции. Это освобождение в моей обертке фигурировало буквально внутри одной функции. Я использовал там scope(exit) так как посчитал абсолютно бесполезным городить отдельный класс вместо одной сраной строчки: scope(exit) PQfree(res).

                  Ты просто видимо из за отсутствия возможностей в D неверно спроектировал работу с библиотекой с точки зрения С++. Поэтому тебе и проще было сделать так. В С++ такой подход - это не проще, это будет тупо костыль.
                  Вот про эту либу ты говоришь?
                  https://postgrespro.ru/docs/postgresql/9.6/libpq-connect

                  Во первых тут нет никакой функции PQfree. Есть:
                  Цитата

                  PQfinish

                  Закрывает соединение с сервером. Также освобождает память, используемую объектом PGconn.

                  void PQfinish(PGconn *conn);


                  Во вторых - судя по документации, туда как раз RAII класс и просится, не хочешь городить класс, пиши auto dbCon = std::unique_ptr<PGconn>(PQconnectdb(psql_connect_info), [](PGconn* pCon){PQFree(pCon)}) и все, больше не нужно задумываться ни о чем. Так что ИМХО, пример так себе. Вот в своей либе, ты передаешь в PQFree(res) - а откуда ты его - res - получил? Вызвал коннект? Так значит уже не ради одной строчки класс городить, а ради двух получается? Или как?

                  Цитата applegame @
                  Кроме того scope(exit) можно применять не только для освобождения ресурсов. Я пихал в него временный отладочный код вроде изменения счетчиков и всяких логов.

                  Это очень просто делается классом-оберткой. В D возможно эта функция полезна, там же вроде GC? А в С++ она просто нахер никому не нужна. Ну не нужна она, если нужно что то подобное - это делается 1 раз за 2 минуты на коленке, и используется везде где нужно.

                  Это как знаешь, сказать в C#/Java есть ах**наая плюшка finally, а в С++ ее нет, бе бе бе. Вы мудохайтесь там теперь и живите с этим, а я finally юзаю и доволен. Ну как то вот так это выглядит :D

                  Ну и к слову, встречал что если класс в D создавать через new, то порядок вызовов с этим scope(exit) - уже не такой однозначный, а все из за GC, так что даже эта "плюшка" может запросто поломать программу. Ей очень осторожно нужно пользоваться. А значит уже и ценность ее, какую ты в нее вкладываешь, сомнительная.
                  Вот собственно тут об этой особенности и пишут: https://forum.dlang.org/thread/kjkdfcnpgdeg...forum.dlang.org
                  Т.е. как минимум один уже выхватил сигфолт в своей программе из за этого scope(exit)
                  Сообщение отредактировано: Wound -
                    Цитата Wound @
                    Ты просто видимо из за отсутствия возможностей в D неверно спроектировал работу с библиотекой с точки зрения С++. Поэтому тебе и проще было сделать так.
                    Нет, ты ошибаешься. В D можно написать также как и в C++, используя вместо классов структуры, без использования GC и с точно таким же автоматическим вызовом дуструктора при выходе из скоупа.
                    Цитата Wound @
                    Во первых тут нет никакой функции PQfree.
                    Да, давно писал, подзабыл, правильно PQClear.
                    Цитата Wound @
                    Во вторых - судя по документации, туда как раз RAII класс и просится, не хочешь городить класс, пиши auto
                    Цитата
                    dbCon = std::unique_ptr<PGconn>(PQconnectdb(psql_connect_info), [](PGconn* pCon){PQFree(pCon)})
                    и все, больше не нужно задумываться ни о чем. Так что ИМХО, пример так себе. Вот в своей либе, ты передаешь в PQFree(res) - а откуда ты его - res - получил? Вызвал коннект? Так значит уже не ради одной строчки класс городить, а ради двух получается? Или как?
                    Нет, PQFinish я как раз вызываю в деструкторе класса Connection. А эти коннекшены я держу в пуле, все по взрослому, тут RAII не нужно, как и scope(exit) или unique_ptr.

                    Ну а вообще, когда я был молодым и глупым и сильно фанател по плюсам, вот это вот:
                    Цитата Wound @
                    auto dbCon = std::unique_ptr<PGconn>(PQconnectdb(psql_connect_info), [](PGconn* pCon){PQFree(pCon)})

                    Мне казалось класной штукой. Но как только я увидел и попробовал D, Ruby, Haskell, Erlang, Elixir, Python, и прочее, я осознал, что это просто нечитаемое говно. Да ты сам, помню, ругал плюсы за уродливое метапрограммирование. Сравни:
                    ExpandedWrap disabled
                      auto res = PQExec(...);
                      scope(exit) PQClear(res);

                    Чисто и любому, деже не умеющему в D, ясно что происходит. Можно конечно написать RAII обертку, но я давно переболел ООП головного мозга и перестал писать классы/структуры на малейший чих.
                    Цитата Wound @
                    Ну и к слову, встречал что если класс в D создавать через new, то порядок вызовов с этим scope(exit) - уже не такой однозначный, а все из за GC, так что даже эта "плюшка" может запросто поломать программу. Ей очень осторожно нужно пользоваться. А значит уже и ценность ее, какую ты в нее вкладываешь, сомнительная.
                    Не понимаю о чем ты. Что именно ты слышал?
                    Сообщение отредактировано: applegame -
                      Цитата applegame @
                      Нет, ты ошибаешься. В D можно написать также как и в C++ используя не классы, а структуры, без использования GC и с точно таким же автоматическим вызовом дуструктора при выходе из скоупа.

                      Ну не удивительно, я же не пишу на D, поэтому я предположил. А раз есть такая возможность - значит, выходит просто ты так спроектировал, что тебе проще вызвать scope(exit), вместо нормальной, красивой, надежной RAII обертки.

                      Цитата applegame @
                      Нет, PQFinish я как раз вызываю в деструкторе класса Connection. А эти коннекшены я держу в пуле, все по взрослому, тут RAII не нужно, как и scope(exit) или unique_ptr.

                      Ну так я же не знаю что ты там использовал, PQfree я не нашел, а под твое описание подпадает только PQFinish.
                      PQClear же работает в связке с PQExec, опять же это все можно обернуть в обертку. Как сделано у тебя, правильно не правильно, не суть важно. Важно то, что тот контекст в котором ты говоришь, что якобы удобно писать scope(exit) вот тут - это удобно при твоей архитектуре приложения и удобно в том языке, в котором ты пишешь. Т.е. это не фича, что без нее вот тут будет плохо, это просто ты так написал свою программу. Я например напишу так, что в scope(exit) не будет никакого смысла, другой напишет так, что без goto не обойдешься.

                      Цитата applegame @
                      Ну а вообще, когда я был молодым и глупым и сильно фанател по плюсам, вот это вот:
                      Цитата Wound @ Сегодня, 13:31
                      auto dbCon = std::unique_ptr<PGconn>(PQconnectdb(psql_connect_info), [](PGconn* pCon){PQFree(pCon)})

                      Мне казалось класной штукой. Но как только я увидел и попробовал D, Ruby, Haskell, Erlang, Elixir, Python, и прочее, я осознал, что это просто нечитаемое говно. Да ты сам, помню, ругал плюсы за уродливое метапрограммирование.

                      Таки да, я же не спорю что в С++ вырвиглазные шаблоны, в которых без поллитрyхи не разберешься. Я с этим полностью согласен. Но речь то шла не о вырвиглазных шаблонах.

                      Цитата applegame @
                      Сравни:
                      CollapsedWrap disabledLine numbers off

                      auto res = PQExec(...);
                      scope(exit) PQClear(res);


                      Чисто и любому, деже не умеющему в D, ясно что происходит. Можно конечно написать RAII структурку, но я давно переболел ООП головного мозга и перестал писать классы/структуры на малейший чих.

                      Вся фишка в том, что возможно это чисто и ясно в D, но в С++ такие махинации чреваты багами, поэтому в С++ приходится писать в RAII стиле не потому что это как то круто, модно, молодежно, а потому чтоб сократить число потенциальных багов. Да и удобнее банально этим будет пользоваться, чем голыми указателями и Си функциями. Это источник многих ошибок, вот чтоб этого избежать и пишут RAII обертки, тем более что язык это поддерживает искаропки. Так почему бы и не воспользоваться этим преимуществом.

                      Добавлено
                      Цитата applegame @
                      Не понимаю о чем ты. Что именно ты слышал?

                      Я же ссылку привел выше, ок продублирую еще раз:
                      https://forum.dlang.org/thread/kjkdfcnpgdeg...forum.dlang.org

                      Вот тут чувак выхватил сигфолт благодаря GC и scope(exit).

                      Добавлено
                      Я вот допустим писал какую то хрень, связанную с вычиткой ACL в винде и ее последующим парсингом, жуткая хрень, пятиэтажные вложенные структуры, везде одни сплошные указатели, все освобождается какими то специфическими функциями, куча всякой дряни. Мне реально было проще взять все эти указатели и обернуть в unique_ptr с кастомным делитером, и вообще не нужно парится по поводу утечек, при любых раскладах. в итоге мне вообще фиолетово было на какие то там ошибки, которые могут произойти(нет они фиксировались и в логе и юзеру), просто сам ресурс - уже полностью контролируется компилятором, т.е. утечки будут только если в компиляторе баг. А это надежнее, чем писать во многих разных местах руками освобождение ресурса, потому как ты можешь не то освободить, забыть написать, не там освободить. Ручное управление ресурсом - всегда хуже автоматического, потому как является источником многих косяков и багов.
                      Сообщение отредактировано: Wound -
                        Цитата applegame @
                        Но как только я увидел и попробовал D, Ruby, Haskell, Erlang, Elixir, Python, и прочее, я осознал, что это просто нечитаемое говно.
                        Чё-то я в этом списке Delphi не вижу. Непорядок?

                        Добавлено
                        Цитата applegame @
                        ExpandedWrap disabled
                          auto res = PQExec(...);
                          scope(exit) PQClear(res);

                        Чисто и любому, деже не умеющему в D, ясно что происходит. Можно конечно написать RAII обертку, но я давно переболел ООП головного мозга и перестал писать классы/структуры на малейший чих.
                        Это прекрасно, пока не встретишь
                        ExpandedWrap disabled
                          auto res1 = PQExec(...);
                          scope(exit) PQClear(res1);
                          auto res2 = PQExec(...);
                          scope(exit) PQClear(res1);
                          auto res3 = PQExec(...);
                          scope(exit) PQClear(res1);
                          Цитата applegame @
                          Мне казалось класной штукой. Но как только я увидел и попробовал D, Ruby, Haskell, Erlang, Elixir, Python, и прочее, я осознал, что это просто нечитаемое говно.

                          Я тоже пробовал много чего, в том числе и то, что указал ты (кроме elixir, да и D мало слишком).
                          Я не считаю C++ лучшим или что-то такое, но вот RAII очень крутая (и при этом простая) концепция.

                          Как раз всякие менеджеры контекста в питоне, которые я активно использую, таки костыли. Но это уже лучше всяких finally и defer/scope(exit).

                          Добавлено
                          Цитата applegame @
                          Сравни:
                          ExpandedWrap disabled
                            auto res = PQExec(...);
                            scope(exit) PQClear(res);

                          Чисто и любому, деже не умеющему в D, ясно что происходит.

                          Ага, это пока в очередной раз фигача подобный код ты не забудешь воткнуть свой scope(exit). Нафиг.
                          Владелец пишется один раз (благодаря умным указателям это иногда просто typedef/using), используется потом много где просто как:
                          ExpandedWrap disabled
                            auto res = PQExec(...);

                          Сравнивай.

                          Добавлено
                          Цитата applegame @
                          Можно конечно написать RAII обертку, но я давно переболел ООП головного мозга и перестал писать классы/структуры на малейший чих.

                          ООП не имеет никакого отношения к теме. Совсем.
                          Я бы даже сказал, что без GC нормального ООП быть не может, но чистые плюсовики меня растерзают, поэтому я не стану этого говорить :D
                          Обертку во многих случаях даже писать не придется - есть unique_ptr и shared_ptr. Напишешь один using и вперед.
                            Цитата D_KEY @
                            Я бы даже сказал, что без GC нормального ООП быть не может, но чистые плюсовики меня растерзают, поэтому я не стану этого говорить
                            Терзать не буду, но вот путаницу с ООП и ОП отмечу.
                            Цитата D_KEY @
                            Обертку во многих случаях даже писать не придется - есть unique_ptr и shared_ptr. Напишешь один using и вперед.
                            И я вот не понимаю, в чём сложность зафиксировать контракты для компилятора, а не полагаться на бессбойность своих шаловливых рук:
                            ExpandedWrap disabled
                                auto  pq_free = [](PGconn* pCon){ PQFree(pCon); };                    // deleter  коннектов
                                using uniquer = std::unique_ptr<PGconn, decltype(pq_free)>;           // владелец коннектов
                                auto  creator =[&](PGconn* pCon){ return uniquer(pCon, pq_free); };   // фабрика  владельцев
                            Я понимаю так, что писать надёжный софт – это, главным образом, наука о его проектировании. Пусть кто-нибудь возьмёт нормальные языки типа Ады, где быстро+качественно+дёшево, а не этот заполонивший рынок ширпотреб, ориентированный на быстро+качественно+дёшево. Ада вон наполовину декларативная, хрен ты там Хелоу, ворлд напишешь, пока все контракты не обозначишь. За натурально декларативные по типу Пролога вообще молчу. Плюсы многословны? Так это в любых надёжных архитектурах так. Но и нужно это один раз, так-то пиши потом
                            ExpandedWrap disabled
                                /* коннектимся к трём базам */
                                auto dbCon1 = creator(PQconnectdb(psql_connect_info1));
                                auto dbCon2 = creator(PQconnectdb(psql_connect_info2));
                                auto dbCon3 = creator(PQconnectdb(psql_connect_info3));
                            и не парься. И гарантировано не отхватишь двойных очисток и утечек, как вон с теми scopeами.
                            Сообщение отредактировано: Qraizer -
                              Цитата Qraizer @
                              Ада вон наполовину декларативная, хрен ты там Хелоу, ворлд напишешь, пока все контракты не обозначишь. За натурально декларативные по типу Пролога вообще молчу

                              Декларативность как бы ортогональна контрактам и всему такому прочему и Ада даже на половину не декларативна, стандартный императив, разве что с более развитой системой типов, чем много где. Но и там есть дыры, и на Аде космические корабли бороздят просторы бетона.
                              Сообщение отредактировано: korvin -
                                Так что scope-ы всё равно остаются и навсегда останутся костылями. Когда некому следить за соблюдением контрактов, всегда остаётся вероятность всплыть "Упс! :wub: "ам. Где-то раньше, где-то позже, у кого-то мало, у кого-то много, когда-то редко, когда-то часто, но вероятность всегда будет.
                                Бывает, что костыли дешевле, потому они и существуют в природе, но делать из костылей технологию – увольте, это детский сад.

                                Добавлено
                                Цитата korvin @
                                Декларативность как бы ортогональна контрактам и всему такому прочему и Ада даже на половину не декларативна, стандартный императив, разве что с более развитой системой типов, чем много где
                                Ну не придирайся. Ты прекрасно понял, о чём речь. Описание контрактов всегда декларативны по своей природе. Даже обычный прототип функции в простом С декларативно описывает её контракт.

                                Добавлено
                                Ну и да, контракты тоже можно описать с ошибками, это не абсолютная панацея.
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (32) « Первая ... 23 24 [25] 26 27 ...  31 32


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0758 ]   [ 15 queries used ]   [ Generated: 7.05.24, 17:15 GMT ]