LINUX.ORG.RU
ФорумTalks

Чем плох Python?

 ,


4

4

Просьба к Python-хейтерам - вы можете адекватно и по пунктам сформулировать, чем он плох? Чем он хуже по сравнению с Perl, Ruby, Javascript, другими подобными языками?

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

Какие классы, о чем ты.

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

А какой как там был объявлен класс, вообще не важно.

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

З.Ы.

Дополню, что C++ имеется в виду в старом стиле, когда писали без шаблонов. С нормальными шаблонами всё стало лучше.

wandrien ★★
()
Последнее исправление: wandrien (всего исправлений: 2)
Ответ на: комментарий от byko3y

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

У JS модель ООП не имеет существенных отличий от Ruby.

Насчёт большей простоты для вывода типов согласен, но с одной оговоркой. Ты в статье в недостатки питона записываешь возможность модифицировать классы на лету. Это относится ко всем обсуждаемым тут ЯП в силу их природы. JS ничем не выделяется на общем фоне.

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

И тут возникает вопрос: а зачем тогда все эти machine learning и прочие data analysis тулзы используют именно питон в качестве обвязки?

Я очень долго сам пытался это понять. И не только поводу питона. Такое ощущение, что я не понимал (не понимаю) каких-то фундаментальных процессов в индустрии. Давай обратимся к истории:

https://www.tiobe.com/tiobe-index/
https://yourbasic.org/top-programming-languages/

По состоянию на 2001 год питон шел за лиспом, PHP, и даже адой. Адой, про которую никто уже и не помнит. То есть, 10 лет спустя старта питон болтался где-то на границе массовой индустрии. А потом пришел гугл — я больше не вижу никакой иной причины. Гугл с таким же успехом мог взять руби, или дорабатывать PHP, или придумать свой язык — как в итоге гугл и сделал (Go). Я не знаю как тогда, но сейчас карго-культ при принятии решений в IT очень популярен, то есть: гугл так делает, потому мы будем так делать. В частности, потому что «все» хотят работать в гугле, а значит они будут учить технологии гугла, будет много предложения на рынке из непопавших в гугл — на этом предложении мы будем кормиться.

То есть, питон популярен потому, что где-то в двухтысячном году собрались два с половиной технических руководителя гугла, и решили «будем прототипировать на питоне, а потом переписывать на жаву с крестами». Вот и всё, судьба индустрии на 20 лет вперед была решена таким образом.

Сейчас, ожидаемо, идет активный поиск альтернатив, потому что да, питон — это ужасный язык для датасаенса, но никакой гугл или фейсбук не придет и не скажет «так, завтра всем использовать Swift для машинного обучения».

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

Я очень долго сам пытался это понять. И не только поводу питона. Такое ощущение, что я не понимал (не понимаю) каких-то фундаментальных процессов в индустрии. Давай обратимся к истории

Хорошее объяснение. Тоже голову ломал.

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

Из-за этого придумали yarn.

Ну это типовое решение. В 2021 в любой системе менеджмента пакетов должно быть из коробки

В yarn из коробки нет автоматического поиска рабочих комбинаций пакетов — приходится руками искать, а потом он уже сам автоматически фиксирует эти версии.

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

Я именно про фиксацию.

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

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

Что касается питона в целом, ты хочешь от него невозможного. Для вывода типов и качественной компиляции есть другие языки.
Непонятно, зачем вообще выбрал питон in the first place

Изначальной проблемой, которую я хотел решить, было устранение GIL. Если говорить про мои личные мотивации, то я искал тупо популярную нишу из коммерческих соображений, а кресты мне не нравились, зато Си вполне устраивал. Сейчас я на кресты смотрю иначе. В каком-то смысле я не столько пишу на питоне, сколько пишу питон.

Я очень быстро понял, что убрать GIL не получится, однако, даже для реализации обходного плана в CPython настолько много препятствий, что их очень тяжело обойти. Одна из ключевых проблем, для которой я до сих пор не придумал каких-то эффективных решений — это необходимость работы с объектами статичной структуры, которые намного эффективнее в многопотоке, чем стандартное динамичное питонье говно. То есть, это разница между статичной числовой ячейкой с блокировкой к ней, илиже ассоциативным массивом, ссылающимся на числовой объект, которые вообще непонятно где блокировать. Простой пример:

a.field = 2

Чтобы это выполнить в многопотчоной среде, нужно заблокировать ассоциативный массив имен модуля, заблокировать объект «a», ассоциативный массив атрибутов объекта a, заблокировать старый a.field, который может быть дескриптором свойства. Четыре блокировки на банальнейшую операцию! Теперь ты понимаешь, почему Гвидо жаловался на проблемы производительности, которые бы возникли при введении мелкогранулированных блокировок для замены GIL. Правда, как всегда, он не назвал настоящей причины: я создал кусок дерьма, с которым ничего нельзя сделать, который невозможно развивать не переписывая с нуля.

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

Контроль типов нужен в каких случаях:
Присваивание.
Передача аргумента.
Что еще упустил?
Что там такого ужасного в сорцах, что контроль типов станет катастрофой?

Ну, а разве весь питон — это не сплошное присваивание и передача аргументов функциям? Я там еще рядом дописывал, что в питоне стандартная либа нетипизирована — это несколько облегчает ситуацию с одной стороны, а с другой стороны делает статическую типизацию бессмысленной, потому что она становится крайне ограниченной.

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

Чтобы это выполнить в многопотчоной среде, нужно заблокировать ассоциативный массив имен модуля, заблокировать объект «a», ассоциативный массив атрибутов объекта a, заблокировать старый a.field, который может быть дескриптором свойства. Четыре блокировки на банальнейшую операцию! Теперь ты понимаешь, почему Гвидо жаловался на проблемы производительности, которые бы возникли при введении мелкогранулированных блокировок для замены GIL. Правда, как всегда, он не назвал настоящей причины: я создал кусок дерьма, с которым ничего нельзя сделать, который невозможно развивать не переписывая с нуля.

Разве есть ЯП схожей природы, в котором можно решить эту проблему?

Всё упирается в компиляцию, которой в таких языках принципиально нет.

Если речь идёт об однопотоке, можно вбухать кучу денег в JIT и надеяться, что всё будет как-то работать. В многопотоке вариантов особо нет, только полностью раздельное исполнение инстансов.

Ну или костыли на корутинах. Но это ни разу не многопоток.

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

Класс-ориентированное программирование не работает, и это уже пора понять.

Ну конечно, и поэтому умники, изначально отказавшиеся от классов, через n лет спотыкаясь бегут прикручивать их синей изолентой. И это случается с каждым. На выходе имеем уродцев как на подбор: perl, python, php, js. Все по этим граблям прошлись, и следуюший на очереди go.

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

Я это вижу тупо как рантайм проверки, которые заменяют явные проверки, что на входе не рандомный мусор. Но это и так теперь есть.

Для остального… увы.

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

На выходе имеем уродцев как на подбор: perl, python, php, js. Все по этим граблям прошлись, и следуюший на очереди go.

У js с самого начала была ООП модель. Просто синтаксис был непривычный. Сейчас добавили сахара.

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

Да, js лучше всех смотрится. Но классов там не было, потом выяснилось, что это не слишком удобно мягко говоря, и прикрутили сахар. А в руби по сути те же прототипы, только сразу продумана структура классов и всякие нюансы типа того как наследуются методы класса, что есть self в каком контексте. Без этих мелочей будут заморочки на ровном месте. Как вот в питоне вроде есть классы, но лучше бы и не было. Или в перле у каждого своя объектная модель. Или в жс старом какие-то костылища на лямбдах были для эмуляции классов и приватности. Ну а совсем без ООП чото ни у кого не получается программировать. В том или ином виде оно везде вылазит.

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

Да. Допуская небольшие неточности, можно сказать, что Ruby — это очень очень много сахара над объектной моделью JS.

Это было прям первое впечатление от знакомства. «Наконец-то удобный сахар и стандартная библиотека без выноса мозга». Ну, JS тогда еще совсем бедный был.

wandrien ★★
()
Последнее исправление: wandrien (всего исправлений: 1)
Ответ на: комментарий от wandrien

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

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

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

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

Оно не работает в случае C++, когда пытаемся на классах построить модель предметной области, она никак не строится, делаем в каждой дырке множественное наследование, всё окончательно запутывается, а стоимость поддержки улетает в космос, потому что для понимания всех костылей кодовой базы нужен целый отдел вундеркиндов, а для правок — магия
Дополню, что C++ имеется в виду в старом стиле, когда писали без шаблонов. С нормальными шаблонами всё стало лучше

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

byko3y ★★★★
()
Последнее исправление: byko3y (всего исправлений: 2)
Ответ на: комментарий от bread

Хотя синтаксис местами конечно…

То у них if не с той стороны пишется, то присваивание в обратную сторону.

Ну хорошо, что всё это опционально, и можно не пользоваться.

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

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

У JS модель ООП не имеет существенных отличий от Ruby

Я отвечал по поводу JS vs CPython — это два языка, которые я хорошо знаю. Я не знаю деталей реализации руби, но подозреваю, что они ближе к питону, чем к JS. Именно ограниченность и примитивность работы с объектами в JS позволила сделать второй (после LuaJIT) турбореактивный JIT-компилятор для динамического языка. В Lua объекты еще проще, за счет чего он и стал первым подобным языком. Конечно, если не считать Java, которая без JIT-компиляции такая же медленная, как питон и руби.

Ты в статье в недостатки питона записываешь возможность модифицировать классы на лету. Это относится ко всем обсуждаемым тут ЯП в силу их природы. JS ничем не выделяется на общем фоне

Выделяется. Прототип нельзя поменять портируемым способом после создания объекта. То есть, делается «снимок» прототипа, после чего цепь прототипов становится неизменяемой. Это поднимает JS на целую ступень выше Ruby/CPython, поскольку позволяет производить оптимизации и иметь гарантии, что внешний код не захочет внезапно поменять стандартный метод у массива.

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

Вот именно. Например, операция сложения не «есть у объекта» — она выполняется над объектом.

Она есть не у объекта, а у класса. Не путайте. А по сути:

Адепты класс-ориентированного программирования с ноги запихивают методы работы с объектами в сами объекты, и делают вид, что так понимать код стало проще.

Самое главное, что никто не заставляет «запихивать».

Методы обеспечивают динамическую диспетчеризацию вызова по таблице методов объекта слева. Там, где она (диспетчеризация) вам нужна — используйте. Там, где не нужна — не используйте. Всё логично. Есть задача, есть под неё инструмент.

На практике в архитектуре мы имеем дело не с числами, а со всякими плагинами, виджетами, менеджерами, менеджерами менеджеров, абстракциями над объектами БД и т.п. Всему этому нужна динамическая диспетчеризация.

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

Это проблема невротичного ума, а не классов. Читайте книги по архитектуре кода, там все эти типовые ошибки рассматриваются, когда в класс суют не то, что к нему относится.

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

Японцы тут не при чём, это всё Ларри Уолл изобрел. А Матцумото был фанатом перла. Отсюда все издержки. Но синтаксис дело десятое (если там нет значимых пробелов конечно), тем более не назовешь синтаксис руби каким-то уж очень ужасным. Читается хорошо.

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

Я отвечал по поводу JS vs CPython — это два языка, которые я хорошо знаю. Я не знаю деталей реализации руби, но подозреваю, что они ближе к питону, чем к JS.

В чем именно он ближе к Питону?

Именно ограниченность и примитивность работы с объектами в JS позволила сделать второй (после LuaJIT) турбореактивный JIT-компилятор для динамического языка.

В JS нет примитивности работы с объектами. Есть концептуальная простота, которая позволяет делать JIT относительно малой кровью, в сравнении с Питоном.

Прототип нельзя поменять портируемым способом после создания объекта. То есть, делается «снимок» прототипа, после чего цепь прототипов становится неизменяемой.

Эээ? Можно менять поля прототипа в любой момент.

qjs > a = {}
{  }
qjs > Object.prototype.xxx = 1
1
qjs > a.xxx
1
qjs > 

Вывести типы и скомпилировать такое в общем случае не получится.

гарантии, что внешний код не захочет внезапно поменять стандартный метод у массива.

Ну ваще-т:

qjs > a = [1, 2, 3]
[ 1, 2, 3 ]
qjs > for (x of a.keys()) {console.log(x)}
0
1
2
undefined
qjs > Array.prototype.keys = null
null
qjs > for (x of a.keys()) {console.log(x)}
TypeError: not a function
    at <eval> (<evalScript>)
qjs > 
wandrien ★★
()
Ответ на: комментарий от bread

тем более не назовешь синтаксис руби каким-то уж очень ужасным. Читается хорошо.

Согласен.

wandrien ★★
()

По пунктам, то что не нравится:

  1. Нарушение совместимости при переходе от 2 к 3. При этом никто не гарантирует, что не появится версия 4, несовместимая с 3. Тут ещё надо помнить, что проблема не столько в самом языке, сколько в сторонних библиотеках.
  2. То что прогнулись и стали вводить имитацию статической типизации. Сюда же и всякие паттерн-матчинги относятся. Я понимаю, что не могли не прогнуться, но это не отменяет моего разочарования.

Здесь говорили, что Python неплох, если пишете один и до 10 тысяч строк. Но 10 тысяч строк на Python, это 40 тысяч строк на Java. Вопрос: если Вы пишете в одиночку и проект предполагается небольшим (менее 10 тысяч питонячих строк), то не будет ли чудачеством в этом случае использовать Java вместо Python?

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

гугл так делает, потому мы будем так делать

А потом они разработали Go, но почему-то хомячки не прыгнули все с питона на Go. Как же так, если надо делать, как гугл?

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

Скорее всего, потому что на тот момент ниша только открывалась, и какой язык туда всосёт, определялось волей случая. Гугл принял участие в этой воле случая.

А сейчас ниша плотно занята Питоном, подвинуть его так просто не получится.

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

Вопрос: если Вы пишете в одиночку и проект предполагается небольшим (менее 10 тысяч питонячих строк), то не будет ли чудачеством в этом случае использовать Java вместо Python?

Если так рассуждать, то… Если взять Ruby, есть неиллюзорная возможность вместо 10 тысяч питонячьих строк получить 6-8 на Ruby.

wandrien ★★
()

Инфраструктура, всякие pip — ужасно. В минорных версиях ломают совместимость. Не иногда, а всегда. Могут накрутить что то на серверах, что даже с фиксированными версиями, оттестированное ПО вдруг перестает работать.

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

и какой язык туда всосёт, определялось волей случая

В гугле бросали игральную кость? Читали из /dev/random? По кофейной гуще определили язык?

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

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

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

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

В гугле бросали игральную кость? Читали из /dev/random? По кофейной гуще определили язык?

Понятия не имею. Но мне неизвестны реальные преимущества python перед ruby. Перед php — конечно да, но с php и так понятно, что всё очень печально.

Где-то уже тут обсуждали одну из возможных причин. Python выбрали многие учебные заведения как «простой язык», так как на первый неискушенный взгляд он таким представляется, и разрабами он так и пиарится.

И мир просто получил толпу джунов, готовых сразу писать на питоне.

При этом язык явно лучше php и perl, и разработчики более доступны, чем для ruby. Выбор бизнеса очевиден.

wandrien ★★
()
Последнее исправление: wandrien (всего исправлений: 1)
Ответ на: комментарий от wandrien

То есть в Ruby не будет проблем с проектом более 10 тысяч строк и несколькими разработчиками? Если он здесь не лучше чем Python, то в моём вопросе можно заменить Python на Ruby.

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

То есть в Ruby не будет проблем с проектом более 10 тысяч строк и несколькими разработчиками?

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

(Лично я этот тезис не поддерживаю, но и не опровергаю.)

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

При этом язык явно лучше php и perl, и разработчики более доступны, чем для ruby.

т.е. не игральную кость бросали?

seiken ★★★★★
()

Чем он плох

по сравнению с Perl

Ничем.

Ruby

В Ruby Ъ-ООП, в питоне – каша.

Javascript

На питоне исключительно сложно писать фронтенд.

Сам я люблю питон, если что.

buddhist ★★★★★
()
Последнее исправление: buddhist (всего исправлений: 1)
Ответ на: комментарий от byko3y

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

и питон создан до джавы

О_о! А можно какой-то пруфец? А то чёт дочитал до сюда и как-то в остальное уже сложно верится.

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

Низкая по сравнению с чем? Где бенчмарки посмотреть?

60% стандартной библиотеки написано на сишке

Как по мне, это скорее достоинство, чем недостаток. Особенно для языков, прямое назначение которых быть клеем.

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

Это совсем не питон. Статическая типизация — это mypy.

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

В Ruby Ъ-ООП, в питоне – каша.

Мы точно про один Ruby? В котором функция без лишних приседаний даже не объект первого класса?

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

Нет. Опытным себя мнит каждый первый, нужен именно lover, который любит корявенький X и сознательно юзает его через всю его корявость.

Вот, ИМХО, полный тред примеров. На две страницы двое упомянули GIL, ни одной чёткой претензии к объектной модели, подавляющее большинство претензий к какой-то косметике и к утиной типизации в языке, о боже, с утиной типизацией. И это тред про язык, где нельзя проксировать произвольный объект.

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

А чем первоклассность определяется? Возможностью написать foo()? Ну так это сахар, под капотом спрятан такой же вызов .call. Просто в руби меньше сахара как ни странно. То, что принимают за сахар, как правило обычные вызовы методов.

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

Ты сам знаешь, где слукавил.

Не знаю.

Я не могу читать твои мысли. Если ты их не говоришь, то как правило так и останешься непонятым.

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

Согласно дизайну в руби нет свободных функций, так что с труевостью ООП всё в порядке. Но метод является объектом полноценным. Тогда уж предъявлять претензии по ФП епархии, мол нет функций нормальных, как так жить.

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

Знаешь-знаешь, шланг, и то, что я с мобилки и заподозрил в тебе компетентного собеседника, тебе не оправдание.

def one
    "This is the new one"
end

puts one.class

inb4 «это не функция», код взят из https://ruby-doc.org/core-3.0.0/Module.html#method-i-module_function

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

Ну да, необходимость боксинга/анбоксинга такой базовой фигни как функция это прям Ъ-ООП. Напомнило известную байку про «да кто ты такой» и Алана Кея, угу.

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

Знаешь-знаешь, шланг, и то, что я с мобилки и заподозрил в тебе компетентного собеседника, тебе не оправдание.

Да нет. Шланг – это твоё «ой, я знаю, и вы тоже знаете, и поэтому вы сами знаете, что я знаю!». А я отвечаю ровно на то, что вижу.

я с мобилки

Ну зайдёшь потом не с мобилки и напишешь сколько хочешь, если тебе интересна эта тема. Проблема что ли?

def one
    "This is the new one"
end

Так это не функция — «не объект первого класса», а к слоту в таблице методов нет прямого доступа.

Сомнительное решение — сделать синтаксис вызова метода всегда неотличимым от получения значения свойства. Но к ООП/неООП отношения не имеет.

Функцию как объект первого класса я выше показал.

Выделяй существенное.

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