Pull to refresh
77
0
Журавлёв Юрий @stalkerg

Разработчик

Send message

Ну это не часть языка а с боку прикреплённая конструкция, работающая только в runtime.

Мало смысла от интерпретатора языка с СТ так как тогда вы не сможете проверить полноценно типы до запуска. Ну и СТ позволяет как правило производить относитльно легко эффективный машинный код чем грех не воспользоваться.
А компилируемый ДТ не будет во время такой операци опущен до машинного кода по настоящему. (т.е a+b не будет выглядить как комманда процессору a+b ) По сути вы просто смержите интерпретатор или его части с вашей программой. Тут только JIT может помочь хотя это уже runtime.

Да, типы документацию не заменяют. Но сильно упрощают навигацию по ней.

И тут я с вами согласен. Хотя это вопрос сильно завязан на процесс подготовки к разработке.


А откуда он возьмётся, этот хороший дизайн, если писать код в соответствии с вашими советами — без проектирования и строго в порядке его исполнения?

Я не призывал отказываться от проектирования, просто это не должно быть самоцелью. Если уж говорить про советы то это KISS, DRY, YAGNI and premature generalization is the root of all evil.


от же rollup — это всего лишь бандлер, в то время как gulp — система сборки.

он не просто бандлер и плагинов у него так же навалом, да и во многом может заменить gulp.

1) Благодаря выводу типов, во многих современных языках программирования не так часто требуется явно указывать типы переменных.

Вывод помогает при работе с перменными внутри функций, но боилерплейт остаётся при объявлении интерфейсов (это и функции если что).


2) Динамическая/статическая типизация и компилируемость/интерпретируемость вещи ортогональные — ЯП может быть компилируемым и с ДТ, а может быть интерпретируемым, но с СТ.

Вопросс во времени, запуск Python, JS, PHP почти моментальный, сборка большого проекта с шаблонами на C++/Rust уже может занять десятки минут (и даже если вы не с 0 собираете это дольше). У C#/Java по лучше дела но старт и прогрев VM это отдельная боль.


3) Какая связь между объявлением класса и связанностью кода?

Прямая! От класса могут унаследоваться, у класса более сложный интерфейс (функции, данные), это тяжёлая абстракция которая увеличивает связанность, отчасти по этому в Rust и Go от них отказались.


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

Мы не про паттерны тут вообще.


Заодно было бы интересно узнать ваше мнение по вот какому вопросу: если динамическая типизация настолько хороша, почему во многих ДТ-языках (python, php, ruby) тренд на добавление возможностей СТ?

А ещё TS для JS. Во многом это связано с тем что в эти языки переходят люди с СТ языков и чувствуют дискомфорт, пишут плохой код и т.д. эти подпорки позволяют им писать в их стиле более или менее комфортно. Другая важная вещь это то что уже упоминалось тут — навигация по коду.
Если у библиотеки описан СТ интерфейс то при наличии хорошего редактора этим пользоваться становится удобнее и нужно меньше смотреть в документацию и исходники.
К счатью это опционально и можно употреблять только там где от этого выгода привышает минусы.


Ну и если вы меня записываете в противники СТ — то нет, я сам этим пользуюсь, пишу на C/C++ и активно ковыряю Rust (а до этого много писал на C# и Java).

Ну вот допустим стал ты перформенс инженером, сидишь профилируешь код: видишь какие-то умники наслушались лекций про ФП и везде возвращают значения обернутые в Optional и один такой метод горячий прям реально нагружает GC, т.к. где ФП, а где джава. Идешь и меняешь метод, он, скажем, теперь возвращает не Optional, а String но может и null теперь вернуть. Коллега, который этот метод написал давно уволился, а те кто им пользовались половина либо уволились либо стали менеджерами и забыли как программировать. Другие же трогали его год назад и уже забыли где и почему. А тимлид хочет ступеньку на графике таймингов уже завтра. Вот в такой ситуации без типов будет очень больно.

Не очень корректный пример так как Optional это свойство СТ языков и в ДТ у вас такой вопросс просто не встанет.

Очень забавно, но иногда мне кажется, что я 100% времени трачу на рефакторинг: мне часто дают задачи взять кусок кода написанный ранее левой пяткой и сделать его быструю и надежную версию к тому же добавив новый функционал.
Но свой код я рефачу достаточно редко:)

Такое и у меня бывает, но редко как правило пишу новый хендлер или новый плагин к системе. Если кто то написал совсем кривой хендлер/плагин то его может быть и впрямь проще написать с 0.


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

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


(на остальное по позже отвечу)

Либо у вас такая задача, которая позволяет писать настолько слабо связный код (и тогда вам никакая СТ не помешает делать то же самое)

Принципиально писать слабо связанный код на СТ мне никто не мешает но на практике получается что:


  1. У ДТ нету болилерплейта связанного с типами, и код получается чище (и компилировать не надо).
  2. Почему то решения для СТ (библиотеки и прочее) толкают тебя к писанию и сильно связаного кода. Вместо callback функции к примеру, обьявлять класс… или для того что бы записать что то в файл из сети надо реализовать целый конвеер по сохранению.

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

Я честно не понимаю.

Надеюсь смогу пояснить.


Ещё один хороший аргумент который постоянно всплывает. С моим коллегой мы выяснили что он в СТ 80% времени тратит на рефакторинг и только 20% на написание нового кода, у меня же обратная пропорция. Очень странно правда? Мы стали выяснять и поняли что:


  1. В СТ вы пишите сильно связанный код, где изменения в одном месте обязывает вас менять много других кусков.
  2. В ДТ как правило пишут слабо связанный код, где мало связей между модулями (к примеру хендлер у API endpoint).

Ну вот вы написали пайплайн, а потом уволились и мне надо добавить изменений в середину?

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


Или скажем изменить какую-то функцию, которой пользуетесь вы и ещё в нескольких разных местах разные люди?

Берёте и меняете… если вы меняете поведение функции то вы либо создаёте новую функцию с новым именем либо (что геморойно и зачем такое вообще?) бегаете поиском по проекту и меняете поведени, но вообще это моветон такое делать не соглосовав с коллегами. Если вы только добавляете аргумент то ничего менять не надо.


И начинается Дженга, где одно неловкое движение и башня упадет.

Не вижу где она тут начинается. Ну и если где то подправить забыли то на тесте упадёт и вы это подчистите.


Или вы просто выбрасываете весь ранее написанный код и переписываете его заново?

Нет, зачем? Если я меняю что то в одном месте это только в крайнем случае влияет на остальную программу.


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

Хорошую документацию типы не заменяют. Я согласен что в простых случаях вам это может быть достаточно но в случае с любым Builder вам всёравно лучше глянуть документацию и изучить методы/поля.


К слову в Rollup с этим по проще. ) Это я к тому что ДТ куда более чувствителен к хорошему дизайну, увы в JS люди не так сильно знакомы с Zen Python. Собственно я уже говорил тут что "простота" и "явность" особенно важны для ДТ.

Видимо стоить раскрыть ещё одну тему из моей гипотетической статьи — уверенность.
На тему СТ и ДТ я очень много спорил с моим коллегой и он был ярым поклонником СТ. После очень долгих и детальных обсуждений мы выяснили что мы по разному относимся к риску и понятию "уверенности". Для него было не комфортно быть не уверенным в типе переменной или в поведении, тогда как я не чувствовал никакого дискомфорта. Скорее всего вы пытаетесь «держать всю программу в голове» именно из-за того что не полная уверенность вам некомфортна и вызывает негативные эмоции. Разное отношение к риску основано во многом на вашей генетике и воспитании, сюда же входит насколько импульсивно вы принимаете решения.
Если вам нравится всё контролировать, строить в голове абстракции, любите строгость (в том числе в искусстве) то скорее всего ДТ вам будет крайне не удобно.
Все люди мыслят по разному, но судя по всему есть разные патерны исходящие из сильных и слабых сторон вашего мозга. У кого то хорошо с памятью (причём по отдельности быстрой и долгой), у кого то с аналитическими способностями а кто то силён в творчестве (программирование это в том числе творчество). И это всё влияет на выбор вами ЯП, технологий и прочего. Я надеюсь эти идеи не покажуться вам слишком радикальными.

Тут на самом деле всё просто — названия и самостоятельный вывод типов.
Если к вам в функцию check_name приходит аргумент my_name а потом ещё и в следующих строчках идёт работа с текстом то ты не особо задумываешься.
Это классическая проблемма людей которые приходят к ДТ из СТ, вы начинаете проектировать программу, строить абстракции а так как типов в интерфейсах нет вы быстро в этом тонете т.к. держать в голове всё невозможно.

Я не очень понял на что вы отвечаете… я не говорил что так нельзя писать на ЯП с СТ, я говорил что это очень важно для ЯП с ДТ, а для СТ это не настолько критично (типы дают ту избыточность которая позволяет вам проводить навигацию даже в тонне оверинженерингого кода)

Что касается концепций, признаться не могу понять в чем аргумент. У меня например постоянно такое, что концепции одинаковые (по крайней мере в моей голове), а код всё таки приходится подправлять.

потому что вы программируете через проектирование, а не через исполнение

Как мы уже говорили, питонисту очень многое приходится делать самому — проверять типы, держать в голове, где будет None, а где число, искать в документации, какие исключения может выбросить функция.

Задам этот вопрос ещё раз — а вы точно python разработчик? Дело в том что разработчики на ДТ языках не думают так как вы описали, такие проблемы просто не встают.
Больше похоже как будто вы после Java/C#/C++ решили поработать с Python и перенесли практики в него которые естественно не заработали.

if len(array) == 0:

А вы точно python программист? Python программист напишет тут


if not array:

Я люблю Rust но вы сравниваете тёплое с мягким. Если вы хотите находить ошибки локально вам не mypy писать надо а тесты.

Да, примерно так и пишется изначально.

Самое интересное, что я не читал ваш комментарий когда ответил точно так же ниже. Это важный ключевой момент.


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

Да, это и похоже на перемещение контекста вместе с процессом исполнения.

Звучит так, как будто программа пишется так же, как исполняется её исходный код, в виде некоторого пайплайна.

именно, при написании на ДТ языках вы в значительной мере не думаете о ниже изложеных вами вещах и концентрируетесь на потоке.


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

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


версию игры в Дженга

именно так выглядит написание программы на языках с СТ. Это особенно чувствуется в Java/C# и возможно в Rust. В C#/Java это усугубляется обязательностью классов и в целом классовым ООП.

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

Отличная статья! Я тут как раз начал писать статью почему динамическая типизация хороша (в зависимости от...). На самом деле вся вторая часть статьи про плюсы статической типизации это отличная иллюстрация где выигрывает динамическая. Это же какая когнитивная нагрузка думать о этих всех дженериках, типах, выводах типов и прочем. :)
На самом деле хочется опровергнуть последний пассаж:


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

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


Никто не пытается держать в голове всю программу и никто постоянно не думает о том какие переменные могут прийти в функцию. Программист на ЯП с ДТ и программист на ЯП с СТ мыслят по разному во время написания программы. Главное различие тут в том что:
Со статической типизацией вы концентрируйтесь над структурой или конструкцией программы (как будто на черчении дом рисуете и вам нужно чтобы детали все подходили, материалы выдержали вес и т.д.)
С динамической типизацией вы концентрируетесь над потоком исполнения, контекст движется вместе с этим потоком и вам очевидно что происходит вокруг, но именно поэтому в этих языках важно писать как можно проще (явно как завещал Гвидо), компактнее и выбирать максимально читабельные и полные названия для всего.


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

ну не знаю… я люблю JS или Python больше чем TS, дело вкуса, стиля разработки и области.

1
23 ...

Information

Rating
Does not participate
Location
Токио, Токио, Япония
Date of birth
Registered
Activity