Обновить
32
Огромный Боевой Человекоподобный Робот@Tanner

Python-программист

0,6
Рейтинг
22
Подписчики
Отправить сообщение
Мне кажется, вам стоило ограничить пост цитатой «Про эффективность хирургических масок». Только без хайда.
“Have I Been Pwned” не спрашивает пароль, только имейл.
Так это проблема Gravatar, а не StackExchange. Можно пользоваться SE, не имея аккаунта на Gravatar.
Я не совсем понял, что такое «приготовление бурбона»? Бурбон получают дистилляцией и выдерживанием в бочках, насколько я знаю.
Я именно этому доводу из статьи и оппонирую. Если динамические языки не помогают, то почему на статических языках так часто реализуют динамические системы типов?
Вы отчасти правы, у меня действительно «подгорает», когда мои любимые инструменты задвигают в угол. Но ответа на свой вопрос я всё-таки не получил. Допустим, го-свичеры написали cty, потому что заскучали по Пайтону, но как тогда насчёт GObject? А имплементациям этим нет числа, не зря появилось правило Гринспуна.
Они сначала так и думали. Но в процессе оказалось, что именно динамическая, потому что ноды разнородные, и где какой тип данных объявлен, непонятно. И валидировать её централизованно не всегда возможно, так как обрабатывает её сторонний код.
Я пытаюсь сказать, что динамические данные проще парсить динамическим языком.
Статья, перевод которой мы сейчас читаем, написана фактически как продолжение дискуссии о том, действительно ли парсинг JSON в статических языках является таким уж адом, каким его зачастую описывают, или ничего, можно терпеть.

Автор вот говорит, что можно терпеть, и даже описывает какие-то best practices. Но я чаще слышу противоположное мнение. А лучшие практики ИМХО − это такие практики, которым проще следовать, чем не следовать. Когда их знаешь, конечно.
Когда вам говорят, что вы чего-то не знаете или не понимаете, а вы приравниваете это к обвинению в глупости − это в вас говорит снобизм или чувство превосходства. Мы все можем не знать или не понимать чего-либо, независимо от уровня нашего интеллекта. Но, чтобы уметь учиться, нужно быть открытым к разным точкам зрения.

А если вы хотите обоснований, можете познакомиться с проектом, в котором я долгое время варился. Он имеет весьма навороченную систему динамической типизации, маскирующуюся под сериализатор данных. Эта система порождает множество проблем, начиная с мелких багов и кончая принципиальной сложностью её более-менее интероперабильной, кросплатформенной реализации. А между тем разработчикам достаточно было встроить какой-нибудь динамический язык (благо, на JVM реализовано много универсальных ЯП: Python, Ruby, JavaScript, Lisp, Tcl), чтобы забыть о реестрах типов, версионировании объектов (Duck Typing), интеропе (те же ЯП встраиваются и в C++, и в C#) и много о чём ещё. Заодно и облегчить подключение кастомного кода при распределённых вычислениях. А критичные части системы (сеть, обнаружение нод, алгоритмы дупликации и восстановления данных) оставить как есть.

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

Иными словами, я не против статически типизированных языков. Но когда то, что вы пишете на статическом языке, начинает сильно напоминать интерпретатор динамического языка (или, как минимум, его часть), имеет смысл не переизобретать велосипед, а выбрать готовый.
Вряд ли это основная причина. Скорее, наоборот, вполне себе опытные разработчики на статически типизированных ЯП не понимают, что такое динамические системы типов и зачем они нужны (некоторые вообще отрицают существование динамических типов). И поэтому вынуждены каждый раз переизобретать их.
Тогда зачем стопицотый проект на C, C++ или Java в стопицотый раз имплементирует динамическую систему типов вместо того, чтобы использовать по назначению уже имеющиеся в наличии Lua или там Groovy? По мне так явный NIH-синдром.
И действительно оказывается, что функции pickle.load() можно дать совершенно разумный тип в Java:

Я бы переформулировал это так: чтобы не писать на уже готовом динамическом языке, который фу-фу-фу, мы (в очередной раз) имплементируем его часть − динамическую систему типов − на нашем любимом статически типизируемом языке. Потому что Serializable − это же только интерфейс. В общем, NIH-синдром в полный рост.
Хранить секреты в переменных среды небезопасно (1, 2).
Правда ваша, кто про что, а шелудивый (я) про баню…

С другой стороны, тут также самозародились C, Fortran, ассемблер, Go. А на горизонте маячат загадочные языки без return. Видимо, не я один проморгал тег “Java”.
Этот тест сравнивает эксепшн с if. if, конечно, менее затратен, чем поимка эксепшна, но не способствует читаемости кода. Я сравниваю поимку эксепшна с вызовом функции.

Например, выход из двойного цикла.

Вариант 1 − двойная проверка
def t1():
    result = False
    for i in range(10):
        for j in range(20):
            if i == j == 5:
                break
        if i == j == 5:
            result = True
            break
    return result



Вариант 2 − исключение
def t2():
    result = False
    try:
        for i in range(10):
            for j in range(20):
                if i == j == 5:
                    raise Exception
    except:
        result = True
    return result



Вариант 3 − вынос циклов в отдельную функцию
def t3_inner():
    for i in range(10):
        for j in range(20):
            if i == j == 5:
                return True
    return false


def t3():
    result = False
    result = t3_inner()
    return result



Вариант 4 − for… else
def t4():
    result = False
    for i in range(10):
        for j in range(20):
            if i == j == 5:
                break
        else:
            continue
        result = True
        break
    return result


Все варианты выполняются за примерно одинаковое время, ±5%, если верить timeit. Вариант с эксепшном мне кажется наиболее читаемым. Последний вариант − самый быстрый, но и самый нечитаемый. В общем, затраты на обработку эксепшна вполне приемлемы.
бросить почти ни чего не стоит, а перехват обходится дорого.

Во-первых, перехват эксепшна − это никаким боком не дорого в Python. Да, я читал документацию. Тем не менее, технически перехват эксепшна сводится к поиску в некоем фиксированном количестве словарей. Как и вызов функции/метода. То есть если вы хотите оптимизировать, например, выход из двойного цикла, который в других языках можно было бы оптимизировать с помощью goto, то выход с помощью эксепшна в Python будет как минимум так же эффективен, как вынос внутреннего цикла в отдельную функцию. Плюс, выход по эксепшну может быть даже более читаем, чем вариант с объявлением дополнительной функции.

Во-вторых, «никакого разворачивания стека» и «не собирать стек трейс» − это совершенно несопоставимые вещи, вам не кажется?
Исключения для управления потоком выполнения нехороши только потому, что приводят к неопределённым затратам времени на разворачивание стека. То есть в С++ и Java. В Python, например, никакого разворачивания стека не происходит, поэтому исключения стоят столько же, сколько вызовы − пренебрежимо мало в большинстве ситуаций. Поэтому управление потоком выполнения через исключения широко используется в Python, даже в системных библиотеках.

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

Информация

В рейтинге
2 332-й
Дата рождения
Зарегистрирован
Активность