Pull to refresh

Comments 1975

UFO landed and left these words here

А вы посмотрите на остальные статьи этого эпатажного автора. Вы думаете, он опомнится на 27-ой разжигающей статье?)

Мне особенно нравится трезвая оценка с опозданием —
Пару лет назад я уже писал о типизации, но тогда я был молодой, глупый и трусливый

Остается немного подождать для оценки уже этой статьи.
UFO landed and left these words here

Афигенно! Автор, жги! * обновляет страницу, дабы насладится холиваром *

Холивар, вроде не пятница.
Динамическую типизацию зачем то придумал и мало того она жива до сих пор, обычно то что никому не нужно умирает на задворках истории.
Но удивительное дело в динамических появляются типы, а в типизированных val.
Такие дела.
Истина где-то рядом, наверно по середине.
И наверно не всех надо по одну гребенку.

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

val это не динамическая типизация, а лишь вывод типов. Вот почему то многие не понимают принципиальной разницы

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

Как говорил один мой знакомый:


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

А ЯП с нормальными системами типов начали появляться относительно недавно.

А можете привести примеры ЯП с нормальными системами типов?

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

Haskell (хотя 0xd34df00d щас опять будет ворчать, что выразительности не хватает), Idris, вроде бы Scala (хотя точно сказать не могу), с некоторой натяжкой — Rust.

Странно (про Haskell), там ведь и Хиндли-Милнер, и алгебраические типы…
UFO landed and left these words here

Первые два скоро подвезут. Только-только появилось понимание как это сделать чтобы потом компилятор не треснул.
Третье доступно в виде библиотек.

UFO landed and left these words here

Мне ещё регулярно (в чужом коде) встречается Vinyl. Но конечно это всё полимеры...

  1. Динамика это просто атавизм из 90-х, когда языки с нормальными системами типов делать не умели
  2. Haskell, 1990 год.
  3. Python, 1991 год.

Как эти три вещи могут одновременно укладываться в голове? Видимо ваш знакомый не знает одной из них.


Не получится убедить, что Haskell — это подходящий язык для разработки, а Python — не подходящий.


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

Все таки Haskell это полигон для экспериментов, который тем не менее дорос до прода, а активно вывод типов начал проникать в индустрию только в 10ых годах.

Ну так хаскель 90-го года и хаскель совеременный — это очень разные языки.

UFO landed and left these words here
Лучшее, что может быть — это типизация по требованию. Когда нужно, беру и использую. Когда не нужно — избегаю кучи бойлерплейта.

Если бы она ещё работала… Потому что когда тебе нужно, а в апстриме не нужно — вылезай, приехали.

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

Как правило больше, на мой взгляд. По крайней мере если брать языки типа C++, C#, Java, TypeScript

Ну вот и не надо их брать.

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

UFO landed and left these words here

Не очень из-за дурацкого деления типов на структуры и классы.

Структуры и классы никак не делят типы и не мешают. Это лишь определяет reference type/value type и системе типов до этого нет никакого дела.

Есть дело мне при написании программ, потому что мне надо думать, где будет глубокое копирование, а где — поверхностное, где меняется аргумент, а где — его копия. И в дженериках подобное разделение обычно аукается.

В C# тоже самое. По факту, структуры придуманы не от хорошей жизни, а ради перфоманса. И мутабельные структуры — это дорога в ад (во всяком случае в C#). А если структура не мутирует, то думать про копирование особо не надо.

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

За мутабельные структуры компилятор всегда подскажет. Если один раз понять как работают reference type/value type в свифте и использовать их где нужно и как нужно, то никаких проблем не будет возникать, а компилятор в случае чего все-равно заботливо предостережет. Все четко и явно в этом плане. И не придется переживать за глубокое/поверхностное копирование.
А что не так с дженериками?
В самом простом варианте все по-умолчанию imutable, потому что компилятор не будет знать что именно туда придет, а для мутабельности можно и inout или var в нужном месте указать.
В случаях посложнее (generic constraints) у вас в протоколе все ограничения описываются, вплоть до указания что этот протокол только для классов.
Не знаю с какими проблемами вы сталкивались, но по этому поводу у меня голова ни разу не болела.

К сожалению он существует только в яблочной экосистеме.

К счастью, его можно поставить и использовать практически на все, кроме винды. На малинку вот поставил недавно.

Только пользователей пк на винде большинство.

87% это в целом по миру или в сфере разработки? Я видел винду только у тех разработчиков, которым по каким-то причинам было лень ставить линукс. Возможно страх перед неизведанным.

Страх перед паршивыми гуями тогда уж.

На самом деле почти у всех знакомых мне разработчиков в экосистеме .NET и 1С винда — основная ось для этой разработки. Линуксы — только для кроссплатформенных задач.

На самом деле у 100% разрабочтиков в экосистеме Яббле стоят XCode и MacOS — основная ось для этой разработки. Винды — только для задач HR/серкретарш и бухгалтерии.

UFO landed and left these words here

Так исторически сложилось, что на свифт перешли все кто писал на ObjC, а он существовал в рамках эппловских операционок, поэтому большинство пишущих на нем — маководы. А так как язык молодой, то пока еще не успел выбиться из нативной разработки под MacOS/iOS (в плане популярности), хоть эппл и делает многое, чтобы он мог быть универсальным. Бекенды эти ваши давно уже можно писать, с ардуинками играться, TensorFlow переходит на него как на основной язык. Дайте малышу время)

UFO landed and left these words here
хоть эппл и делает многое, чтобы он мог быть универсальным.
А что именно он делает? Мне просто интересно. Компилятор предоставил? Так Objective C всегда был под разные платформы (стараниями Столлмана, правда, вопреке желанию Джобса… но был).

Каких-либо попыток сделать разумную среду, которую можно использовать вне экосистемы Apple я не наблюдаю… да неясно какой в ней мог бы быть смысл: Apple же нужно сделать так, всё-таки, чтобы «хомячки» не разбежались с его платформы, а не чтобы кто-то вне её творил…

TensorFlow переходит на него как на основной язык
Кто сказал? Откуда уверенность, что из этого не получится очередная стелла на известном сайте?
Fullstack-разработка на swift вполне себе цель. В смысле — клиент под ios + серверсайд под линукс.

Про TensorFlow Google сказал, мол уходят с питона на свифт. Потому что быстрый, безопасный и: https://en.wikipedia.org/wiki/Differentiable_programming


Если появится очередная стелла, свифт от этого никак не пострадает. Но это не отменяет факта, что свифт уже не только язык для “хомячков” с платформ Apple.

Про TensorFlow Google сказал, мол уходят с питона на свифт
Где, когда, а главное, кто? Те, кто его разработал? Там им свою разработку и внутри Гугла надо как-то продавать — ещё бы они не излучали оптимизм.

Если появится очередная стелла, свифт от этого никак не пострадает.
Пострадает, конечно. Причём уже похоже, что не «если», а «когда». Итересно только — релиз успеют сделать или прямо из беты в небытиё?

Но это не отменяет факта, что свифт уже не только язык для “хомячков” с платформ Apple.
Та же самая история, что и с Objective C, на самом деле: когда Objective C только появился — народ разработал GNUstep и были даже попытки куда-то это всё приспособить. Однако со временем всё заглохло и, насколько я знаю, Cocoa уже никто никуда портировать особо не пытался — так, кой-какие обрезки для игрушек.

То же самое и здесь: каждая неудача применить Swift куда-нибудь, кроме iOS и macOS будет подчёркивать «неразрывную связь»: Swift == Apple, Apple == Swift.

Слабо себе понимаю причину захоронения S4TF. Ребята из Google просто искали наиболее подходящий язык и выбрали Swift. Cделали форк языка и на его основе допиливают под нужды. В Colab уже добавили. FastAI, курсы начали переводить. Единственная проблема, крайне сыроват еще, но светлое будущее :).

По-моему вы сами всё прекрасно описали:
Ребята из Google просто искали наиболее подходящий язык и выбрали Swift.
Именно так: не «Google искал», а «ребята из Google искали».

В Colab уже добавили. FastAI, курсы начали переводить. Единственная проблема, крайне сыроват еще, но светлое будущее :).
Где-то я это уже слышал… Chrome Apps, NaCl… Да собственно половина проектов из Google Graveyard когда-то были «сыроватыми, но со светлым будущим».

Слабо себе понимаю причину захоронения S4TF.
То же самое, что и всегда: не оправдал надежд, не набрал критической массы… Посмотрим. Самый важный вопрос не в том, смогут ли они в Colab что-то добавить, а смогут ли они хотя бы один «большой» проект этим увлечь… и то может не помочь: NaCl использовался в App Engine, но ему это не очень помогло…

Вот это самое "кроме" такой немаленький минус. И подозреваю в обозримом будущем оно не войдет в Tier1 поддерживаемых ОС. Rust вполне неплохая альтернатива в данной ситуации.

Есть язык D. Благодаря удобно сделанным шаблонам, утиной типизации, возможности ограничивать типы в шаблонных параметрах (часто используются обобщения для структур данных, например, чтобы условный тип массива и условный тип списка могли приниматься функцией поиска). Ну и плюс обычные Си-подобные типы данных и С++-подобное ООП (но без лютого трэшака). Нормальные массивы, хранящие и указатель на себя, и свой размер. Там много хорошего, выводящего на другой уровень программирование на Си-подобных языках. Как раз тот язык, благодаря которому никак мне не удаётся полюбить динамическую типизацию, хоть я и много времени программирую на Python'е, JavaScript'е и bash'е по долгу службы.
Динамическая типизация переносит ряд возможных ошибок на время исполнения программы вместо времени компиляции.
На самом деле очень прокачивает скиллы кардинальная смена стека. Я всю жизнь (лет 15 я думаю) писал на PHP, пару лет назад понадобилось прочно влезть в яву (более строго-типизированного языка я в жизни не видел), дак я вам скажу что именно после того, как я вернулся обратно на PHP я полностью оценил все преимущества статической типизации, ибо мне не нужно боятся что по какой-то причине я загоню аргументом строку, хотя должен был массив (например, изменил возвращаемое значение какой-то другой функции), представляете что произойдет при этом, особенно когда эта функция должна будет пройти этот массив и сделать несколько запросов в БД или сконвертить его в JSON и отправить его на сервер? Теперь начиная с 7 версии PHP тоже имеет строгую типизацию и заругается если аргумент имеет другой тип данных или функция возвращает другое значение, а не то, которое от нее ожидается.

Как по мне оптимальна гибридная типизация, ибо иногда просто хочется расслабиться и что-то наклепать на коленке, не задумываясь о типах, но в серьезных проектах на том же PHP строгая типизация просто необходима по причинам, которые я описал выше. Причем я понял что словами это не объяснить, с этим нужно сталкиваться чтобы оценить все преимущества.

P. S. Это еще ладно, я еще и после этого с MySQL на PostgreSQL перешел (который тоже строготипизирован), теперь он меня обругивает каждый раз если по какой-то причине в строку суется число (а это может быть следствием какой-то очень серьезной проблемы, ибо почему возвращается число там, где должна возвратиться строка, например, array_search не нашел какое-то значение в массиве, хотя должно, что означает что этот массив сформирован неверно). Очень сильно выручало уже, хотя я не так давно пользуюсь всеми ее преимуществами.
писал на PHP, пару лет назад понадобилось прочно влезть в яву (более строго-типизированного языка я в жизни не видел)
Это не та ли система типов, которая считает null объектом любого типа?
В РНР эту «особенность» умудрились не повторить, кстати.

Наверное, просто потому что null в PHP появился чуть ли не раньше чем сама Java появилась (шутка, она старше на пару месяцев) и изначально был отдельным скалярным типом, когда объектов ещё даже в проекте не было

это круто, конечно, что умудрились не повторить ошибку системы типов, которую проектировали четверть века назад. Дженерики тоже сразу сделали, а не как в джаве?
Ну да, всю систему типов на помойку, и сам язык туда же, у него же тип null есть!
Типа null у него как раз нет. В этом и проблема.

Ну так-то вот эта концепция с null самим её изобретателем признана "ошибкой на миллиард долларов".

заругается если аргумент имеет другой тип данных

Нуда, только его ругание попробуй еще перехвати, приходится статический анализатор гонять

ЗЫ на самом деле Php начинает нервировать, ятоже много лет на нем пишу, и у меня все более отчетливое желание писать на jsp или на чистой Java

TypeError обычное исключение. Обычно его и особо перехватывать не нужно, так же как любое необработанное.

Как правила это — ошибка в коде и ловить такие вещи в рантайме — странная идея.

Лучше поздно чем никогда.

На рантайме вообще ничего тестить нельзя, учитывая его специфику, все делается на локальном сервере, и просто через Гитхаб обновляются бранчи. Но PHP тем и хорош, что иногда хочется расслабиться и накидать что-то для себя на коленке, не заботясь о типах, как раз таки именно Java в этом плане начинает напрягать, когда ты только и занимаешься тем, что приводишь все к типам. Но в крупных и серьезных проектах это необходимость, да, и очень полезная необходимость.

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


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

Пример того, когда автор может честно говорить, что думает. Да, грубовато. Но большинство статей про js намного токсичнее, хотя автор будет обращаться на «вы».
Эта статья скорее развлекательная. Честность и эпатаж в стиле камеди клаб — немножко разные вещи. Честным было бы показать особенности подхода на примере своих работ с примерами кода и анализом выбранных решений.
Наконец то кто то осмелился это сказать! Я уж думал со мной что то не так
Не зря во многие ЯП добавляют статическую типизацию(PHP, Python, Javascript)

В PHP добавляют строгую. А про джс можно подробнее?

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

Типизация — не контроль типов?

UFO landed and left these words here

Не согласен. Типы — информация о том, как интерпретировать то или иное значение. А где она хранится и как и когда проверяется — детали реализации.

UFO landed and left these words here

Лучше поздно, чем никогда, нет?

UFO landed and left these words here

Как по мне, то если контроль типов есть, то это типизация.

UFO landed and left these words here

Ваша программа станет типизированной.

Если эта проверка встроена в язык и её нельзя обойти — то конечно язык типизированный. По крайней мере, такое понимание типов согласуется и с википедией, и с официальными документациями языков программирования, и с литературой по программированию. То, что это не идеально совпадает с теорией типов в математике — ну так в разных областях одно и то же слово может использоваться в разных значениях.
UFO landed and left these words here
Не знаю, из какой именно книги ваша цитата выше — но даже в ней написано, что такое использование термина является стандартным. То есть, именно так понимается «динамическая типизация» применительно к языкам программирования. Так зачем спорить о терминах?
UFO landed and left these words here

Большинство источников используют "динамическая типизация" без подобных огооврок.

Понятие вроде «динамически типизированный» есть по логике вещей неверное наименование и должно быть вероятно заменено на «динамически проверяемый» (или «проверяемый во время выполнения» — прим. пер.), но использование этого понятия уже устоялось.
Очень странный подход к определению типов данных. Вот есть языки, которые позиционируются, как языки со стогой статической типизацией. При этом практика диктует наличие в таких языках механизмов позднего связывания (по факту элементов строгой динамической типизации). Получается все данные и структуры, для которых использованно позднее связывание не имеют типов вообще? Это как-то выбивает основу из-под строгой типизации, не находите?
Читать про алгебраический тип данных. Много думать.

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

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

Но нет, позднее связывание не делает язык нетипизированным. Даже если в каким-то месте про тип и нельзя ничего сказать (как в Java, когда вы получаете Object), но в других-то можно!
UFO landed and left these words here
UFO landed and left these words here
К сожалению dlsym даёт просто указатель на функцию, которую можно вызывать. А уж как её вызывать — не его дело.
UFO landed and left these words here
Были архитектуры, где именно так и сделано — железо само следит за типами аргументов. Можно ли считать такой ассемблер типизированным?
UFO landed and left these words here
Вы определили «типы» как нечто, проверяемое при компиляции. Но это ведь не единственное определение.
UFO landed and left these words here
Применительно к программированию я, например, встречал определение типа как набора значений и операций над ними. Когда именно проверять, что объекты удовлетворяют такому типу, там не уточнялось.

назвать типизацией наличие проверок на корректный доступ к элементу массива


Тем не менее в Паскале длина массива именно что входила в определение типа.

(ещё до программирования)


Если вы имеете в виду математические типы в стиле введенных Расселом, то он ведь тоже не уточнял, в какое время их надо проверять.

Поэтому ваше утверждение

которое на программирование отображается как статические проверки


достаточно спорно.

Если уж на то пошло, то и статическая, и динамическая проверка типов вообще не относятся к типам, как таковым — типы просто существуют, а является скорее помощью человеку, который не может не делать ошибок и не путать данные разные типов в процессе программирования или выведения логических формул.
UFO landed and left these words here
> Дико неконструктивное определение.

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

Типы в ЯП до формализации примерно так и строились.
UFO landed and left these words here
На практике просто выбирают удобные и легко реализуемые. Для целых чисел, например, знакомые арифметические действия с поправкой на двоичность и ограниченность.
UFO landed and left these words here
Вы путаете инженерию с математикой. Инженерия — это как раз о том, что удобно и реализуемо, а не то, что аксиоматично и строго формализуемо. Математика всего лишь шьет пиджаки для осьминогов.
Должна ли операция «удалить первые N символов» быть в определении строки?


Может быть, но не обязательно. Она не слишком аксиоматическая, что ли.

Если у вас питон с типа строгой динамической типизацией, то, получается, «abcde» и "" — разные типы?


Непонятно, почему вы пришли к такому выводу. Операция эта будет определена как функция отображения строки в строку, т.е. тип объекта не изменится.
UFO landed and left these words here
Значит, это частично определенная функция. Ничего особенного.
UFO landed and left these words here
Иногда так и делают. Например, добавляют к множеству «действительных чисел» NaN и доопределяют деление.
UFO landed and left these words here
Может быть, но не обязательно. Она не слишком аксиоматическая, что ли.

То есть вместо строгого определения имеем: "Вроде как нет, но если надо, почему бы и не да".

Отнюдь. Просто задачу выделения элементарных операций над типом (и определить тем самым тип) можно решить разными способами. Как только мы зафиксировали один из них, дальше все строго.
UFO landed and left these words here
Боюсь, что это не столько теория, сколько практика. И не моя, а универсальная.
UFO landed and left these words here

И это положительно сказывается на популярности?

UFO landed and left these words here
Несомненно. Порядок и логика всегда лучше хаоса и конструкций из палок. Но практика еще и показывает, что математизации поддаются только самые простые части мира, и программирования в частности.

У меня лично ощущение, что "полная" математизация основ языка (теория типов, теория категорий) негативно сказываются на его популярности.

UFO landed and left these words here
некоторые выражения не имеют смысла, не «вычисляя»


Вы все равно вычисляете — ведь это знание не дано свыше, а требует тех же символьных манипуляций. Просто в данном случае есть более короткий способ вычисления — как некоторые интегралы можно посчитать в символьной форме, а не численно. Но в общем случае вычисления все равно придется проводить полностью.
UFO landed and left these words here
В частных случаях. Это просто shortcut — как и вся математика, собственно.
UFO landed and left these words here
выделить массив ровно такой длины


Насколько я помню исходный виртовский Паскаль — нет. Массивы там были вообще не динамические, а в их тип входили тип элементов, тип индексов и диапазон индексов.

А для передачи массива в процедуру приходилось определять формальный аргумент, прибегая к чему-то вроде any: ARRAY OF INTEGER, например, вместо полного типа ARRAY[1..10] OF INTEGER.
Конечно ассемблер типизированная вещь. Типов, правда, не так много: «нечто размера 32 биты», «нечто размера 128 бит»… ну и всё.

Хотя бывают разные ассемблеры. Почитайте документацию на TASM. У них там объекты были.
Не нечто, а вполне определённые форматы, для которых нужны свои инструкции.
Целочисленный add, применённый к float значению, выдаст хурму на выходе.
елочисленный add, применённый к float значению, выдаст хурму на выходе.
Недоумённо смотрит на свой код из релизнутого продукта. А вы точно в этом уверены?

А вот эту статью вы когда-нибудь видели?
На ассемблере add вполне себе выполнится, вот только результат будет весьма прикольный.
Почему прикольный? Всё будет зависеть о того, что вы складываете с чем и зачем.

В моём случае речь шла об округлении мантиссы — это делается как раз использованием целочисленных операций с float.
В этом случае да, но не следует забывать того, что какраз у самого процессора(x86, сопроцессор и прочее не учитываем!) понятия типов вообще нет, и ему глубоко пофигу что с чем складывать. Поэтому 1.1f + 43 вполне себе может вылиться в любой треш.
Тут код специально рассчитан на такое поведение и работает со специально подобранными константами.
Разумеется, какие-то целочисленные операции можно применять к float зная формат и ожидаемый результат.

Я же говорил, что сложив 1+1 вы получите не 2, а 1.7014118346e+38

Точно так же, перепутав знаковое и беззнаковое деление результат может быть неверным.
Я же говорил что сложив 1+1 вы получите не 2
А почему вы, собственно, должны получить 2? Вы и без всяких floatов можете получить чушь, если в одной переменной у вас 1 и в другой 1, только в одной — это метр, а в другой дюйм.

Проверено экспериментально.
Хоспаде. Я написал банальную мысль о том, что при программировании на ассемблере нужно следить за типами инструкций и операндов. Типы отличаются не только размером, но и форматом данных.
Процессор не сделает преобразование типов за вас. К чему вот было это ваше «а можно плавать и со штангой»?

>> А почему вы, собственно, должны получить 2?
Потому что я хочу получить 2, наверное?
Потому что я хочу получить 2, наверное?

Интересный аргумент. А если я хочу получить 3, то должно получаться 3?
Нет, конечно. Лицензия на «хотение», очевидно принадлежит beeruser — и потому только он имеет право чего-то хотеть. Вы опоздали.
А если я хочу получить 3, то должно получаться 3?
1+1=3? Cтранное желание, но как хотите.
UFO landed and left these words here
Проверка выхода за границу массива это не проверка типа? Или защита от выполнения данных?
Ещё, слышал, бывали процессоры, у которых переменные содержали поле с типом.
UFO landed and left these words here
У типа есть очень формально определённое значение

Много определений типа в программировании. Некоторые ещё тянут в программировании определения типов из математики.

UFO landed and left these words here

На любителя. По ощущениям на любителя ФП

"У типа есть очень формально определённое значение".


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

UFO landed and left these words here
Понятие типа в контексте STLC


1. Система типов из «лямбда-исчисления с типами» не единственная система типов, а только одна из.
2. Системы типов в современных мейнстримных языках (как со статической типизацией, так и с динамической) — это очень далеко не STLC и я подозреваю, что их авторы строили их на несколько других основаниях (и не только формальных).
3. Да, можно натянуть сову на глобус (что и делает тапл) и вывести одно из другого, но это вообще не означает, что определение типа из STCL единственно верное или валидное для языков программирования.
4. То что система типов красиво формализуема еще не означает, что она хорошо подходит для промышленной разработки людьми, которым важно получить результат здесь и сейчас, а не формально верифицировать корректность программы.
UFO landed and left these words here
А в каких других теориях типов это не статическая классификация?


Ну есть, например, такая «Gradual Type Theory». Правда я с ней недостаточно знаком, чтобы внятно ее обсуждать.

По остальным пунктам — а о чём мы спорим-то?


Я спорю с утверждением, что «типы — это не рантайм-метки рядом с другими ячейками в памяти, а что-то, что проверяется компилятором статически», и утверждаю, что если «статическая типизация = типы проверяются компилятором статически», то так же правомерно говорить «типы проверяются рантаймом динамически = динамическая типизация».
UFO landed and left these words here

А если система типов есть, но она плохая по этому критерию?

UFO landed and left these words here
automath какой-нибудь возник сильно до любого из ныне существующих языков программирования.


Я думал, что тут разговор о языках программирования, а не доказателях теорем.
Разве пыха компилируется в принципе? Я сто лет не пышник и не в курсе новостей этого вашего пшп 7, хотя про типы и слышал. Просто обывательский подход — если ты не сидишь и не ждешь конца компиляции — оно не компилируется, а выполняется.

Оно компилируется в опкод, который выполняется VM.

В 8 обещают JIT компиляцию в нативный код, а пока только в опкоды

А как называются рантайм метки более коротко? И какое название у описания того, что можно делать с некоторой штукой вне зависимости от того, рантайм это или дизайн тайм?


Мне кажется, такой подход к терминологии менее ортогонален.

UFO landed and left these words here
Ну так и называются, метки.

А кем они так называются? Есть ли какая-то реализация которая называет их не типом?


Например, в вашей любимой IDE при отладке тип переменной и тип значения переменной называются по разному? Один тип, другой метка?


Ээ, не знаю, это какой-то слишком общий термин для меня.

Ну вы в обычной речи слово тип не употребляете?


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

UFO landed and left these words here
С моей точки зрения в книжке терминология интересна но неудобна, все говорят «тип» для общего, никто не использует выражения «рантайм метка»

А зря. На мой взгляд, создаёт неправильные ожидания.

Зря или не зря — это уже больше философский вопрос. Факт в том, что «динамическая типизация» по отношению к языкам программирования используется именно в таком смысле, и причины, по которым так сложилось, здесь не важны.
UFO landed and left these words here
В языке «ться» и «тся» не различаются, они различаются лишь на письме, которое представляет собой условность. Потому, собственно, их и путают на письме.

лишний раз указать на принципиальное различие между типизацией и рантайм-проверками


То, что вы называете типизацией, — всего лишь проверки до рантайма.
UFO landed and left these words here

Это лишь ваше убеждение :)

UFO landed and left these words here

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

UFO landed and left these words here
UFO landed and left these words here
UFO landed and left these words here

Извините, но вы соответствие Карри-Говарда проигнорировали. Избирательное зрение?

UFO landed and left these words here

Надеюсь теперь всем ясно, что это — тролль?

UFO landed and left these words here
UFO landed and left these words here
Что вы собрались выяснять и в каком споре? Если человек не умеет в логику? В принципе?
UFO landed and left these words here
А… ну это, успехов. Я умею сделать так, чтобы их уволили (что, обычно не так и сложно), а большего мне и не нужно обычно.
UFO landed and left these words here
В политику и я не умею. Но с людьми, не умеющиеми в логику, обычно бесполезно спорить. Нужно просто пользоваться тем, что они не умеют просчитывать результаты своих шагов и «делать их крайними».

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

Даже если вам за выполнение чего-то сказанного мимоходом и нигде не зафиксированного обещают кучу плюшек и всяких благ. Лучше прослыть «ничего не понимающим в бизнесе», чем оказаться крайним, когда очередной такой персонаж будет на вас пытаться повесить свои косяки.
UFO landed and left these words here
UFO landed and left these words here
UFO landed and left these words here
UFO landed and left these words here
А если мне сказали закодить биржевого бота, который будет торговать на какой-нибудь азиатской бирже только в рабочие дни, то, например, если я неправильно скопирую список праздников (или нагуглю список не для той страны), то типы едва ли это помогут отловить, конечно. Но как это отлавливать — вообще непонятно.

Хуже. Список рабочих дней может как в России определяться в предыдущем году по решению Правительства. Или как с "нерабочими" днями. По ходу дела.
Вообще удивительно, что только 0xd34df00d реально вернулся к истокам. Все это программирование — это не код ради кода, а код обработки данных. А все данные типизируются. А код — это просто функции превращения одного в другое.

у него большая проблема: многое из того что он говорит базируется не на научном подходе, а на религиозных предпочтениях/взглядах
Ну хоть с тем, что ЯП со статической типизацией убирают множество проблем с ошибками типов вы согласны?
UFO landed and left these words here
однако надо помнить (и это исследовал ещё Ларри Уолл), что большинство проблем с ошибками типов связаны с тем, что в языках некорректно сдизайнены операторы сравнения и математические операции.
А ещё нужно помнить, что когда эта «глыба», эта «гора», этот «гений» решил создаить что-то на основе своих идей… то получился высер такого микроскопического размера, что о нём даже как о мыши-то говорить смешно.

и чем крута динамическая типизация: что программист больше думает об алгоритме, нежели занимается обрядами вокруг его реализации
Серьёзно? И потому как только вам требуются реально серьёзные алгоритмы (распределённые базы данных или хотя бы SQL-базы, компиляторы, операционные системы и всё такое прочее) — так прям все на динимических языках начинают программировать? Вы это сейчас серьёзно?

Знаете — весь этот ваш пафос был бы слегка более уместен если бы подверждался опытом. И вы могли назвать хотя бы одну систему, где динамически типизированный язык — это не «пенка» на базисе из модулей на статически типизированных языках, а что-то, что сущесвует само по себе. Хотя бы.

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

и это путь решения тех же проблем но на дороге динамической типизации
Это махание руками. Давайте ближе к практике:
1. Реализация динамически типизиванного языка на динамически типизованном языке же: ___
2. Операционная система на этом самом динамически типизованном языке: ___
3. База данных на таком же языке: ___
4. Процент рынка, который вот всё это заняло в ___ году: ___

Вот как заполните пропуски — так сможете лить в уши сказки про преимущество динамической типизации в деле реализации алгоритмов. А до тех пор — это всё рассказы условного «таджика» умеющего неплохо строть туалеты и двухтажные домишки дендрофекальным метордом о том, что у оного метода есть масса преимуществ перед сталью и бетоном, а что какие-то идиоты из говна и палок даже не пытаются строить мосты и небоскрёбы — так это потому что у архитекторов и инжинеров-строителей умишко слабенький и нет того опыта строительства туалетов, что «таджика»…
UFO landed and left these words here
назовите три полезных программы на Расте/Хацкеле стоящие на большинстве компьютеров
Назовите хоть одну такую на Raku для начала. Или вам можно выбирать языки, а мне нельзя? Вы же сами тут поёте песни про крутизну Ларри — ну вот покажите… на практике.

динамически типизированные языки — это скриптовые языки, прежде всего.
Внезапно как, а. А почему так, не расскажите? Почему языки, в которых «программист больше думает об алгоритме, нежели занимается обрядами вокруг его реализации» не применяются там, где алгоритмы сложны и о них действительно приходится думать — но всё больше там, где алгоритмы тривиальны и думать о них не нужно?

затем попробуйте удалить Perl и Bash. и посмотрите на результат
И много вы алгоримов на Bash написали? Я как-то писал топологическую сортировку банальную — то ещё равлечение было. В Android, кстатати, нет ни Perl, ни Bash. И ничего — работает как-то.

А вот попробуйте оттуда удалить модули, написанные на C…
UFO landed and left these words here
Вы хотите сказать что языки со строгой/статической типизацией все находятся в стадии «бета» (== «ещё не доделан»)?
Я хочу сказать, что с идиотами, записывающими в языки с динамической типизацией C и Java разговаривать бессмысленно. Хотя вас я идиотом не считал, но… теперь вижу._
UFO landed and left these words here
UFO landed and left these words here
Эти все доводы работают в каком-то выдуманном виде. Где «венец творения» это не "рюмка коньяка с ломтиком лимона документооборот", а какие-то дурацкие вещи типа смартфонов и космических кораблей.

Статически типизированный язык, между прочим

Типизация слабая, да. Но даже при всём при этом в OpenSSL уязвимостей куда меньше, чем в каком-нибудь Drupal. А уж если выкинуть всякие «module that can only be compiled by the HP-UX assembler, so that only HP-UX PA-RISC targets are affected»…

Да, предствьте себе — даже такая слабая типизация, как в C, и даже при такой ужасной культуре кода, как в openSSL (поговорите с теми, кто внутрь смотрел) всё равно снижает количество уязвимостей. В каком-нибудь NGINX — их меньше на порядок. В Chrome — да, побольше будет… но вы когда-нибудь сраванивали по объёму Drupal и Chrome? Сравните как-нибудь на досуге.
поэтому языки вроде C, C++, Java (и прочие языки традиционно ориентированные) — это языки, которые я противопоставляю высказываниям сектантов.
У… как всё запущено. Что такое вообще «традиционно ориентированный язык»?

именно строгую типизацию сектанты вроде 0xd34df00d противопоставляют тестам.
Серьёзно? У вас всё с логикой настолько плохо?

Извините, но я нигде и никогда не слышал, чтобы 0xd34df00d говорил о том, что типами нужно заменять тесты. Он всегда говорит о том, что можно — и да в Idris это попроще, а в C++… ну на спор, наверное, тоже можно, но в реальной программе — не получится.

Вопрос того, что нужно выражать ограничениями на типах, а что лучше оставить в виде тестов — он совершенно отдельный от вопросов принципиальной реализуемости того или иного подхода.
UFO landed and left these words here
А какое вообще вопрос «кто кого любит и как» оказался связан с языками програмирования?

И, кстати, как вы вообще выясняете ориентацию программистов на Haskell или C++?
UFO landed and left these words here
UFO landed and left these words here
UFO landed and left these words here
UFO landed and left these words here
UFO landed and left these words here
Давайте теперь Вы назовите пару монополистов, имеющих аудиторию в миллиард людей, чтобы их основной язык был со строгой/статической типизацией
Вы издеваетесь или как? Ну пусть будет Google и Microsoft, если уж так хотите. Только не рассказывайте сказок про то, что Microsoft меньшая монополия, чем какой-нибудь Facebook: в китае без Facebook отлично живут, а без Window — таки не обходятся. Ну или Apple возьмите — да, это не монополия… но денег она зарабатывают больше, чем Facebook и Mail.Ru вместе взятые.

то FaceBook — это PHP.
Нет. PHP такую махину не потянет. Facebook — это Hack. И да — он статически типизирован.
UFO landed and left these words here
В Касперском что-то пилили на хаскеле. По крайней мере, когда тамошние рекрутёры общались со мной N лет назад.

поговаривают, что там лоно адептов крестов и Раста

Да-да. Нанимают сишников-системщиков и заставляют их монадки моноидировать.

> Booking.com — это Perl (сейчас мигрируют на Python, просто Python'щики готовы работать за еду, поэтому)

На Java. Какой смысл уходить на Python для такой нагруженной задачи?
(распределённые базы данных или хотя бы SQL-базы, компиляторы, операционные системы и всё такое прочее) — так прям все на динимических языках начинают программировать?


Однако же поверх всех этих замечательных программ тут же возникают динамические языки — шеллы или тот же SQL. SQL сильно типизирован?

Совпадение? Не думаю.

Так никто вроде бы и не спорит, что в качестве glue code для одноразовых задач динамические языки вполне себе работают.

Некоторые SQL запросы переживают несколько смен языка арр-сервера

Совпадение? Не думаю.
Нет, конечно. Как только вы решаете, что вам не нужен качественный код, но нужны дешёвые программисты — так динамические языки становятся, вдруг, резко осмысленными.

Программисты на PHP получают меньше, чем программисты на C++, а администраторы («программисты на bash») — ещё меньше.

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

Где-то тут уже приводил: в Киеве разница между PHP и Javaсеньорами порядка 5% всего. Это во столько бизнес оценивает надежность статической типизации (забудем про то, что часто Java и быстрее)?

Опять бред несете. Вы живое доказательство того что динамика а особенно PHP разжижает мозг.

Поищите — это публичная статистика, я ссылки приводил в топике

Ох уже эти предрассудки. Во многих организациях платят одинаково что фронтам что беками независимо от языка программирования. Дело вообще не в том кому больше платят. Сколько платят больше от организации конкретной зависит. Дело вообще в другом.
Вооб вон PsyHaSTe говорил что он фронтов нанимал дороже чем беков. Я бы все равно из-за этого не перешел бы во фронты.

к чему тогда пассажи про "нужны дешёвые программисты — так динамические языки становятся, вдруг, резко осмысленными. Программисты на PHP получают меньше, чем программисты на C++"


У меня есть цифры, что эти "дешевые" лишь на 5% дешевле, а разница в качестве, вроде как, качественная, если верить адептам статики.

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

Разница между дешёвыми и дорогими программистами лишь слегка кореллирует с зарплатой.

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

Подумайте над этим.

а разница в качестве, вроде как, качественная, если верить адептам статики.
Разница качественная — но не между динамикой и статикой.

А между продукцией «дешёвых» и «дорогих» программистов.

Я это уже показывал на примере CVE.

И да, разница между зарплатами — гораздо меньше, тут вы, что забавно, тоже правы.
UFO landed and left these words here
Не в возражение основному, но:

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

В языке у них разная роль, что можно увидеть, например, по тому, что для некоторых глаголов вместо "-ться" получается "-тись": нестись, пастись…
(это как раз о типизации;))

В фонетике, да, они сливаются — но уже после этого.
Они не различаются на слух, следовательно, со временем это будет один и тот же грамматический элемент, исторически произошедший из двух разных.
1. Это не грамматический элемент.
2. С чего это бы им становиться одним элементом? У большинства глаголов таки тут нет совпадения, случаи типа «храниться»:«хранится» — малая часть.
И если мы обсуждаем преимущества разных видов типизации, то, ИМХО, лишний раз указать на принципиальное различие между типизацией и рантайм-проверками, которое по-хорошему должно быть определено даже в терминологии, вполне себе стоит.

Так никто не против указывать на различия статической и динамической типизации. Более того, никто вроде не отрицает, что с некоторой точки зрения правильнее эти две альтернативы называть по-другому. Но для того, чтобы как можно больше людей, связанных с программированием, вас сразу без дополнительных пояснений правильно понимало, нужно использовать именно «статическая типизация» и «динамической типизация» — это устоявиеся названия классов языков. Можно для себя их называть как угодно, но все (?) официальные документы по динамически типизированным языкам программирования используют слова «тип» и «динамическая типизация»/«динамическая проверка типов» — например python, js. То же верно и для обсуждений этих языков на практике. Поэтому смена терминологии привнесёт только путаницу на этом этапе.
UFO landed and left these words here
В моей IDE для хаскеля вообще нет рантайм-меток (да, я за всю практику пользовался Typeable в своём коде ровно один раз). Да и дебаггером я там не пользуюсь.

Если вы им не пользуетесь это не значит что его нет. Я посмотрел — оно умеет как-то определять тип в рантайме.


Кстати, определите до конца термин "рантайм метка" он не отражает метка чего именно.


В моей IDE для плюсов их тоже не особо много для рантайм-поведения.

А что у вас за IDE для плюсов? У вас там нет cимволов и RTTI? в окне watch нет колонки type для переменных? Или там написано что-то типа "рантайм метка относящаяся к набору операций которое можно совершать со значением"?


А зря. На мой взгляд, создаёт неправильные ожидания.

Какие и у кого?


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

Я хаскель знаю очень поверхностно. Мне трудно с этим поспорить.


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

UFO landed and left these words here
type-hints
прекрасный термин, и никого не обманывает
В архитектуре «Эльбрус» такие аппаратные метки назывались тегами.
Думаю в PHP, как и в питоне можно проверять линтерами не в рантайме.

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

Можно писать на Idris и эммитить код на PHP

Разве только чтоб обмануть работодателя (которого примерно бесконечно проще найти для PHP, чем для Idris).
Тот, кому первому пришла в голову идея назвать рантаймовый контроль типов «типизацией» — будет вечно гореть в аду за обман джуниоров.


А как по вашему это нужно называть?
Контролем типов, как и указано в мануале.

Типизация в PHP как была динамической и слабой, так и осталась. И нет никаких предпосылок к изменению этого положения.
Контролем типов
Вроде это по определению делается во всех системах с проверками типов. Ну там Rust, Haskell. На другом этапе, конечно.
Я не понимаю отчаянного сопротивления применению определенного уважаемого термина к РНР и попыток его замены на какой-нибудь другой, не такой уважаемый.
Типизация в PHP как была динамической и слабой, так и осталась
Кстати, вы будете гореть в аду
Тот, кому первому пришла в голову идея назвать рантаймовый контроль типов «типизацией» — будет вечно гореть в аду за обман джуниоров.
UFO landed and left these words here
Если это не type (тип). Каким словом обобщить свойство поведения «строка», «число», «интерфейс» в ЯП? Чтобы можно было корректно спросить «Какой blabla у этой переменной?» и другой разработчик понял вопрос.
Если это не typing (типизация), то как сообщить другому человеку «Я придумал ЯП с динамическим blabla» и остаться понятым?
UFO landed and left these words here
«Можно ли на этой переменной дёрнуть эту функцию?»
Но если мы хотим донести, что эта переменная ведёт себя как string ибо помечена таковой средой выполнения, то нам придётся долго перечислять список функций (и всё равно можем не попасть, потому что у другого типа может быть такой же, но он к примеру несовместим со string). Нам же нужны обобщения.
вы придумали язык без статической типизации.
Это можно, да. Термин взаимоисключающий.

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

Я не знаю, как это было с исторической перспективы, но сейчас частичное пересечение узкоспециального термина с широким общим играет отрицательную роль для первого.
UFO landed and left these words here
Понятие типа — хоть в номинативном, хоть в структурном смысле — вполне может пригодиться в динамическом языке. Например, для перегрузки функций: перемножить две плотные матрицы — один метод, плотную и разреженную — другой, разреженную и диагональную — третий; сложить элементы с i-го по j-й — один метод для типа, который имеет доступ по индексу, другой для типа который позволяет только итерироваться. И т.п.
Но да, это не про питон.
Можно просто сказать, что вы придумали язык без статической типизации.

Это может быть и безтиповый язык типа популярных ассемблеров.

А еще смешнее, что нет контроля за этим контролем.
А джунам тем стоит взять JSP если уж на то пошло)
В PHP 7.4 для полей классов завезли именно статическую.

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

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

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

Пока нет 8 и нет JIT, ни о какой компиляции мы не можем говорить =)

Java на JIT, насчёт C# не могу сказать ничего. А 8 с JIT ещё только в альфе, первый релиз-кандидат вроде как только осенью будет, а сам релиз в декабре.
В пыхе компиляция пока что относится только к сборке самого бинарника руками) А наш с вами код интерпретируется, это сильно другой процесс.

В альфе, но есть :)


Тут о терминах можно спорить долго. javac запускает компиляцию в байт-код, который отдаётся виртуальной машине. Раньше она его просто интерпретировала, сейчас JIT везде или почти везде. php запускает компиляцию в байт-код, который отдаётся вирткальной машине. раньше она его просто интерпретировала, сейчас JIT в мастере. В чём качественная разница? В отсутствии файла с байт-кодом?

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

Ну вот JIT тогда не компиляция? Файлика нет же. :)


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

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

У вас слишком узкое представление.

Форт я ещё в самом начале 90-х затруднялся к чему отнести, настолько у него режимы интерпретации и компиляции перпелетены.


P.S. Точнее — сшиты :)

Не во время компоновки/загрузки?

PS На всякий случай подчеркну, это вопрос, а не утверждение.
Если кратко:
Проверка типов происходит точно на рантайме, когда данные переданы в поток (то есть код уже в куче)

Если развернуто:
1. В зависимости от версии пыха и правил типизации (strict_types) проекта на этапе разработки (локально) доступны:
1.1. Анализ самого IDE в режиме реального времени
Картинка
image

1.2 Встраиваемые пакеты для статического анализа codestyle
Картинка
image

1.3 Встраиваемые пакеты для стат анализа codequality
Картинка
image


2. Дальше в крупных проектах CI/CD, со стендами для предварительных тестов регрессии, интеграции, фича тестов и вероятнее всего 1.2 и 1.3 повторные.
Картинка
image


3. Дальше, в зависимости от критичности проекта, может быть ряд canary продакшн серверов, на которых крутятся «свои» юзеры, которые выступают в роли кроликов-тестировщиков.

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

А так, по топику могу сказать одно.
Типизация нисколько не спасает от багов на проде.
Чаще всего прод на пыхе страдает от кривой логики реализации бизнес-процесса или не до конца протестированных юзкейсов.
Орут о величии строгой типизации над динамически типизированными языками в основном фронтендеры, которые пересели с js на ts и решили, что они не верстальщики, а программисты =)

Про нгинкс погорячился, в голове джакарта и джетти)

Нет. Вы очень глубоко ошибаетесь. «Статическая» — это на этапе компиляции. В PHP же любой контроль типов, даже контроль типов свойств классов и объектов — рантаймовый.

Для полей классов таки да.


private string $a = 10;

отлупит на этапе компиляции

тут скорее идет разговор не о компиляции как о таковой, а о самом моменте.
Компиляция всех файлов происходит в одно время или в разное. В PHP в момент обращения к файлу.
В Python не добавляют статическую типизацию, вы заблуждаетесь.
Хинты с mypy всё больше используется, по-моему. Как бы становясь best practice и правилом хорошего вкуса. Субъективно, конечно, потому что Python сообщество — тот еще (un)pythonic пузырь.

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

«Сила» типизации Python преувеличена:
print((not None) + 7)
Сначала None автоматически преобразуется в bool, потом bool автоматически преобразуется в int.
Типичная слабая типизация.

Да, у Python отсутствует автоматическое преобразование число<->строка и возможности преобразования None ограничены. Но в остальном PHP может обеспечить более строгий контроль типов. Аннотации типов аргументов подпрограмм в Python не обеспечивают контроль типов — в отличие от PHP, в котором реализуется реальный контроль и типов аргументов (с возможностью отключения преобразования число<->строка), и типа возвращаемого значения.
Сначала None автоматически преобразуется в bool, потом bool автоматически преобразуется в int.
Типичная слабая типизация.

Оператор not возвращает True или False. Тип bool унаследован от int, поэтому в арифматическом смысле True всегда равен 1, а False всегда равен 0. У вас не получится сделать None + 1.

gaal@catalina monitoring % python3
Python 3.7.6 (default, Dec 30 2019, 19:38:26) 
[Clang 11.0.0 (clang-1100.0.33.16)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 
>>> print((not None) + 7)
8
>>> print(None + 7)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'
Главная фишка вот:
Python 3.7.5rc1 (default, Oct  8 2019, 16:47:45) 
[GCC 9.2.1 20190909] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> not []
True
>>> not "Oops"
False

Операция «not» применима к чему угодно. То есть там «None» не преобразуется в Bool. А что True/False — разновидности целых… это странно, но это Python унаследовал от C. Он ещё парочку странностей от него унаследовал…
То есть там «None» не преобразуется в Bool.

Спасибо за разъяснение, но я этого и не утверждал. Из моего сниппета четко видно, что None — это инстанс NoneType. А не Bool. А особенности работы not… ну, спасибо.

UFO landed and left these words here
В моих книжках написано, что not (not x) = x для всех допустимых x, значит, None эквивалентно not (not None).

Ещё раз. У вас не получится сложить None и 1. Оператор not это логический оператор отрицания, который возвращает строго True/False. Двойное инвертирование True вернёт True и наоборот, эта цепочка из not not not [...] может быть бесконечной. Не понимаю, что мы обсуждаем?

Да, это всего лишь ещё один способ указать на unsoundness языка.

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

Все языки делятся на два непересекающихся класса, к сожалению: неконсистентные и мёртые. В Haskell, скажем, Monad это не Applicative именно по той причине что лучше быть неконсистентным, чем мёртвым.
UFO landed and left these words here
Да, есть unsound-элементы, но они связаны с изначальными ошибками (или компромиссами) в дизайне системы типов, и о них думают, как бы их устранить.
Лучше бы они подумали как «людям снаружи» дать доступ ко всему этому.

Либо объявите GHC «единственной правильной версией» (и тогда версии языка будут соответствовать резлизам GHC), либо сделайте уж, как в C++, регулярные релизы. А то официальной версии 10 лет, а что из бесконечного количества расширений и дополнений, доступных после этого, считать «официальной частью языка» — «снаружи» понять невозможно.

Далеко не у всех есть возможность следить за всей «движухой», если они хотят попробовать Haskell на примере задачи генерации какого-нибудь отчёта.

А с устранением косяков вопрос сложный, на самом деле: в Python считается идеоматичным не писать в if всякие "== 0" или "== []" (хотя лично я это считают некрасивым как раз) из чего, как бы, очевидно следует, что и not должен работать со всеми типами — иначе будет нелогично.
UFO landed and left these words here
Де-факто это уже давно так.
А как до этого догадаться? Захожу я на www.haskell.org (а куда надо было зайти?), открываю раздел с документацией — первым делом, первой ссылкой, меня отправляют на Learn You a Haskell for Great Good!, где есть прям целаю душешипательная история про то что Монада — это не Applicative. Ладно, это тьюториал, они часто не поспевают за развитием языка. Ищем описание языка… единственное, что там есть — это Haskell 2010. Если погуглить — можно на wiki найти информацию про Haskell'… ссылка ведёт на сайт, который не отвечает, а страничка на archive.org радостно сообщает, что Haskell Prime 2020 committee has formed — «свежая» новость от 2016го года.

Ну и куда мне идти, чтобы что-то узнать, а главное, как до этого догадаться?

Сравните с C++. Wikipedia отправляет на isocpp.org. Там есть анносы GCC 10.1 (релиз от 11 мая 2020го), есть ссылка на Core Guidelines, можно добраться до драфта (хотя было бы полезнее, если бы ссылка была бы поближе к корню isocpp.org, а так туда приходится идти через cppreference).

А где у Haskell-community что-то подобное?

P.S. У C++-комьюнити есть, правда, своя, особая фишка: бесконечные draftы. Попытка найти хоть чего-нибудь отрелизнутое — обречена на неудачу. Нужно некоторое время «повариться», чтобы понять, что это — следствие бюрократии ISO, которое привело к тому, что все и всегда используют draftы. Релиз, типа-вроде-как окончательная версия, никого не интересует настолько, что если draft будет говорить одно, а релиз — другое, то реализуют именно draft: их используют разработчики компиляторов, программисты и вообще все, кто мало-мальски интересуется C++. А релизы? Ну их ISO за деньги продаёт, можно купить и положить на полочку. Всё. Больше в них никакого смысла нету. Да, этот «секрет Полишинеля» сходу, на web-сайте не найти…
UFO landed and left these words here
ruby, 1 + "hello" => TypeError (String can't be coerced into Integer)
А я говорю, что описание типов — и есть описание процесса
Э? Вообще-то описание _процессов_ — это функции/процедуры.
и у функции есть интерфейс, а именно аргументы и возвращаемое значение, чьи типы хорошо бы знать
Обе системы типов (статическая и динамическая) имеют преимущества.
Код на динамических языках не только пишется легче, но и легче читается. Поэтому многие ошибки видны невооруженным глазом.
Но с определенного размера кодовой базы все связи уследить уже просто не возможно, и вот тут на помощь приходит статическая типизация.
В общем, для каждой задачи — свой инструмент.

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

Вывод типов — это хорошо, но работает он не всегда. Так или иначе компилятор все равно хочет «подсказок». По крайней мере в тех языках, с которыми работал я.
UFO landed and left these words here
TypeScript предлагает не самый удобный синтаксис, где декларация типов и имплементация смешиваются в одном предложении. Подход за который топит автор — сначала пишем типы, потом все остальное — не работает чисто синтаксически.
function foo (string) : string { } // error 

В хаскеле сделано удобнее. Но это имхо и вкусовщина, не буду спорить если у кого-то другое мнение.
function f(a: number): string;


попробуйте так
Потому что имена аргументов, это так же часть сигнатуры и она важна для понимания, что функция делает.
В Вашем варианте foo я понятия не имею, что за строку она от меня хочет, но стоит написать вот так:
function foo(userName: string): string;
и все стало гораздо понятнее, хотя foo по прежнему не очень удачное имя…

И да, по-нормальному было бы вообще так:
function foo(userName: UserName): string;
но убогая структурная система типов тайпскрипта не дает это выразить нормально

Вобще-то даёт. Гуглите брендированные типы.

Знаю я про них, но они все равно не работают нормально, ибо структурная типизация…

Всё прекрасно работает.


import {
  $mol_data_nominal as Unit,
  $mol_data_integer as Int,
} from "mol_data_all";

const Weight = Unit({ Weight : Int })
const Length = Unit({ Length : Int })

let len = Length(10)
len = Length(20) // Validate

len = 20 // Compile time error
len = Weight(20) // Compile time error
len = Length(20.1) // Run time error

let mass: typeof Weight.Value
mass = len // Compile time error
Вы плохо знаете историю. Это всё ALGOL.

А Delpha/Pascal — это уже «закат эпохи». Когда теоретики заизолировались у себя в башне, а практики начали делать «удивительные открытия», известные теоретикам в середине прошлого века.
UFO landed and left these words here
Буквально вчера делал у себя на проекте похожую штуку. Работает :)

type UserName = string & { readonly tag: unique symbol };
type Password = string & { readonly tag: unique symbol };

const nameOf = (name: string) => name as UserName;

function stringOf(name: UserName): string {
  return name;
}

stringOf(nameOf("bingo347")) // OK
stringOf("bohdan-shulha") // Argument of type '"bohdan-shulha"' is not assignable to parameter of type 'UserName'.
stringOf("hellowrld" as Password) // Argument of type 'Password' is not assignable to parameter of type 'UserName'.

const nameOf = (name: string) => name as UserName;
Вот я и говорю, что это не работает, любую строку можно просто привести к типу UserName без доказательства последнего
А как доказать, что строка, которая пришла с сервера, это действительно UserName, а не что-то иное? Предполагается, что приведение типов будет использоваться в фабриках, а по приложению будут ползти уже Value Object. Этот способ, как минимум, гарантирует, что нельзя будет случайно передать рандомную строку вместо UserName.

Я могу ошибаться, но вы именно о таком поведении писали в комментарии выше.
А как доказать, что строка, которая пришла с сервера, это действительно UserName, а не что-то иное?
Проверить, что она соответствует всем ограничениям на тип UserName, если проверка успешна — я получу тип UserName, иначе получу ошибку. Другого способа получить тип UserName в программе нет, поэтому ему можно доверять. А вот типу, в который можно просто кастануть любую строку я доверять не могу, он для меня бесполезен.

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

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

Но я согласен с автором что «в продакшене» всё-таки лучше использовать языки со статической типизацией.
UFO landed and left these words here
К сожалению, не видел еще удобных средств в менйстримных ЯП, позволявших легко избежать складывания условных int и int (где первый — метры, второй — секунды). Надо оборачивать, а всем влом. И библиотеки всякие все равно будут принимать и отдавать int-ы.
UFO landed and left these words here

В плюсах же как раз есть пользовательские суффиксы.

UFO landed and left these words here
Что Вам там больно? «4s + 500ms» сработает и даст четыре с половиной секунды, а «4s + 500m» не скомпилится, поскольку секунды с метрами не складываются.
Описать всевозможные метр/сек кг/сек итд.
Так вот же и статья об этом: либо мы описываем все типы и получаем типобезопасность, либо мы складываем футы с метрами и наш марсоход пролетает мимо Марса (true story).

Ну и, кроме того, всё уже сделано до нас: Boost.Unit
Если нет boost то надо вручную всё это делать.

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

UFO landed and left these words here

Там ограничения есть, например, для целого это всегда long long int, а зачем мне это, если я метры хочу только int32.
Другое дело, что можно все в классы обернуть… тогда точно, одно с другим не сложишь. Но это конечно дополнительно писать придется кода...

В C++ как раз сложишь, если оператор + переопределишь :)

И как так просто метры с миллиметрами сложить? Переопределить то можно… придется делать столько этих операторов, сколько типов собираетесь складывать.

Хорошо, Фаренгейты с Цельсиями.

Вообще не проблема: Фаренгейты с Цельсиями складывать в принципе нельзя (даже в физике), но и то и другое можно перевести в Кельвины или Ранкины. И там уже складывать.
UFO landed and left these words here
UFO landed and left these words here
Именно что аналогично — то есть неизвестно что получится в результате. Кельвины и Ранкины скаладывать можно, а Цельсии, Фаренгейты и Реомюры — только если знать что они означают: собственно температуру или разницу температур. При этом температуру с температурой складывать нельзя.
температуру с температурой складывать нельзя
Вот у меня литр воды 20 градусов и 5 литров 50 градусов, как мне посчитать температуру смеси (пренебрегая теплопередачей посуде и воздуху)? Всегда думал что для этого нужно средневзвешенное значение находить (в кельвинах), а для этого множить на скаляры и складывать.
Научный коммунизм вами усвоен на отлично, цитаты вы дёргать научились. А если хотите увидеть ответ — то прочитайте все пять строчек. Это не так много.
Вам нужно описывать операцию среднего взвешенного. Чтобы библиотека (условно) через unsafe получала скаляры, делала математику и возвращала усредненную температуру. Складывать температуру нельзя, можно усреднять. Т.е. можно складывать только при условии последующего деления, например.
Самое простое — это сделать такие операции:
[цельсий] — [цельсий] = [кельвин]
[кельвин] + [цельсий] = [цельсий]
ну и для кельвина всякие сложения друг с другом и умножения на число.
И (хоть я настолько и не люблю доведение до такого) поэтому в VHDL надо вообще всё полностью описывать, включая преобразования.
Фаренгейты и Цельсии изоморфны, можно перевести одно в другое и сложить.
В том-то и дело, что они нифига не изомрфны. Сколько будет 1°C + 1°F? А фиг его знает: может быть 159°C, может быть -3049°C. И без дополнительной информации вы это не узнаете.

Да, тут есть неоднозначность, каким должен быть тип результата, но это вполне может зависеть от вызывающего кода, и какой тип он там ожидает.
Если бы речь шла только о типе результата — беды бы не было. К сожалению меняется ещё и значение этого самого результата.
UFO landed and left these words here
1°F может быть как температурой (то есть, соответственно, -314/9°C), так и разницей температур (тогда это всего навсего 5/9°C). Точно также 1°C может быть как температурой (тогда это 33.8°F), а может быть и разницей температур (тогда это 1.8°F).

Результаты, как несложно заметить, будут сильно разными.

Потому — только перевод в Кельвины (ну или, если очень приспичит, в Ранкины), потом что-то там можно считать…
std::chrono::duration и std::chrono::time_point решение проблемы для времени.
UFO landed and left these words here
Просто группа градусов как дельт действует (ну как в алгебре) на множестве градусов как температур с привязкой к абсолютному нулю или ещё чему-нибудь.
Не совсем так. В отличие от времени для температуры ноль имеет чёткий физический смысл: это средняя квадратичная скорость поступательного движения молекул (вернее пересчитывается в неё через постоянную Больцмана. Потому для неё не нужны все эти сложности.

Но это только в Келвинах или Ранкиных.

Если же вы хотите что-то считать в Цельсиях или Фаренгейтах… то да, можно развести весь этот дуализм… но обычно не нужно. Ибо всё равно запутаетесь.
UFO landed and left these words here

Вы как-будто в школе физику не учили. Первым делом в любой задаче было привести все параметры к СИ. С другой стороны это очень странная система, если вам приходится складывать такого рода значения. Но в целом проблема N+1 операторов существует. В соседней ветке предложили использовать Boost.Units для таких штук, но если я правильно понял доку, то там собственно все для единиц измерения СИ и его альтренатив вроде СГС. Если нужны будут свои собственные еноты на парсек в час, то кучу бойлерплейта писать все равно придется.

Все верно, в этом и есть задача. Она ничем не отличается от задачи метры +милиметры.
Складывать градусы с градусами можно. А вот метры с градусами нельзя.

В С++ можно так. Код не скомпилился.
int meters = 1;
std::chrono::seconds seconds{1};
auto val = meters + seconds;


А библиотеку обернуть:
int flib_mul2(int i){
    return i * 2;
} 

std::chrono::seconds mul2(std::chrono::seconds i){
    return std::chrono::seconds{flib_mul2(i.count())};
} 

int main()
{
    std::chrono::seconds seconds{1};
    auto seconds2 = mul2(seconds);
}

ну для времени это частный случай. я про отсутствие средств в целом, чтобы можно было легко отличать один intы/doubleы от других. Секунды, килограммы, 1/дж^2. И чтобы иметь возможность запихать их в формулу и получить КГ/АМ если надо, но с проверкой, что именно КГ/АМ получаются

Haskell же!


{-# LANGUAGE GeneralizedNewtypeDeriving #-}

newtype Seconds = Seconds { getSeconds :: Int }
    deriving Num

Rust же!


use derive_more::Add;

#[derive(Add)]
struct Seconds(u32);
в этой ветке комментариев я сразу сказал, что жаль, что в мейнстриме такого нет :)
UFO landed and left these words here

Да это вроде и на Haskell не очень выглядит.

boost::units как раз похожее и делает (API немного мутноват правда), наверное следующим шагом наверное было бы eigen::vector<boost::length, boost::pressure, boost::force>

Например squants:


scala> val energyUsed = 100.kilowatts * (3.hours + 45.minutes)
energyUsed: squants.energy.Energy = 375000.0 Wh

scala> val energyUsed = 100.kilowatts + 3.hours
                                          ^
       error: type mismatch;
        found   : squants.time.Time
        required: squants.energy.Power

В F# есть такая встроенная фича, называется units of measure. Очень удобная, в моём физическом коде пару ошибок помогла поймать.


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


(забавный факт: автор обсуждаемой статьи как раз тоже топит за F#)

В F# есть такая встроенная фича

Там степени только целые, а хотелось бы рациональные иметь.

Вроде в какой-то версии это допилили. У меня работает, например, такое:


[<Measure>] type cm
[<Measure>] type xx = cm ^ (1/3)

let a = 10<cm>
let b = 10<xx>

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

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

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

В гауссовой системе единиц (фактический стандарт в теоретической физике), а равно в СГСЭ и СГСМ такие размерности.

В обработке сигналов часто используется сректральныя протность в удиницах вроде V/sqrt(Hz)

Я бы сказал что это уже от моделей зависит. Иногда как раз и интересно что за зверь в итоге всплывёт.
Этот момент — проверка единиц измерения — весьма слабо связан именно со статичностью типизации. В статически типизированных языках проверка на соответствие условно string или int производится при компиляции, в динамически типизированных — во время выполнения. Точно так же (на том же этапе) делается и проверка единиц измерения — то есть, это реализуется и в статических, и в динамических языках соответствующими библиотеками.
UFO landed and left these words here
Так вы сами подтверждаете, что проверка единиц измерения не зависит от «статичности» типов в языке. Просто единицы проверяются тогда же, когда и стандартные типы — в условном питоне во время выполнения, в условном с++ во время компиляции. Но сама проверка единиц измерения полезна и в питоне тоже.
UFO landed and left these words here
благодаря динамической типизации очень понятен numpy(сарказм)
Говнище, братан, это ваши ооп и типы. ну вот зачем лезть в чистый мир JS со всем этим барахлом?

От всех эти еретических ограничений чист: статика, строгость. Что хочешь, то и воротишь. Почти ассемблер. :)

Своей непорочностью от всякого говнища, братан.

Динамическая типизация — адское говнище

Погодите это про отсутствие типов а ля питон или разрешения типов компилятором в F# перед компиляцией?

Кто сказал что в питоне типов нет? Там их объявлять не нужно.


type(1.5)
<type 'float'>
type(5)
<type 'int'>
type('hello')
<type 'str'>


Ох уж эти три треугольные скобки >>>

UFO landed and left these words here
Супер! Я по заголовку сразу же угадал автора, стиль однако!
Хм… И почему тогда все (многие?) языки со строгой типизацией все больше скатываются к добавлению «динамических» типов, типа std::any в С++???

Может все-же в некоторых ситуациях оно таки надо, м?

Да и те-же темплейты в C++ это шаг в сторону динамических типов…
А может имеет смысл понимать разницу между «строгий/нестрогий» и «динамический/статический», м?
Я не утверждаю что он чисто динамический, но это определенно шаг в ту сторону.

Он шаг в сторону строгой типизации как раз


template <typename T>
class Summ
{   
    T x; 
 public:
    Summ(T value): x(value) {};
    Summ(): x(0) {};
    Summ operator+(Summ const& rhs) const
    {
        Summ result ;
        result.x +=  rhs.x ;
        return result ;
    }
};

  Summ<int> sum0(0);
  Summ<float> sum1(2.0f);
  sum0 = sum0 + sum1 ; //Такое не проканает

  int sum00(0);
  float sum01(2.0f);
  sum00 = sum00 + sum01 ;  //а такое проканает
sum00 = sum00 + sum01 ;  //а такое проканает

Предупреждение C4244: преобразование «float» в «int», возможна потеря данных
Warnings as errors и такое не проканает.

Это какой то специальный ворнинг, скорее всего с ключём диагностики, потому что GCC и Clang без ключей никаких ворнинга не дают. Это же не запрещено стандартом. Просто неявно тип катится к другому.
А так конечно со статическим анализатором можно все узкие места находить на этапе компиляции.

Это обычный ворнинг MSVC.
Для GCC есть -Wconversion
Естественно, что он не включён по умолчанию, так как обычно это ненужно.

Опции компилятора для того и есть, чтобы настроить под конкретные нужды. Компилировать без настроенных флагов, значит полагаться на дефолтные значения. Далеко не факт, что это те настройки, что требуются.
UFO landed and left these words here
А каким образом темплейты — шаг в сторону динамики, непонятно.

Ну как-же. Вы ведь можете подставить в темплейт любой тип, или переменную, т.е. строгого типизирования нет. Понятно что с точки зрения компилятора все будет все равно типизировано строго, но с точки зрения программиста чем не «динамический» тип?
Собственно концепты и ввели чтобы изобразить что-то вроде типизирования для темплейтов.
UFO landed and left these words here
std::any a = std::string(«fas»);
std::any b = a;
std::any c = a + b;
Не съел компилятор, и вряд ли когда-то съест. any всё таки контейнер для хранения неизвестно чего, а не динамический тип.
any почти наверное означает, что где-то сделана ошибка

Либо что оно прилетело оттуда, где у вас нет власти

В играх ECS без std::any довольно сложно представить, особенно когда это дело еще из сети откуда-нибудь качается.

UFO landed and left these words here