Pull to refresh

Comments 38

Народ, кто ещё угадал Армина после первого же предложения? =)
Вообще вторая часть понравилась больше первой. О каких-то моментах совершенно не задумываешься, пока их тебе вот таким безпардонным образом не швырают в лицо :)
Совершенно согласен, и ведь многие вещи сам замечал, но просто проходил мимо, считая, что «так и надо», и исходники CPython изучал. Глаз замыливается, увы. А такие статьи заставляют задуматься и расти в профессиональном плане =)
я не очень внимательно читал, но по-моему, тут как-то в кучу все свалено

Типизацию можно проклассифицировать по нескольким ортогональным категориям:

1. строгая/нестрогая. То есть можно ли преобразовать 1.0 -> 1 -> «1» -> true
2. Явная/неявная. То есть нужно ли везде писать int double и т.д. при объявлении переменных
3. Времени компиляции/исполнения. Собственно, когда мы типы будем проверять.

У python строгая неявная типизация. Поскольку python не компилируется, то типы все равно будут проверяться при запуске, и ничего особо явная типизация не даст (ха ха!)
Если мы говорим про CPython, а про него речь и идет в статье, то проверять типы можно в момент компиляции в байткод.
Для этого нужно понимать, кто какую функцию и с какими параметрами вызывает. В большом числе случаев в python это невозможно

mypy это эксперимент, а не попытка навязать какую-то догму. отнюдь не первый в своем роде, и вряд-ли последний.

в pep-3107 речь идет только о синтаксисе. к статической типизации эти аннотации не имеют ни какого отношения.

на практике статический анализ (pylint тот же) решает большую часть проблем.
MyPy — просто левый проект, PEP — просто рекомендации. Это понятно и так :)

Pylint, конечно, хорошо, однако не панацея ни разу. Да, часть проблем (в основном, результат обычной невнимательности) он решает, однако взамен он привносит огромное количество геморроя. Вариант с явной или статической типизацией ведь всегда будет лучше, чем гадание на кофейной гуще, коей является pylint?
С явной/неявной типизацией не всё так просто и однозначно, хорошие примеры есть в статье.

Проблема несколько глубже, проблема не в классификации языка по системам типизации (тут всё просто), а в особенностях (читать как «недостатках») существующей реализации Python. Статья, по большей части, об этом.
А что не однозначно? Я просто наблюдаю путаницу у автора явной и статической типизации, которые никак не связаны (auto C++, var C# — неявная статическая типизация), что уде меня самого сбивает с толку
Автор так и пишет, например, что auto C++ — неявная статическая типизация. Да и у меня в переводе, вроде, так и написано. Если я где-то ошибся, прошу поправить.
C++ в большинстве случаев все-таки явная статическая типизация. А автор вообще пишет что статитеческая типизация имела место быть, а теперь авто от нее избавляет. Что не верно — статическая типизация осталась.

Вот тут переходы совсем не ясны:
Python и явная типизация
Некоторое время назад на одной из конференций кто-то убеждённо доказывал, что статическая типизация — это здорово, и языку Python это крайне необходимо.
И затем пример на явную типизацию:
def print_all_usernames(users: List[User]) -> None:
С местом про C++ и статическую типизацию с дальнейшим переходом на описание автотипов согласен, можно придраться, хотя стоит ли? :)

А вот про Python и явную типизацию не соглашусь — там всё правильно написано. Обсуждалась статическая типизация, да, а в итоге предлагают реализовать явную (и MyPy и PEP-3107), там так и написано же, разве нет?
Ну так что ему не нравится-то? Аннотации типов? Так кому же они могут нравиться? В 21 веке явная типизация точно должна уйти в прошлое. А вот как особенности типов будут мешать статической типизации, я не понимаю, если честно. Интерпретатор по хорошему должен учесть все особенности типов, он-то ведь их знает!
Мне всегда казалось, что для того, чтобы участвовать в дискуссии вокруг какой-либо статьи и вести конструктивный диалог, первым делом неплохо было бы прочитать эту самую статью. Иначе получается разговор ни о чём. Без обид и ничего личного :)

Отвечаю на вопрос: да. Собственно, примерно обо всём об этом и написана (и переведена) статья.
мы кажется разбирали довольно узкий вопрос, плюс я сразу предупреждал.
Тем не менее по главному (второму) вопросу я ответа как раз и не нашел.
То есть того времени, которое я потратил на перевод недостаточно, нужно ещё персонально вам ответить на все те вопросы, которые возникли после того, как вы не прочитали перевод, с учётом того факта, что ответы на все эти вопросы есть в статье? Ну давайте, чего уж там, мне всё равно в два часа ночи перед началом рабочей недели делать нечего. Всегда мечтал побыть в шкуре репетитора :)

Повторите, пожалуйста, ещё раз второй (главный) вопрос? Мне почему-то показалось, что я на всё ответил.
как особенности типов будут мешать статической типизации, я не понимаю, если честно. Интерпретатор по хорошему должен учесть все особенности типов, он-то ведь их знает!

доп.: разница с точки зрения вызова функции между статической и динамической типизацией в том, что на момент вызова при статической типизации известно, какие типы аргументов может принимать функция, а при динамической — нет. я вижу проблемы с переходом на статическую типизацию в питоне, но мне совершенно не ясно, какое это имеет отношение к внутренностям типов, то есть к тому, что описывает автор. Пусть часть типов реализовано одним способом, а другая — другим. И что?
Вообще, речь в статье именно про Python. А можно я просто отвечу цитатой из статьи?
Например, объекты datetime, в общем случае, можно сравнивать с другими объектами. Но если вы хотите сравнить два объекта datetime друг с другом, то это можно сделать только в случае совместимости их таймзон.
то же самое, что вы процитировали, можно сказать про любой язык программирования. В том числе со статической типизацией. Это runtime и не имеет к типизации никакого отношения.
Мне, например, нравятся явные аннотации типов. Это отличная документация для публичного API. Я в основном пишу на JS и код типа
profile.auth = function (credentials) {
  // some magic here
}

заставит меня читать тело функции, иначе я так и не пойму что же туда передавать надо и что она вернет
В то же время
/**
 * @param {{username: string, password: string}} credentials
 * @return {IThenable.<boolean>}
 */
profile.auth = function (credentials) {
  // some magic here
}

очень даже понятен.

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

Если вы попробуете писать что-то на С++, то поймете сколько мусора на самом деле добавляют обязательные аннотации.
UFO just landed and posted this here
Да, примерно так же пишутся (хорошими программистами) докстринги в питоне. Вот тут хорошо расписано: http://stackoverflow.com/questions/3898572/what-is-the-standard-python-docstring-format.

Другое дело, что не существует общепринятого стандарта, ну и докстринги — они ни на что не влияют в чистом Python, это просто документация для разработчика.
Про хаскель автором написана заведомая чушь, опровергаемая еще до первого знакомства с Maybe.
Почитал про maybe, справедливо на первый взгляд. Пойду чинить сломанный после чтения кода на хаскеле код :)
Даже такая простая вещь, как интерфейс для работы с командной строкой (библиотека click) просто не работает в других языках, и основная причина в том, что вам приходится беспрестанно бороться с типами данных.

Есть аналог для C# — cmd. Для подобных прикольных вещей (XML/JSON DOM, AR ORM, упрощение паттернов) и для взаимодействия с другими языками динамическая типизация рулит.
Архитекторам будущих языков программирования определённо следует избегать всех ошибок, которые были совершены разработчиками языков PHP, Python и Ruby, когда поведение языка в конце концов объясняется поведением интерпретатора.

Жаль что это перевод и не могу донести моё мнение до автора… В случае PHP существует только три проблемы, связанные с поведением интерпретатора — вложенные тернарные операторы, регистрация костыльной функции в глобальном пространстве при создании лямбды через create_function и невозможность вызвать функцию из объекта, если объект создавался вот так:
$any = (object)['some' => function(){}];
$any->some(); // error

В остальном я считаю PHP абсолютно и беспрецендентно предсказуемым языком (как следствие — предсказуемость поведения интерпретатора), проблемы которого просто связаны с багажом заранее непродуманной стандартной библиотекой, в отличие от того же Ruby, допустим, и в особенности JS (который почему-то опущен в опусе автора).

Хотя, может я просто привык и не нахожу бревно в глазу…
Я никогда не думал, что в Python так много спорных мест, однако же конструктивная критика Армина позволяет трезво взглянуть на вещи со стороны. К сожалению, я уже позабыл всё то, что когда-то знал про PHP, поэтому не могу оценить его или Ruby. Что касается JS, автор его «любит»: lucumr.pocoo.org/2013/12/9/stop-being-clever/ =)
JS в нынешнем виде — это прям почти PHP4 14-ти летней давности (можно даже подискутировать на эту тему, если кто хочет), т.к. пока я не вижу особой разницы (кроме наличия безымянных функций в первом, которые появились в php всего 5 лет назад).

По поводу питона — писал очень мало, но восхищался некоторыми мелочами, которых не находил в рубях, кофескрипте или пыхе, так что статья немного осадила моё впечатление (всё же он не идеален, как казалось вначале).

По поводу же руби — есть очень много мест, которые совершенно взрывают мозг своим поведением, но зачастую это оправдано тем, что сабжевый язык (по моему мнению) просто избыточно гибкий, слишком много синтаксических конструкций и позволяет\предоставляет слишком много возможностей, в отличие от того же пыха, где синтаксис очень простой и привычный любому плюсовику\шарписту\проч., а расширение происходит за счёт функций.
Извините, что в топике про python, но

$x = 0;
$a = array(&$x);
$b = $a;
$x = 2;
unset($x);
$b[1]++;
$b[0]++;
echo $a[0], ' ', $b[0];

For the example above, a conforming implementation could output “2 1”, “2 3”, or “3 3” depending on how it implements value assignment for arrays. © github.com/php/php-langspec/blob/master/spec/04-basic-concepts.md

Ну и всякие квантовые эффекты вроде 3v4l.org/ShFpG и stackoverflow.com/q/26258550/2815355
Согласен, не предсказуемо, можно добавить в список проблем. Я бы назвал результат 3 3, хотя в реальности происходит 2 3.

В оправдание могу сказать, что подобного безумия никто в здравом уме не напишет =)
Соласен со всем высказанным. Программирую на питоне не слишком много, но с с упомянутой проблемой с «непонятным типом скомпилированного рег. выражения» уже сталкивался.

Вообще несмотря на то, что питон лично мне оче нравится синтаксисом и идеями, всё-таки избегаю писать на нём что-то большее, чем «скрипт на несколько сотен строк». Всё из-за типов. Python декларируется как «язык для быстрого кодинга», но вот у меня до сих пор немалая часть времени разработки уходит на постоянные запуски скрипта, ловле эксепшенов на некорректных операциях с типами и обвязка этих мест кода в try-except'ы или if'ы, так что особой экономии время как-то и не чувствуется.

С интересом поглядываю в сторону Cython (не путать со стандартным интерпретатором CPython) — там типы можно задавать явно, но не уверен, что он будет работать со всеми сторонними питоновскими «батарейками».

Наилучшая система типов из всех испробованных мною языков — в C#. Можно указать тип явно (int, string), можно неявно (var) — логика программы не меняется, просто тип будет выведен автоматически на этапе компиляции, а можно динамически (dynamic), тогда все проверки будут на этапе выполнения.
Да и вообще благодаря чудесному Intellisense, 99% ошибок с типами отлавливается ещё на этапе набивания кода, что, в отличие от питона, как раз таки способствует быстрой разработке.
Cython вообще для другого. Cython позволяет писать модули расширения (pyd-файлы, что по сути динамические библиотеки), на python-подобном языке со статической типизацией. Это нужно, когда требуется высокая производительность, так как такой код транслируется в Си. Писать всё подряд на Cython неудобно, и никто обычно этим не занимается. На Cython пишут только узкие места, критичные к производительности, чтобы не связываться с C Python API или C++ (Boost.Python).
Я раньше просто обожал Python. Но чем больше я его узнавал, тем меньше мне хотелось его использовать. А сейчас я думаю куда бы соскочить совсем.
Sign up to leave a comment.