Бегло посмотрел на indeed — на rust 1000+ вакансий, на паскале — около 50, на delphi — 24 (все с фильтром зарплаты 50+ в год, чтобы убрать поваров в Pascal's Pizzeria).
А не в России, в некоторых странах на порядок больше чем на C# или C++.
Переменная - часть любого алгоритма, которая должна быть строго определена.
Нет, конечно, это не так.
Объявляю алгоритм обмена значений как морфизм A × B → B × A, описанный как ⟨ π₂, π₁ ⟩. Здесь нет никаких переменных (ни временных, ни постоянных, никаких), при этом это вполне строго определённая формальная категориальная конструкция.
Разница такая, что я не могу абстрактные метаконцепции переложить в код, нужны какие-то конкретные примеры, чтобы поиграться.
Но пока что выглядит так, что всё ещё у вас там просто добавился один из вариантов вокруг уже имеющейся семантики, и это вполне выразимо в достаточно мощных статически типизированных языках.
А проблема как раз в большой кодовой базе: становится безумно тяжело производить изменения.
Почему тяжело? Легко же. Компилятор вам сразу показывает, где семантика могла поменяться.
нам нужно протаскивать руками всю асинхронность наверх
Если вызывающая функция требует результаты асинхронной функции, то она тоже становится асинхронной, поэтому всё работает как и должно.
Если же не требует, то, насколько я знаю, даже в мейнстримных языках не обязательно раскрашивать все функции аж до main, можно так или иначе detach'нуться от асинхронности.
Я хочу видеть, возвращает ли функция результат сейчас, или её надо подождать, прям в её типах, и хочу, чтобы компилятор мне говорил, если мои ожидания расходятся с реальностью.
Асинхронность — это просто один из эффектов. Эффекты полезно видеть в типах. Особенно в большой кодовой базе.
Настоящий программист должен точно знать, сколько байт памяти выделяет его код, в какие машинные инструкции он преобразуется
А плюсы этого больше не дают, всё. Без оптимизаций у вас std::move может быть отдельной функцией (а может и не быть), но без оптимизаций на плюсах на практике никто не пишет (кроме совсем настоящих программистов, пишущих такой код, что глупый оптимизатор его ломает), а с оптимизациями — там такая же магия, как в каком-нибудь JIT-языке.
уметь писать собственные аллокаторы, контейнеры и т.д.
Контейнеры-то легко, и это можно делать на любом языке, а аллокаторы в плюсах — не стоит вскрывать эту тему. Про это на конференциях доклады делают, причём не об алгоритмике и машинных особенностях, а об особенностях языка (типа, как пропагейтить аллокатор std::vector'а в std::string'и, которые там лежат).
И, кстати, почему настоящий программист должен машинные инструкции и аллокаторы? Почему не категориальную семантику его программы и монадические регионы?
Когда я открываю реальный промышленный код на хаскеле, то там нормально всё с newtype.
На плюсах, в принципе, тоже. Правда, когда я собеседуюсь на приплюснутого ассенизатора, то при написании кода на интервью я вполне себе говорю (и пишу) о типобезопасности и смотрю на реакцию интервьювера, поэтому у меня тут не совсем репрезентативная выборка.
Это, конечно, отсылка к личному опыту и вообще немного выпендрёж, но по-другому отвечать на тезисы «в реальном продакшен-коде не используются несовместимые алиасы типов / тесты / системы контроля версий» тяжеловато.
Другое дело, что он не ко всем проектам подходит (я вот, например, сегодня добавил поддержку нового обрабатываемого типа данных в выполняющуюся программу прямо на ходу, не останавливая её)
Мне как-то (не) везёт писать такой код, где между мной и продом либо несколько слоёв стейджинга, либо это вообще библиотеки и вещи уровня «тайпчекер и интерпретатор для языка смарт-контрактов», где «менять программу при выполнении» не имеет особого прикладного смысла.
Поэтому, короче, я не могу эффективно спорить на этой территории за отсутствием наработанных паттернов. Какой тип добавили? Зачем? В чём конкретно это добавление выражается? Где бы вы упёрлись в выразительном статически типизированном языке? ХЗ.
Если выкинуть из вашей фразы слово «паскалевской», то не соглашусь: приблизит.
В какой версии буста там STRONG_TYPEDEF появилось? Судя по копирайту в хедере (2002-й год) — рано появилось, может, даже раньше boost.lambda и всего такого. Надо, наверное, зачем-то людям разделять типы, чтобы неявных преобразований и ошибочных присваиваний не было.
Нет, Паскаль образец языка с полумерами в отношении системы типов, которые и в смысле контроля ничего особенного не дают, и лишнюю писанину делать заставляют.
О, здесь мы согласны. Но из этого есть простой вывод: не надо рассматривать паскаль (а не «не надо рассматривать статическую типизацию»).
До JS и CPython.
У меня есть разные знакомые, работающие в веб-экосистеме, причём в компаниях от местных консалтинг-бодишопов на три боди до фаанга, и если судить по их рассказам, то проектов на чистом JS, без тайпскрипта, не встречалось уже очень давно.
Другое дело, что в части проектов на TS половина типов — any, но это, гм, другое дело.
Я хочу знать, что написал ерунду, ещё до деплоя в прод (в идеале — вот прям когда я пишу конкретно эту строку, прям в IDE), а не в три часа ночи оповещением с прода, что ровно здесь случилась редкая комбинация условий, которая пошла по тому бранчу, который привёл к прибавлению единицы к адресу.
Религиозной традицией я назвал декларации типов переменных.
А почему вы смешиваете отсутствие типизации (нет, я никогда не буду в серьёзных разговорах использовать оксюморон «динамическая типизация») и неявную типизацию?
Более того, статическая типизация – это шаг к нестрогой типизации, то есть к неявным преобразованиям типов. Даже в Паскале
Паскаль у нас теперь образец языка с сильной и выразительной системой типов?
Реальная востребованность их, как видим, невелика.
Ну куда уж TS и mypy до Lisp и Scheme, понятное дело.
Однако в качестве примеров почему-то приводите задачи ввода-вывода, где статическая типизация не имеет существенного значения. Вы же не предлагаете на самом деле раскидывать нюансы работы с внешним миром по всей программе, вместо того чтобы обучать отрабатывать сериализацию/десериализацию данных на границах слоев?
Статическая типизация как раз помогает доказать убедиться, что на границах слоя сериализация/десериализация была выполнена, и что все части слоя согласны с тем, что именно должно было быть (де)сериализовано.
Это, как всегда, вопрос между затратами на полноценный рефакторинг сейчас и минимизацией проблем потом, или тяп-ляп сейчас, но проблемы потом.
Первое не всегда лучше, это факт.
Бегло посмотрел на indeed — на rust 1000+ вакансий, на паскале — около 50, на delphi — 24 (все с фильтром зарплаты 50+ в год, чтобы убрать поваров в Pascal's Pizzeria).
А можете назвать эти страны?
Нет, конечно, это не так.
Объявляю алгоритм обмена значений как морфизм A × B → B × A, описанный как ⟨ π₂, π₁ ⟩. Здесь нет никаких переменных (ни временных, ни постоянных, никаких), при этом это вполне строго определённая формальная категориальная конструкция.
Разница такая, что я не могу абстрактные метаконцепции переложить в код, нужны какие-то конкретные примеры, чтобы поиграться.
Но пока что выглядит так, что всё ещё у вас там просто добавился один из вариантов вокруг уже имеющейся семантики, и это вполне выразимо в достаточно мощных статически типизированных языках.
Почему тяжело? Легко же. Компилятор вам сразу показывает, где семантика могла поменяться.
Если вызывающая функция требует результаты асинхронной функции, то она тоже становится асинхронной, поэтому всё работает как и должно.
Если же не требует, то, насколько я знаю, даже в мейнстримных языках не обязательно раскрашивать все функции аж до
main, можно так или иначе detach'нуться от асинхронности.Вы о репрезентации, а я как раз о семантике. Что именно было нового в этой семантике?
Integer promotion rules назубок помните? Ученикам рассказываете? Хорошо экзамены по ней сдают?
Говорить, что в си чёткая система типов — это очень смешно.
Чем плохо?
Я хочу видеть, возвращает ли функция результат сейчас, или её надо подождать, прям в её типах, и хочу, чтобы компилятор мне говорил, если мои ожидания расходятся с реальностью.
Асинхронность — это просто один из эффектов. Эффекты полезно видеть в типах. Особенно в большой кодовой базе.
А плюсы этого больше не дают, всё. Без оптимизаций у вас
std::moveможет быть отдельной функцией (а может и не быть), но без оптимизаций на плюсах на практике никто не пишет (кроме совсем настоящих программистов, пишущих такой код, что глупый оптимизатор его ломает), а с оптимизациями — там такая же магия, как в каком-нибудь JIT-языке.Контейнеры-то легко, и это можно делать на любом языке, а аллокаторы в плюсах — не стоит вскрывать эту тему. Про это на конференциях доклады делают, причём не об алгоритмике и машинных особенностях, а об особенностях языка (типа, как пропагейтить аллокатор
std::vector'а вstd::string'и, которые там лежат).И, кстати, почему настоящий программист должен машинные инструкции и аллокаторы? Почему не категориальную семантику его программы и монадические регионы?
Что значит «новый тип»? Какие типы были, и какой тип — новый?
Когда я открываю реальный промышленный код на хаскеле, то там нормально всё с
newtype.На плюсах, в принципе, тоже. Правда, когда я собеседуюсь на приплюснутого ассенизатора, то при написании кода на интервью я вполне себе говорю (и пишу) о типобезопасности и смотрю на реакцию интервьювера, поэтому у меня тут не совсем репрезентативная выборка.
Это, конечно, отсылка к личному опыту и вообще немного выпендрёж, но по-другому отвечать на тезисы «в реальном продакшен-коде не используются несовместимые алиасы типов / тесты / системы контроля версий» тяжеловато.
Мне как-то (не) везёт писать такой код, где между мной и продом либо несколько слоёв стейджинга, либо это вообще библиотеки и вещи уровня «тайпчекер и интерпретатор для языка смарт-контрактов», где «менять программу при выполнении» не имеет особого прикладного смысла.
Поэтому, короче, я не могу эффективно спорить на этой территории за отсутствием наработанных паттернов. Какой тип добавили? Зачем? В чём конкретно это добавление выражается? Где бы вы упёрлись в выразительном статически типизированном языке? ХЗ.
Если выкинуть из вашей фразы слово «паскалевской», то не соглашусь: приблизит.
В какой версии буста там
STRONG_TYPEDEFпоявилось? Судя по копирайту в хедере (2002-й год) — рано появилось, может, даже раньше boost.lambda и всего такого. Надо, наверное, зачем-то людям разделять типы, чтобы неявных преобразований и ошибочных присваиваний не было.А что с ней?
Я могу скомпилировать модуль, определяющий эту функцию, без знания конкретного типа.
Я могу скомпилировать другой модуль, скажем,
тоже без каких-либо конкретных типов.
Ну отлично. Тогда ML-стайл вывод типов вам норм?
О, здесь мы согласны. Но из этого есть простой вывод: не надо рассматривать паскаль (а не «не надо рассматривать статическую типизацию»).
У меня есть разные знакомые, работающие в веб-экосистеме, причём в компаниях от местных консалтинг-бодишопов на три боди до фаанга, и если судить по их рассказам, то проектов на чистом JS, без тайпскрипта, не встречалось уже очень давно.
Другое дело, что в части проектов на TS половина типов —
any, но это, гм, другое дело.Ну так это ключевой момент.
Я хочу знать, что написал ерунду, ещё до деплоя в прод (в идеале — вот прям когда я пишу конкретно эту строку, прям в IDE), а не в три часа ночи оповещением с прода, что ровно здесь случилась редкая комбинация условий, которая пошла по тому бранчу, который привёл к прибавлению единицы к адресу.
Не понял. Можно пример?
А почему вы смешиваете отсутствие типизации (нет, я никогда не буду в серьёзных разговорах использовать оксюморон «динамическая типизация») и неявную типизацию?
Паскаль у нас теперь образец языка с сильной и выразительной системой типов?
Ну куда уж TS и mypy до Lisp и Scheme, понятное дело.
Когда именно я узна́ю, что я где-то случайно попытался прибавить единицу к почтовому адресу?
Статическая типизация как раз помогает
доказатьубедиться, что на границах слоя сериализация/десериализация была выполнена, и что все части слоя согласны с тем, что именно должно было быть (де)сериализовано.