О типизации в Python сказано уже очень много. Если вам выпало сомнительное удовольствие поработать со мной, то вы, вероятно, в курсе, насколько скептически я отношусь к типизации в Python. Причины тому – сложность синтаксиса, mypy еле ползает, реализация языка в принципе переусложнена, а взаимодействовать с ним зачастую неудобно. Сегодня я не буду упирать на эти детали, а хочу пригласить вас в небольшое путешествие в прошлое и рассказать, каковы были мои первые впечатления от работы с Python. Почему? Потому что я думаю, что существует фундаментальный и глубокий конфликт между формообразующей философией Python и концепцией типизации. Причём, этот конфликт не нов.

Концепция типизированных языков программирования появилась задолго до 2015 года. Дебаты по поводу необходимости типизировать код – также совсем не новое явление. Всякий раз, когда вы собираетесь начать новый софтверный проект, особенно такой, что напоминает веб-сервис, у вас на выбор всегда будет несколько языков программирования. Ещё в 2004 году, когда я только начинал знакомиться с программированием, такой выбор уже был широк. Вариантом номер один считался не Python, и даже не PHP, а Java. Java де-факто применялась в любых серьёзных проектах по программированию веб-приложений, поскольку обладала как системой типов, так и возможностями enterprise-класса. PHP считался игрушкой, а Python было не сыскать. PHP был популярен, но в близких мне кругах всегда воспринимался как смехотворный проект. Идея, что кто-нибудь попробует создать бизнес на основе PHP, казалась ещё смешнее. Помню, на первом курсе в моём окружении было принято считать, что в реальном мире все проекты работают на .NET, Java и C++. PHP высмеивался, Python и Ruby практически не обсуждали, а доля JavaScript на сервере была несущественной.

В таких условиях я и существовал, писал на PHP и Python. Выбор мой был продиктован не отвращением к статической типизации (или ленью), а тем, насколько исключительно удобны эти языки для разработки – в основном именно потому, что в них нет типов. Работать с ними было одно удовольствие. Да, у меня в распоряжении не было интеллектуальных подсказок, но любые изменения, которые я вносил, мгновенно отображались на сайте. Помню, как напрямую подправлял работающие сайты в режиме реального времени по FTP. Позже редактировал веб-страницы прямо в редакторе vim, развёрнутом на продакшен-сервере. Думаете, это было страшно или ужасно? Ещё как! Но, чёрт возьми, продуктивно. Работа в таком режиме многому меня научила. Например, ценному искусству идти на компромисс. Причём, не только мне, но и целому поколению программистов, работавших с этими языками, довелось узнать, что в нашей величайшей слабости (этот код не типизировался и не компилировался) заключена наша величайшая сила. Да, она налагает некоторые ограничения и требует немного иного подхода к программированию, зато такой метод невероятно продуктивен.

Существовал мир XPath, мир DTD, были миры SOAP и WSDL. Был такой мир, где системы обладали такой огромной неотъемлемой сложностью, что при работе было никак не обойтись без IDE, генерации кода и инструментария для работы во время компиляции. Совсем в другом мире жил я. В моём мире я сидел с Vim, CVS и SVN, а также с компьютером, на котором была базовая комплектация Linux. При помощи этих инструментов мне удавалось создавать вещи, которыми я очень гордился. В конце концов я перешёл с PHP на Python, так как последний предлагал компромиссы, которые меня более устраивали. Но я никогда не забуду о том, что мне дал PHP: работая с ним, я осознал, что код не должен быть идеально вылизан, главное, чтобы он решал поставленные задачи. А он решал.

Но, точно, как и при работе с PHP, общая площадь контакта между мной и средой выполнения Python оставалась крошечной. Я писал код, интерпретатор, преобразовывал его в инструкции байт-кода (я в этот байт-код даже мог посмотреть!), после чего код выполнялся в крошечном цикле в рамках интерпретатора. Интерпретатор был опенсорсным, его было легко читать и, самое главное, я мог там покопаться. Такой подход к работе не только помог мне лучше разобраться в компьютерах; более того, я невероятно легко мог понять, что именно в коде происходит. Несомненно, мне было полностью понятно всё происходящее между тем кодом, который я написал, и тот код, который работает в программе от начала и до конца.

Да, там не было статической проверки типов, и интеллектуальных подсказок тоже в принципе не существовали. Такие компании как Microsoft тогда даже не считали Python за язык. Но, чёрт возьми, насколько он был продуктивен! Мало того, на нём пишутся крупные программные проекты. Было понятно, где какие компромиссы нужны. В продакшене налево и направо летали ошибки, поскольку то и дело передавались ненадлежащие типы, но у нас был инструментарий, позволявший работать в такой ситуации. Явственно припоминаю коллегу, специалиста по .NET, насколько он был поражён, когда я похвастался перед ним тем арсеналом, которым располагаю. Ведь если бы я развернул плохой код, и этим кодом кому-нибудь прилетело бы в лицо, то в ответ я получил бы электронное сообщение, в котором приводился бы не только совершенно разборчивый стектрейс, но и строка исходного кода для фреймов. Тем более мой собеседник поразился, когда я показал ему модуль, при помощи которого можно было удалённо подключаться к действующему интерпретатору и на лету выполнять код Python, требующий отладки. Вся работа программиста выстраивалась вокруг такой «луковицы», слоёв в которой было совсем не много.

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

Вот что изменилось: теперь разработчикам уже нет такого доверия, как раньше, и в программирование повторно проникает та сложность, с которой мы боролись. Современный Python порой бывает просто непостижим для разработчика. Можно сказать, в некоторых областях мы изобретаем новую Java. Мы превратились в тех, кого когда-то вытеснили. Просто мы потеряли бдительность и вступили на путь, который может привести нас к наихудшему аналогу Java. Мы внедрили типизацию в язык, который её не поддерживает, наш интерпретатор медленный, у него есть GIL (глобальная блокировка интерпретатора). Нужно действовать внимательно и не забывать, где наши корни. Не следует коллективно отказываться от тех благ, которые у нас были.

Сегодня ветер переменился, это невозможно отрицать. Другие языки показали, что типизация может быть ценна в самых новых и потрясающих отношениях. Когда мне доводилось спорить с разными людьми о том, как устроена типизация в Python по сравнению с типизацией в Java, в языке Java ещё даже не было дженериков, а JavaScript боролся с собственной репутацией «невыносимой игрушки». До создания TypeScript оставались ещё годы. Ничего нового не изобреталось, но некоторые вещи популяризовались. Например, абстрактные типы данных вошли в практику, а когда-то были просто исследовательскими игрушками. В .NET начали смешивать статическую и динамическую типизацию. Позже в TypeScript популяризовали практику добавления типов в те языки, которые исходно создавались без них. В нашем сообществе тем более хватает разработчиков, которые вообще не представляют, чем были привлекательны такие языки.

К чему же мы пришли? Мне просто захотелось поворчать о том, что раньше трава была зеленее, а теперь повсюду эти ужасные типы? Едва ли. Невозможно отрицать, что типизация полезна, и в ней есть зерно, которое в целом помогает сильно повысить производительность труда. Но от компромиссов при этом никуда не уйти, и выбор «я за типизацию» или «я против типизации» не должен стигматизироваться. Ключевые принципы остаются прежними: типы ценны, но за пользование ими приходится платить.
________________________________________________________________________________
Постскриптум: Python сейчас на том этапе развития, когда усилия по его типизации не приносят мне никакой пользы. Если мне нужно повысить продуктивность, то я склоняюсь к использованию TypeScript. Возможно, Python выйдет на тот уровень, где сейчас находится TypeScript. Тогда я вернусь к этому вопросу.

Комментарии (12)


  1. Xeldos
    28.12.2023 09:48

    компромисс

    такой метод невероятно продуктивен

    В продакшене налево и направо летали ошибки, поскольку то и дело передавались ненадлежащие типы

    Не следует коллективно отказываться от тех благ, которые у нас были.


  1. ParaMara
    28.12.2023 09:48

    Проблема не компьютерная, а социальная. Можно уметь писать хороший (в смысле быстрый, правильный и модифицируемый) код с типами. Можно уметь писать хороший код без типов. А можно не уметь писать хороший код ни с типами ни без, но очень хотеть кабинетную работу за приличные деньги. Это источник типов в Python и вообще много чего номер раз.

    Можно пытаться так изменить содержание труда, в том числе язык программирования, чтобы иметь а) возможность нанимать дешёвую рабочую силу (в просторечии - бездарных недоучек) и б) повышать предсказуемость (какой вариант лучше - три эксперта выполнят проект на отлично за 1 - 6 месяцев и 3 х $20к в месяц или 20 «джуниоров» которые сделают на удовлетворительно за 8 - 9 месяцев и 20 х $1.5к в месяц? Для не знакомых с бизнесом привожу очевидный ответ - второй вариант не оставляет шансов первому). А что первым приходит в голову на счёт языка? Правильно, запретить делать ошибки… И это источник типов в Python и ещё много чего номер два.

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

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


  1. CaerDarrow
    28.12.2023 09:48
    +1

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


    1. Tishka17
      28.12.2023 09:48

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


  1. Myclass
    28.12.2023 09:48
    +1

    Когда ты пишешь проект один - не важно какой сложности, то недостатка в отсутствии типизации нет никакой. Когда за дело берётся команда, нужны 'договора' между собой. И типизация - один из них.


  1. economist75
    28.12.2023 09:48

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


    1. Andrey_Solomatin
      28.12.2023 09:48

      Аннотация лучше чем Вергераская нотация.


  1. Tishka17
    28.12.2023 09:48
    +5

    Зашёл прочитать про код без типов, а прочитал про код без тайп хинтов.

    Автор, не путайте нас. Когда вы пишете x=1, число 1 имеет тип int, а вот переменная x хинта явного не имеет. А дальше можно накручивать разную логику подсказок и проверок. Но факт в том, что тип у объекта есть и доступные операции у единицы как раз определяются ее типом.


  1. nameisBegemot
    28.12.2023 09:48

    Так в Питоне нет типов. В Питоне объекты. Остальное - сахар


    1. Andrey_Solomatin
      28.12.2023 09:48

      a = 1
      a.__class__
      <class 'int'>
      a.__class__.__class__
      <class 'type'>
      a.__class__.__class__.__class__
      <class 'type'>

      И у каждого объекта есть класс. И даже у это класа есть класс. Это ли не типы?


      1. nameisBegemot
        28.12.2023 09:48

        В данном контексте - один тип данных. Ссылочный. Нет примитивов, как в жабе или сях


  1. GBR-613
    28.12.2023 09:48

    Обычная судьба очень многих проектов: сначала есть что-то маленькое и удобное, и все очень довольны, потом это начинают улучшать, потом ещё больше улучшают, и ещё больше... пока не получается что-то большое и неудобное (и с кучей багов).