Почему некоторые сеньоры не любят Python.

Почему некоторые сеньоры не любят Python.

UniLecs

И почему они защищают статические языки, такие как C++

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

Оказывается, с этим согласны не все. Многие senior разработчики утверждают, что для них работа с динамически типизированными языками — это головная боль. Комментарий ниже собрал много лайков:

«Простите, что? Языки с динамической типизацией менее подвержены ошибкам, чем языки со статической типизацией? Извините, но проработав 21 год программистом я в это не поверю». — Расмус Шульц

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

В качестве примера языка программирования с динамической типизацией мы возьмем Python.

Динамическая типизация

Есть множество разных типизаций(strong typing, duck typing), однако в этой статье мы ограничимся лишь двумя наиболее популярными: динамической и статической.

Динамическая типизация — это когда тип данных определяется во время выполнения программы. То есть нет необходимости явно объявлять типы данных. Примером языков с динамической типизацией могут стать PythonRuby или JavaScript.

В отличие от динамической типизации, статическая типизация предполагает явное объявление типа данных перед компиляцией. Пример: C/C++ или Java.

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

Давайте рассмотрим пример кода на Python:

Результат:

[12, 12, 12, 12]

В приведенном выше примере мы хотим выполнить некие арифметические операции с переменной max_number и сохранить результаты в списке my_list. Однако переменная max_number не изменилась и my_list хранит ошибочные результаты.

Это все потому, что внутри цикла for мы сделали ошибку в названии max_number, что привело к созданию другой переменной с именем max_numbre. Смешно, правда? Да вот не очень. Такие ошибки может допустить любой человек, особенно под конец рабочего дня. Отыскать её в коде порой бывает очень сложно и утомительно.

То ли дело если рассматриваем языки со статической типизацией, такие как С/C++, то в них вы должны объявить переменные перед их использованием. Вам также необходимо провести предварительный анализ, дабы убедиться, что типы ваших переменных согласованы. В конечном счете вы выиграете с точки зрения безопасности, так как будете лучше контролировать свои переменные.

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

Глобальная блокировка интерпретатора (GIL — the global interpreter lock)

Еще один подводный камень — это производительность. На это особенно обращают внимание senior разработчики.

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

GIL(the global interpreter lock) является узким местом производительности для таких языков программирования, как Python и MRI Ruby. Ресурсы, которые блокирует GIL, — это потоки(thread с англ.) ЦП.

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

Параллельные вычисления — это не что иное, как одновременное выполнение потоков. Этот тип вычислений сейчас актуален как никогда из-за астрономического объема данных, которые необходимо обрабатывать.

Пример параллельных вычислений — на диаграмме ниже:

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

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

Как все происходит на самом деле, лучше всего иллюстрирует диаграмма:

Пытаясь решить проблему производительности, многие программисты или, по крайней мере, смышленые программисты пытаются вручную разбить код по потокам, используя, например, модуль многопоточности в Python. Но в результате такой код демонстрирует еще худшую производительность. Хотя такой результат может показаться странным, но это всего лишь computer science и не более. Если вникнуть в дело, все должно встать на свои места.

Хотя основная часть Python разработчиков прекрасно осведомлена об этой проблеме, трудно избавиться от GIL, потому что GIL — это основа многих особенностей Python таких, как управление памятью.

Гвидо ван Россум, автор Python, сказал, что не уверен, что Python когда-либо будет поддерживать параллельные вычисления, ибо это не было предусмотрено на начальном этапе проектирования.

В то же время статически типизированные языки, такие как С/C++ не имеют GIL’а. Это делает их более производительными.

Чувствительность к whitespaces

Программировать на языке, который помечает ошибку на основании неуместных или отсутствующих пробелов, для некоторых затруднительно. Whitespaces — это пробел, табуляция, новая строка, возврат каретки(\r). В отличие, например, от C, Python чувствителен к пробелам.

Продемонстрируем это с помощью следующего сравнения C кода и Python.

Python версия:

Результат:

C версия:

Результат:

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

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

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

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

Обратная совместимость

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

Хороший пример, когда обратная совместимость оказалась серьезной проблемой, — это переход с Python 2 на 3.

Команда разработчиков ядра Python предполагала, что людям не составит труда преобразовать код Python 2 в Python 3. Они ошиблись.

Сам автор Python признал это, когда сказал:

«Мы недооценили количество людей, которые написали большой объем кода на Python, а затем практически забыли, как он работает. Таким образом, у них не было возможности обновить его. Мы поняли, что у нас в этой части проблема».

Решением этой проблемы стало продление поддержки Python 2.7.

Заключение

Языки программирования всегда были спорной темой, поэтому нельзя считать что-то правильным или неправильным. По крайней мере, всегда есть несколько причин предпочесть один язык другому. Как правило, каждый язык программирования подходит определенной группе людей. Автор Python сказал:

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

Кроме того, наилучшим сценарием было бы наличие языка программирования, который мог бы сочетать достоинства C++ и Python.

В настоящее время наиболее близким прототипом является язык программирования Julia.

Оригинал статьи.

Report Page