1. Куча / Говнокод #28301

    −6

    1. 1
    хде хруст?

    Превед, говнокод. Чому нет категории для раста?

    Запостил: orion, 28 Июля 2022

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

    • Война с Украиной.
      Ответить
    • Превет, напиши струйкеру
      Ответить
    • На Растишке не говнокодят.
      Ответить
      • Наполнил твой ротик растишкой, проверь...
        Ответить
    • Я кстати понял почему дrustня «most beloved language» у анскилябр.

      Компиляция рустни длиной почти в вечность, для них это плюс, а не минус.

      Никогда не любил сей сцайт c быдлогомиксами, но тут broken watch argument. И там есть пару удачных находок.
      Лучшая иллюстрация к аргументу xkcd.com/303 (оно компилируется целый рабочий день, а мы пинаем хуи).

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

        Отличие котлина от любого другого языка программирования в том, что он медленно компилируется, зато потом в рантайме всё тормозит (как всегда в JVM).
        Ответить
        • Если есть javac, то есть и javav?
          Ответить
        • > Отличие котлина от любого другого языка программирования в том, что он медленно компилируется, зато потом в рантайме всё тормозит

          Не от любого другого.
          Это прям, слово-в-слово описание Свалки.
          https://govnokod.ru/27985#comment761061

          Впрочем всё-равно сорта йажи.
          Ответить
        • > Подумаешь, у нас и на джаве всё долго компирилируется

          Хахаха. Да что вы знаете о «долго»?

          Йажа компилируется быстрее крестов. А кресты быстрее дrustни.
          Компиляция Гiгетох после перехода на ржавчину могла идти ЧАСАМИ.

          При том что рустня изначальна имела в основании крайне шустрый Шланг.

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

          Тем не менее анскилябры умудрились обделаться даже тут.
          Ответить
          • Какой багор)))
            Ответить
          • > нормальную мудульную систему

            Они захотели прям на уровне функций инкрементальность, чтобы смотреть на сишников с высока... и обосрались. Походу до сих пор инкрементальные билды крашатся.
            Ответить
            • инкрементальные билды у рустни на уровне кратов вроде как.
              Ответить
      • Именно ради экономии зарплат придумали компилировать ночью.
        Ответить
      • Компиляция и правда не быстрая (что странно, при наличии модулейто) но при этом есть шаблоны на уровне АСТ (пусть и не такие мощные как в плюсах)

        зато есть статический полиморфизм (как концепты) ну и динамический тоже есть


        Раст это первый хипстерский язык без вонючего ГЦ , а это уже много
        Ответить
    • раст отличный яп, давайте течь по расту

      * Перформанс почти как у плюсов
      * чек лайфтайма и ссылок в компиляции
      * бесплатный API с сями
      * крэйт для работы с виндоапи в коплекте
      * ключ слово unsafe, и пиши уже как тебе угодно (сырые указатели и пр)
      * пакетный менеджер и тесты в комплекте
      * неймспейсы и модулми
      Ответить
    • А вообще давайте пиздеть про раст. Вот например пример отсасывания.

      В последнее время популярно асинхронное программирование на корутинах. Никто не хочет проблемы 10K. Никто не хочет десять тыщ тредов, которые висят на медленном сетевом I/O.

      Но и ебаться с оверлапами, комплишен портами, кику, асинкио и прочими еполами никому не всралося.

      Потому Go сделал горутины, в которых блокированные сисколы заменены на асинхронные и макака может даже не думать про это

      В расте вместо этого есть крейт токио (типа торнадо в питоне) где вручную написаны асинхронные версии синхронных колов

      так себе решение
      Ответить
      • Всё лучше, чем «Питон». Там любые попытки пописа́ть асинхронщину заканчиваются гомоеблей с кучей либ, которые в неё не умеют. А уж если надо сделать API с асинхронщиной на каком-нибудь «Flask» и засервить через «uwsgi»/«gunicorn» — тут всё, полный пиздец, ты будешь манкипатчить и ловить ошибки чуть ли не из глубины сисколлов до посинения.
        Ответить
        • Для асинхронщины лучше Erlang. /thread.
          Ответить
        • Вместо питона я бы вообще всегда советовал брать Goвно.
          * никаких зависимостей от внешнего говна
          * статическая типизация всего вообще
          * дешевая асинхронщина и параллельность (нету гила)

          Реально, чем это хуже скриптоговна?
          Ответить
          • Отсуствием динамичности.
            Банальные декораторы, например. Метаклассы.

            Хуёвые дженерики.

            Вместо простых и удобных (особенно в контексте скриптушни) классов — какая-то лютая поебень со «структурами», «типами», «интерфейсами», «методами»… Нахуя это всё?
            Ответить
            • метаклассы это ж вроде какой-то чисто пистонячий костыль, или нет?
              Ответить
              • в плюсах скоро тоже появятся)) Это способ метапрограммирования для создания классов налету
                Ответить
                • А на минусах скоро?
                  Ответить
                  • скоро, скоро. Потерпи. Уже завтра появятся...
                    Ответить
                • В плюсах будут свои метаклассы, у «Питона» это другая вещь.
                  Ответить
                  • ну иедя ведь та же: мегапрогармирование

                    просто не в рантайме навеное
                    Ответить
              • Это полезная фича, позволяющая модифицировать поведение при создании классов (не объектов, а самих классов). В частности, например, добавлять/удалять/менять классметоды, модифицировать проверки на isinstance(), делать всякие прикольные автоматические валидаторы, фабрики, билдеры… Мощная штука, в общем.
                И да, часть из этого можно сделать простым декоратором (которых в «Го» тоже нет, да), но не всё.
                Ответить
                • короче, превратить код в непонимаимае никем нечто


                  (это постирония конечно же, я не против волшебства, иначе не любил бы руби)
                  Ответить
                • > модифицировать проверки на isinstance()

                  это вообще сразу сжечь нахуй

                  если я в коде проверяю, является ли А наследником Б - А не должен иметь возможности подмухлевать
                  Ответить
                  • Есть класс AccessLogger, который логирует доступ к классу, который оборачивает. Ну там:

                    ХХ:ХХ "Вызов метода pitux с аргументами yayco, gnezdo"
                    XX:XX "Метод pitux вернул vasilisk"
                    XX:XX "Доступ к несуществующему полю foo"

                    Вот ему нужно передавать проверки isinstance классу, который он хранит, потому что он иначе этот класс нигде не будет работать нормально.
                    Ответить
                    • Ты сейчас говоришь, что паттерн декоратор в питоне почему-то невозможен
                      Ответить
                      • Питоновские декораторами очень легко сломать isinstance, если не знаешь, что делаешь:
                        def fuck_it(Class):
                        
                            class FuckIt(Class):
                        
                                # типа полезная нагрузка
                                def __new__(cls):
                                    return Class()
                        
                            return FuckIt
                            
                        @fuck_it
                        class Pitux:
                            pass
                        
                        pitux = Pitux()
                        
                        print(isinstance(pitux, Pitux))
                        ------------------
                        False


                        А если ты не хочешь ещё и наследоваться от класса, то модифицировать запросы к isinstance придётся.
                        Держи класс:

                        AccessLogger(Logger, ProxyClass):
                            def __init__(self, initial_target=None, output=Logger.default_stream):
                                self.target = initial_target
                                self.output = output
                        
                            def _set_proxy_target(target):
                                self.target = target
                        
                            def _ger_proxy_target():
                                return self.target
                        
                            # функции проброса запросов с логированием.

                        Тебе придётся модифицировать запросы к isinstance, чтобы этот код работал:
                        def foo(bar):
                            if isinstance(bar, str):
                                # do shit
                            if isinstance(bar, MyCoolClass):
                               # do other crap
                            else:
                                raise WhatCrapAreYouPassingToMeException
                        
                        # . . .
                        
                        baz = "some string"
                        baz = AccessLogger(baz)
                        foo(baz)
                        Ответить
                        • > Держи класс

                          держу, это классический декоратор, почему в питоне с ним должны быть проблемы там, где в других языках их нет?
                          Ответить
                          • Потому что нахуя писать миллиард строк ПАТТЕРНОВ, когда можно не писать?
                            Ответить
                            • Переведу: зачем переопределять поведение isinstance, когда можно и нужно обходиться без этого?
                              Ответить
                              • Потому что тебе [email protected] показал задачу, которая примитивно и обобщённо решается переопределением isinstance в три строки. Тебе же с твоими ПАТТЕРНАМИ придётся впихивать эдак под пол-сотни, да ещё и плодить нахуй не нужные сущности.
                                Ответить
                                • ХУЯТТЕРНОВ
                                  Ответить
                                  • Кстати, в «Питоне» очень просто и безболезненно реализуются миксины!
                                    Ответить
                                    • ХУЕКСИНЫ
                                      Ответить
                                      • Ну ты посмотри как красиво!
                                        from typing import Protocol
                                        
                                        
                                        class Action(Protocol):
                                            def do(self):
                                                ...
                                        
                                        
                                        class ButtonMixin:
                                            def on_click(self: Action):  # !
                                                print(f'Click-click!')
                                                return self.do()
                                        
                                        
                                        class SpeakButton(ButtonMixin):
                                            def do(self):
                                                print('I can speak')
                                        
                                        
                                        class ThinkButton(ButtonMixin):
                                            def do(self):
                                                print('Thinking...')
                                        
                                        
                                        
                                        >>> speaking = SpeakButton()
                                        >>> speaking.do()
                                        I can speak
                                        >>> speaking.on_click()
                                        Click-click!
                                        I can speak
                                        >>>
                                        >>> thinking = ThinkButton()
                                        >>> thinking.do()
                                        Thinking...
                                        >>> thinking.on_click()
                                        Click-click!
                                        Thinking...

                                        И даже в статике всё проверяется!
                                        Ответить
                                        • > красиво
                                          > питон

                                          https://i.kym-cdn.com/entries/icons/facebook/000/030/710/dd0.jpg
                                          Ответить
                                        • ПРОСТО ИДИ НАХУЙ
                                          Ответить
                                        • Помоему смысл миксинов в напихивании их в сущесьтвующий класс (Как в руби)

                                          А это просто множественное наследование (хотя и называется оно там миксинами)
                                          Ответить
                                          • > Помоему смысл миксинов в напихивании их в сущесьтвующий класс
                                            Это тоже можно сделать (по сути простой манкипатчинг), да.

                                            > А это просто множественное наследование (хотя и называется оно там миксинами)
                                            Не совсем. Тут вся фишка в том, что классы-потребители миксина не обязаны наследоваться от Action (это вообще протокол), да и сам Action нужен только для статических проверок. Миксин же позволяет добавить в класс какую-то общую функциональность, основывающуюся на фиксированном наборе (возможно, нулевого размера) атрибутов. По сути миксин — это анти-интерфейс: миксин тоже нельзя инстанциировать напрямую, он тоже требует от класса-потомка реализации каких-то методов, но при этом интерфейс содержит только абстрактные методы, а миксин — только реализации.
                                            Ответить
                                          • ХУЕКСИНОВ
                                            Ответить
                                • Зачем ебаться с каким-то «OЯM», если задачу легко решить в одну строчку с mysql_query + mysql_real_escape_string?
                                  Ответить
                                • > Тебе же с твоими ПАТТЕРНАМИ

                                  он показал мне задачу, которая является де-факто декоратором. это не мои паттерны, это его паттерн

                                  > оторая примитивно и обобщённо решается переопределением isinstance в три строки.

                                  которая решается без переопределения вообще в одну: hasattr(x, 'speak') или, если очень нужно, callable(getattr(x, 'speak', None))
                                  но даже если бы она давала бенефит, сама по себе простота не может являться причиной тащить хуйню в язык
                                  Ответить
                                  • > он показал мне задачу, которая является де-факто декоратором. это не мои паттерны, это его паттерн
                                    Ну понятно: лучше написать ещё триста тысяч классов, чем решить задачу просто и понятно. Зарплата за количество строк сама себя не нафармит!
                                    Thinking With JAWA.

                                    > которая решается без переопределения вообще в одну: hasattr(x, 'speak') или, если очень нужно, callable(getattr(x, 'speak', None))
                                    1. А вот в его случае надо проверять на честный isinstance(). Например, либа требует Foo, а ей надо передать Foo в обёртке.
                                    2. Нахрюк на протоколы сам по себе нелепый: двадцать нужных методов ручками проверять будешь? А если в каждом надо ещё аргументы проверить — вооружишься inspect и пошло-поехало?

                                    > но даже если бы она давала бенефит, сама по себе простота не может являться причиной тащить хуйню в язык
                                    Для скриптушни это не хуйня, это полезная фича.
                                    Ответить
                                    • > Ну понятно: лучше написать ещё триста тысяч классов

                                      погоди-погоди: классы-протоколы пишешь ты, я предлагаю дактайпинг
                                      Ответить
                                      • Ты предлагаешь «паттерн ДЕКТОРАТОР».

                                        Для прояснения задачи:
                                        Есть внешнаяя либа A, в которой определены:
                                        1. Класс Foo;
                                        2. Функции для его получения get_foo (пример из реальной жизни — либа requests, класс Response и функция requests.get(url, ...));
                                        3. Функции, которые принимают Foo и проверяют isinstance(), например:
                                        def do_govno(foo_or_str):
                                            """
                                            Если передали Foo -- делаем _do_foo();
                                            Если передали строку -- создаём Foo() из неё и делаем _do_foo()
                                            """
                                            if isinstance(foo_or_str, Foo):
                                                return _do_foo(foo_or_str)
                                            elif isinstance(foo_or_str, str):
                                                foo = Foo(foo_or_str)
                                                return _doo_foo(foo)
                                            else:
                                                raise TypeError('Пошёл нахуй')


                                        Есть класс AccessLogger, который оборачивает объект и логгирует доступ к его полям.

                                        Задача: передать в функцию A.do_govno объект Foo, обёрнутый в AccessLogger:
                                        foo = A.get_foo('...')
                                        foo_logged = AccessLogger(foo)
                                        A.do_govno(foo_logged)  # Должно корректно вызвать _do_foo()


                                        Как ты собираешься её решать?
                                        Ответить
                                        • > Ты предлагаешь «паттерн ДЕКТОРАТОР».

                                          Я предлагаю тот вот AccessLogger выше, который является декоратором и и ничем иным, проверять на соответствие нужному не по номинативной линии, а по структурной

                                          > Есть внешнаяя либа A, в которой определены:

                                          Здесь проблема ровно в том, что сидеть надо либо на номинативном, либо на структурном стуле, и припарки "я не тот класс, я этот" в целом от этого не спасут. Решается это в зависимости от контекста либо выдачей пиздюлей автору библиотеки, которая принимает конкретную имплементацию, а не контракт, либо вопросом а нахуя вам вообще логировать что она внутри делает с объектом, который ровно так же идет из третьей библиотеки requests?
                                          Ответить
                                          • > Я предлагаю тот вот AccessLogger выше, который является декоратором и и ничем иным, проверять на соответствие нужному не по номинативной линии, а по структурной
                                            В точности для этого и нужны манипуляции с isinstance(), да.

                                            > сидеть надо либо на номинативном, либо на структурном стуле
                                            Кто это сказал?

                                            > и припарки "я не тот класс, я этот" в целом от этого не спасут
                                            Всё прекрасно работает. Я уже приводил в начале обсуждения пример протоколов, которые используют «трюки» с isintance/issubclass для обеспечения работы коллекций.
                                            Благодаря тому, что Гнидо думал вне коробки (ДЖАВЫ), в «Питоне» список одновременно является Iterable, Sized, Sequence, Collections (https://docs.python.org/3/library/collections.abc.html) — и при этом не отнаследован от миллиарда интерфейсов.
                                            Ну и да, вводить отдельный оператор для проверки сабтайпинга, и отдельный — для дактайпинга — это говнище. Текущая обобщённая реализация прекрасно работает, и в дополнение к этому позволяет делать дополнительные приятные вещи, вроде AccessLogger'а.

                                            > Решается это в зависимости от контекста либо выдачей пиздюлей автору библиотеки
                                            Понятно.

                                            > либо вопросом а нахуя вам вообще логировать что она внутри делает с объектом
                                            Ясно.

                                            Итог — задача не решена, бизнес стоит, убытки идут, зато ПАТТЕРНЫ не осквернили.
                                            Ответить
                                            • Извините, мой ротоёбский бейзлайн действительно слишком высок, чтобы просто решать поставленный задачи без оглядки. Но при желании можно хоть отнаследоваться от того класса, что ожидается или намонкипатчить; и всё это ближе к парадигме питона, чем протоколы-интерфейсы.
                                              Ответить
                                              • > отнаследоваться от того класса, что ожидается
                                                Да, это сработало бы, если бы либа позволяла передавать в себя стратегию сборки Foo.

                                                > намонкипатчить
                                                Не вижу, чем манкипатчинг превосходит переопределение поведения isinstance().

                                                > протоколы-интерфейсы
                                                Протоколы — это одно из следствий исходной возможности переопределения поведения isinstance(), от которого ты триггернулся. В задаче и её решении я их не применяю.
                                                Ответить
                                              • Зачем вы срётесь по поводу какого-то там скриптотговна? Оно нужно для поделок 5 файлов * 300 строк, не более. Какие ещё, нахуй, ХУЯТТЕРНЫ? На питоне писать чтото серьёзное — это надо быть поехавшим.
                                                Ответить
                                    • >лучше написать ещё триста

                                      нее, лучше кое-что другое сделать

                                      угадаешь?
                                      Ответить
                        • Кстати, это решается даже без метаклассов, но с не меньшей магией:
                          class AccessLogger:
                              def __init__(self, target):
                                  self.target = target
                                  self.target_type = type(target)
                              
                              def foo(self, arg):
                                  print(f'Before foo({arg})')
                                  res = self.target.foo(arg)
                                  print(f'After foo({arg}) => {res}')
                                  return res
                              
                              @property
                              def __class__(self):  # Я утка!
                                  return self.target_type
                          
                          
                          class Foo:
                              def foo(self, arg):
                                  print(f'Original foo({arg})')
                                  return arg + 42
                          
                          
                          foo = Foo()
                          print(foo.foo(1))
                          
                          foo_logged = AccessLogger(foo)
                          print(foo_logged.foo(1))
                          
                          print(isinstance(foo, Foo))  # True
                          print(isinstance(foo_logged, Foo))  # True
                          Ответить
                      • Говоришь как опытный джаваёб!
                        Ответить
                    • >> логирует доступ к классу, который оборачивает

                      --Джавист-джавист, а как ты логируешь вызовы методов?
                      --Вручную пишу "log" в начале каждого метода
                      --Джавист-джавист, а ты слышал про AOP?
                      --AOP ГОВНО ЕГО НЕЛЬЗЯ ИСПОЛЬЗОВАТЬ
                      --Но почему?
                      --ПОТОМУ ЧТО AOP ГОВНО ЕГО НЕЛЬЗЯ ИСПОЛЬЗОВАТЬ
                      --Но почему?
                      --ПОТОМУ ЧТО AOP ГОВНО ЕГО НЕЛЬЗЯ ИСПОЛЬЗОВАТЬ
                      --Но почему?
                      ....
                      --Джавист-джавист, видал в питоне декораторы?
                      --Да, прикольно, нам в джаве конечно такого не хватает
                      Ответить
                  • Одно слово: дактайпинг.

                    Дано:
                    from typing import Protocol, runtime_checkable
                    
                    
                    @runtime_checkable
                    class CanSpeak(Protocol):
                        def speak(self):
                            ...


                    Теперь мы совершенно бесплатно получаем:
                    class Petuh:
                        def speak(self):
                            print('Kukareku')
                    
                    
                    class Kit:
                        def speak(self):
                            print('Meow')
                    
                    
                    def Gologub:
                        def babble(self):
                            print('Trump Obama Biden levakis')
                    
                    
                    # ...
                    petuh = Petuh()
                    kit = Kit()
                    gologub = Gologub()
                    
                    print(isinstance(petuh, CanSpeak))  # True
                    print(isinstance(kit, CanSpeak))  # True
                    print(isinstance(gologub, CanSpeak))  # False

                    И нам не надо наследоваться от миллиарда интерфейсов (особенно актуально для библиотечных коллекций), не надо никаких «паттернов»: всё просто работает искаропки за счёт переопределения проверки наследования внутри протокола.
                    Ответить
                    • зачем при дактайпинге вообще проверка номинативного наследования? зачем мне проверять наследование CanSpeak вместо проверки наличия метода speak?
                      Ответить
                      • А это и не номинативное наследование, это де-факто проверка существования полей/методов, просто красиво обёрнутая (ну и она и в статике проверяется, да).
                        Ответить
                        • Как она может провериться в статике, если ты делегируешь вычисление результата isinstance пользовательскому коду?
                          Ответить
                          • Тайпчекер в курсе о существовании Protocol и принимает его во внимание.
                            В теории ему ничего не мешает выполнять и любые другие переопределённые isintance, как на практике — не знаю.
                            Ответить
                    • Но ведь в Go мы то же самое получаем точно так же бесплатно
                      Ответить
                    • Ты кстати слышал, что и в го тоже дактайпинг? Там неужно явно реализовываь интерфейсы

                      type Pizdun interface {
                      	pizdet()
                      }
                      
                      type Syoma struct {
                      }
                      
                      func (s *Syoma) pizdet() {
                      
                      }
                      
                      func accepts_pizdun(p Pizdun) {
                      	p.pizdet()
                      }
                      
                      func main() {
                      	s := Syoma{}
                      	accepts_pizdun(&s)
                      }
                      Ответить
                      • Я слышал, приходилось использовать. Пиздец говно. Вообще весь го — одно сплошное го...
                        Ответить
                      • Во-первых, ты украл мой комментарий, ВОР

                        Во-вторых, рациональные аргументы никому не интересны
                        Ответить
    • https://twitter.com/i/status/1610960641329889282

      тут есть кое-что и про петухов
      Ответить
    • Panik vor Putin | Doku HD | ARTE
      Ответить

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