Куча говна / Говнокод #28301 Ссылка на оригинал

0

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

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

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

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

  • Я кстати понял почему дrustня «most beloved language» у анскилябр.

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

            Хуйца пососи своего хозяина вместе с волоснёй своими усами
            Ответить
      • Вместо питона я бы вообще всегда советовал брать 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...

                                      И даже в статике всё проверяется!
                                      Ответить
                                      • Помоему смысл миксинов в напихивании их в сущесьтвующий класс (Как в руби)

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

                                          > А это просто множественное наследование (хотя и называется оно там миксинами)
                                          Не совсем. Тут вся фишка в том, что классы-потребители миксина не обязаны наследоваться от 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)
                    }
                    Ответить

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

Я, guest, находясь в здравом уме и твердой памяти, торжественно заявляю:

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


    8