LINUX.ORG.RU

Зачем нужна статическая типизация?, или Вы всё врете!

 ,


1

4

В теме "Питонячьи радости " на последних страницах между мной и @rtxtxtrx внезапно разгорелся спор, из которого я понял, что есть еще люди, которые не считают динамическую типизацию (в том виде, в котором она представлена в Питоне, а именно строгая динамическая типизация) серьезным недостатком при работе с большим объемом кода, особенно при рефакторинге. Вообще изначально разговор завязался вокруг назначения type hints введенных в Питон 3: я утверждал, что они нужны для создания семантических связей в коде, которые будут препятствовать внесению деструктивных изменений в код в результате опечатки или иной ошибки кодера (изменил код, в результате которого какое-либо выражение получило некорректное значение, которое тем не менее обладает схожим с корректным значением типовым контрактом, поэтому при запуске код не «упадет» сразу, указав на проблему); оппонент заявил, что они нужны для (само)документации и не более того.
Но потом выяснилось, что и царь-то ненастоящий (читай, статическая типизация). Не нужна она, просто именуй сущности понятно и уповай на строгую типизацию. А если типизация не строгая, то сами виноваты, у нас в Питоне всё ОК.
Поскольку тема большая и вкусная, я предлагаю всем обсудить этот очень важный вопрос в меру скромных сил и познаний каждого желающего. Обсуждение вторичных вопросов, как-то «статическая типизация нужна для генерации эффективного кода», «при динамической типизации тип только один, object» etc. не предусмотрено — спорим только о том, дает ли статическая типизация выигрыш, если надо перекраивать несметные тыщи kloc. Если есть вообще о чем спорить 😅.

★★★★★

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

Большую часть времени программа пребывает в состоянии «что-то уже сделано, а что-то ещё нет»

Есть ещё состояние «половина функций имеет телом undefined».

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

Аннотации - годная штука.

Фактически, применяя аннотацию, программист признаётся, что Java — недостаточно мощный язык и ему нужно что-то другое.

не знаю никого, кто бы это любил)

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

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

Понимаешь, это всё проблемы уровня «мне классы мешают хелло ворлд написать в две строчки».

Порефактори объемную кодовую базу с более чем 10-летней историей, куда бесконтрольно заливались фичи, а над архитектурой думать было некогда. Узнаешь, что такое боль.

Это вон тот самый «Скрам. Фичи, фичи, фичи.» (c)

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

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

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

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

Понимаешь, это всё проблемы уровня

У нас тут вся индустрия последние 40 лет работает над сокращением цикла разработки, целый CI/CD придумали, чтобы с максимальной скоростью доставлять изменения и проверять идеи. А тут приходит персонаж и рассказывает про хелловорды на две строчки. Ясно-понятно, будет исполнено.

Порефактори объемную кодовую базу с более чем 10-летней историей,

У меня под боком толпа в триста ява программистов ноет, вот так же точно как вы сейчас. Чёт не затащила статика, наверное где-то ещё нужно ответ искать.

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

У меня под боком толпа в триста ява программистов ноет, вот так же точно как вы сейчас.

Ты чо-то попутал. Ноешь тут ты, тебе проверки типов компилятором мешают говно месить «скопировав функции в новый файлик». Какие 300 программистов, очнись.

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

применяя аннотацию, программист признаётся, что Java — недостаточно мощный язык и ему нужно что-то другое.

мы точно об одних и тех же аннотациях? Это фича языка, а не «что-то другое».

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

Но вот мотивацию «я хочу писать заведомо сломанные программы, а ваш компилятор мне мешает!» я в этом треде услышал впервые.

Это у кого такое? Вроде мешает писать рабочие программы, не укладывающиеся в систему типов.

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

А в Go я вместо repl’а могу создать новый файл main.go скопировать туда нужные функции и быстро скомпилировать.

В Хаскеле тоже. От нового файла определённо ничего не зависит, значит можно делать любые типы.

А кто мешает сразу выбрать другой язык?

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

Плюс в Хаскеле есть диспетчеризация по типу возвращаемого значения.

Здесь вызываются разные функции read:

(read "123" :: Int) == 123
(read "123" :: Float) == 123.0
monk ★★★★★
()
Ответ на: комментарий от wandrien

Порефактори объемную кодовую базу с более чем 10-летней историей, куда бесконтрольно заливались фичи, а над архитектурой думать было некогда. Узнаешь, что такое боль.

Я этим регулярно занимаюсь на языке 1С. Отсутствие типизации не мешает. И иногда помогает, если надо расширить объём пробрасываемых данных через полдюжины уровней кода.

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

В типизированных также. Заглушки типа

getLogin a b  = ""

getDBTotal db a b c = 0

Кстати, на нетипизированном Racket приходится писать также. IDE полнофункционально работает только если все используемые функции существуют.

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

Штук пять постов об этом опубликовал, думал кого-то этот вопрос заинтересует.

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

Многие статически тупизированным макакам очень не нравятся языки с динамическим петушением. Их в шок приводит тот же JS:

if ((new class Foo {
  foo() {
    console.log('bar')
  }
}).foo());

Он позволяет себе многое: например, засунуть в условие ЛЮБОЕ ВЫРАЖЕНИЕ (ну почти). Макаки хватаются за сердце, начинают яростно бросаться собственным калом в монитор и строчить посты и сообщения на ЛОРЧане полные ненависти к этой ереси. Проблема только в том, что хоть так и можно, никто так не делает…

Так же макаки с презрением смотрят на нестрогую типизацию:

    [[], {}, [42], 42, '42', null, undefined, NaN].forEach((lhv, _, thisShit) => {
        for (rhv of thisShit) {
            if (lhv === rhv) continue
            console.log(`${JSON.stringify(lhv)} + ${JSON.stringify(rhv)} =`, lhv + rhv)
        }
    })
[] + {} = [object Object]
[] + [42] = 42
[] + 42 = 42
[] + "42" = 42
[] + null = null
[] + undefined = undefined
[] + null = NaN
{} + [] = [object Object]
{} + [42] = [object Object]42
{} + 42 = [object Object]42
{} + "42" = [object Object]42
{} + null = [object Object]null
{} + undefined = [object Object]undefined
{} + null = [object Object]NaN
[42] + [] = 42
[42] + {} = 42[object Object]
[42] + 42 = 4242
[42] + "42" = 4242
[42] + null = 42null
[42] + undefined = 42undefined
[42] + null = 42NaN
42 + [] = 42
42 + {} = 42[object Object]
42 + [42] = 4242
42 + "42" = 4242
42 + null = 42
42 + undefined = NaN
42 + null = NaN
"42" + [] = 42
"42" + {} = 42[object Object]
"42" + [42] = 4242
"42" + 42 = 4242
"42" + null = 42null
"42" + undefined = 42undefined
"42" + null = 42NaN
null + [] = null
null + {} = null[object Object]
null + [42] = null42
null + 42 = 42
null + "42" = null42
null + undefined = NaN
null + null = NaN
undefined + [] = undefined
undefined + {} = undefined[object Object]
undefined + [42] = undefined42
undefined + 42 = NaN
undefined + "42" = undefined42
2x undefined + null = NaN
null + [] = NaN
null + {} = NaN[object Object]
null + [42] = NaN42
null + 42 = NaN
null + "42" = NaN42
null + null = NaN
null + undefined = NaN
null + null = NaN

Макаки испытываю сметение, подавленную волю, когда узнают, что им предстоит писать НА ЭТОМ.

И тут мы подходим к главному: А КАКОЕ ОТНОШЕНИЕ ЭТО ИМЕЕТ К PYTHON?

❯ python
Python 3.11.5 (main, Sep  2 2023, 14:16:33) [GCC 13.2.1 20230801] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> [] + {}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can only concatenate list (not "dict") to list

В таких ситуациях не хватает забаньсядебила, который всегда мог дать хороший совет…

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

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

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

Уважаемый ФишХук, у вас в функции описано, что она ожидает на вход, следовательно в юниттесте этой функции, вы должны убедиться как она себя ведет при невалидном значении на вход, но вы решили что программисты безгрешны (на авось иными словами). Странно, что такие элементарные вещи необходимо объяснять.

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

и сколько ты таких файликов за день создаешь? вот тебе и надо тесты писать, а скриптобогам достаточно repl запустить чтобы проверить функцию из 10 строк

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

Ограничения питона — вообще излишни. В жизни нам никто не запрещает пальцы в огонь сувать или ножом в глазу поковыряться. Не понимаю зачем язык должен ограничивать кого-то в возможности обфускации кода

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

Странно, что такие элементарные вещи необходимо объяснять.

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

def create_key(metrics: tuple[str, str, str]) -> str:
   return "".join(get_metric_key(m) for m in metrics)

И всё! Финита, проблема решена, небезгрешные программисты больше не засунут по ошибке другой итератор. Без дополнительных тестов. Это настолько очевидно, что даже тупо. Как с этим можно спорить я не понимаю! Наверное, стоит меньше борьбой заниматься, а то это сказывается на когнитивных способностях

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

Будто на джавадрисне твой код не упадет, если в редиске нужных данных не окажется. Тесты вообще сложная вещь. Если изначально через тесты разработку вести, подготовить все эти тестовые данные, написать конфиги композа, чтобы базы поднимались, заполнялись нужными для тестов данными. Но это ж кому-то писать надо, а у всех АДЖАЙЛ кроме твоей конторы, где все занимаютя Ⱈ его знает чем, ты, например, тут в рабочее время комменты строчишь

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

Во-первых, ты не знаешь, в каком часовом поясе я живу, вполне может быть, что у меня и НЕ рабочее время, или вообще отпуск.

Во-вторых, «кроме моей конторы». Моя контора в прошлом году заработала чуть больше пяти лярдов долларов https://www.statista.com/statistics/1114313/total-revenue-of-workday-since-2016/. Предположу, что это может быть как-то связано со стандартами качества кода, и может даже так получиться, что тебе стоило бы поучиться у «моей конторы»?

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

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

что ты вообще не понимаешь

я не понимаю

здесь никто ничего не понимает, а автор вообще «не сварщик»

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

Там выше уже Ресет приводил вариант, когда твои аннотации идут лесом. Бесплатный совет тебе - не пиши говнокод (я хз как твой код этой функции прошёл ревью). И да, нормальные тесты вообще исключили бы эту проблему (но тесты видимо не твоё, ты серебрянную пулю ищешь…).

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

Аннотации ни к чему не обязывают - это подсказки для редактора. Бредни всяких ресетов, редактирующих код в виме по ссх так же ставят вопрос о твоей вменяемоести, а фраза:

Интеграционный тест тоже не выявит проблем

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

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

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

Уверен, что в юниттесте типа

assertRaises(Exception, create_key, 1)

всё хорошо.

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

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

Финита, проблема решена, небезгрешные программисты больше не засунут по ошибке другой итератор.

Зато могут засунуть другой кортеж из трёх строк.

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

Опять же, от смены арности не помогает

В хаскеле ЕМНИП это не проблема, ибо там все функции это функции от одного аргумента плюс магия повсеместного каррирования. Это и по сигнатурам видно, map, например: map :: (a -> b) -> [a] -> [b].

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

Технологии настолько развились

@

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

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

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

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

Зато могут засунуть другой кортеж из трёх строк.

А еще можно сдуру базу на проде грохнуть. Является ли это проблемой тайпхинтов?

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

Так я и говорю, что аннотации, от говнокода, не спасут.

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

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

Автор с питончиком знаком уже лет 15, поэтому что я там «увидел» это, конечно, интересно было узнать 🤣. Хотя близко с 3 версией не знаком, но аннотации типов это очень старая история, чтобы о ней не знать. А истерично строчит комменты тут кто угодно, только не я, не будем показывать пальцем 👉. Я уделяю внимание своей созданной теме в том объёме, который считаю нужным.

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

Я вот не прошу многого. Я прошу лишь тайп-хинты в коде использовать. Ну не могу я уже видеть шедевры типа def do_something(obj) ладно бы еще писали user, post, comment - понятно бы было какая модель, но любители монады и матана предпочитают шокировать названиями типа q, r, t, p. Это, кстати, реальный пример где и тайп-хинты бесполезны

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

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

Если тестировать как чёрный ящик, то угадать почти нереально.

P. S. Если важно, чтобы попадало нужное, то передаётся не кортеж, а экземпляр класса. И на [... in metrics.metricdata()] становится на порядок сложнее передать не то.

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

Ну не могу я уже видеть шедевры типа def do_something(obj)

Тебе было бы легче, если бы рядом было указание, что obj строка?

ладно бы еще писали user, post, comment

И это всё может быть строка…

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

2.7 хватало как-то, когда надо было 🤷‍♂️. Я же — ненастоящий 😊.

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

obj - это не строка это инстанс чего-то, но непонятно чего. Строку просто бы s обозвали. С check_username(s) все нормально. Username, password, email, phone и тп - только строки, но все равно, если уж в остальных местах типы указаны, то пусть и тут указываются

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

Да и такое нормальным бы было:

class User:
  @classmethod
  def check_username(cls, obj):
    ...

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

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

Разные подходы и системы типов - это попытки придумать всё более мощный язык описания этой неправильности. Начиная от простейшей типизации в Си и заканчивая всякими системами зависимых типов.

Загвоздка в том, что в мейнстримных ЯП языки аннотаций очень топорные. В результате кроме тривиальных случаев всё это больше мешает. И начинатся финты ушами с ослаблением типизации. Вместо того, чтобы решать задачу, сидим и думаем как обмануть систему типов. Ну в си или голанге это просто, а если сделать язык строгим-престрогим, то будет больно. И тут нужен очень навороченный язык аннотаций (может сложнее самого ЯП) и/или вывод типов. Без вывода бывает вообще невозможно описать иной тип. А вот в динамике этих проблем совсем нет (но есть другие), и языки при этом остаются простыми. До тех пор, пока к ним не начинают прикручивать аннотации в стиле питона. Там и сам по себе убогий ЯП, так сделаем его ещё тупее. А программисты то хитренькие, они будут эти ограничения при любой возможности обходить скатываясь в динамику. И багов все равно будет вагон, зато все str -> str будут добросовестно проверены.

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

Была тут одна тема, про которую меня никто не спрашивал, и поэтому я ее точна вам расскажу

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

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

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

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

А это востребовано не всегда. А писаниной вы будете заниматься всегда.

Писаниной или поиском ошибок, которые вызваны отсутствием писанины.

Это как в анекдоте: украли ящик водки, продали, а деньги пропили.

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

Зато могут засунуть другой кортеж из трёх строк.

Это если вы набираете себе штат на крыльце психбольницы, а так маловероятно

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

Деточкин бы поступил по другому.
Украл ящик водки, продал бы, а деньги вернул в ЛОР.

А шо тут в треде?
Кто побеждает - остроголовые или тупоголовые?

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

Кто побеждает - остроголовые или тупоголовые?

А кто бы судил поединок…

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

Тупоголовые всегда побеждают. А в треде кто за чем пришёл, тот то и получил. Кто поспорил, кто поговорил, кто почитал. В целом все остались при своих, ну хоть развлеклись 🙂.

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

Гм, пошутил ...
Я сам бываю иногда и «тупоголовым» и «остроголовым».

Вот на парсинг глобального модуля с первого захода накалякал 3000 строк.
Ну чем не «тупоголовый»?

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

Строку ведь вместо кортежа засунули.

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

Вот на парсинг глобального модуля с первого захода накалякал 3000 строк.

Широкой души Вы человек 😊. Будет и второй заход?

Virtuos86 ★★★★★
() автор топика
Закрыто добавление комментариев для недавно зарегистрированных пользователей (со score < 50)