Comments 1975
А вы посмотрите на остальные статьи этого эпатажного автора. Вы думаете, он опомнится на 27-ой разжигающей статье?)
Афигенно! Автор, жги! * обновляет страницу, дабы насладится холиваром *
Динамическую типизацию зачем то придумал и мало того она жива до сих пор, обычно то что никому не нужно умирает на задворках истории.
Но удивительное дело в динамических появляются типы, а в типизированных val.
Такие дела.
Истина где-то рядом, наверно по середине.
И наверно не всех надо по одну гребенку.
Удивительный у автора талант писать статьи, которые вызывают эмоции от полного принятия до лютой неприязни.
val это не динамическая типизация, а лишь вывод типов. Вот почему то многие не понимают принципиальной разницы
Динамическую типизацию зачем то придумал и мало того она жива до сих пор, обычно то что никому не нужно умирает на задворках истории.
Как говорил один мой знакомый:
Так ведь значит же. Динамика это просто атавизм из 90-х, когда языки с нормальными системами типов делать не умели, а писать на вербозном говне не хотелось.
А ЯП с нормальными системами типов начали появляться относительно недавно.
Ни в коем случае не троллинг, действительно интересно.
Haskell (хотя 0xd34df00d щас опять будет ворчать, что выразительности не хватает), Idris, вроде бы Scala (хотя точно сказать не могу), с некоторой натяжкой — Rust.
- Динамика это просто атавизм из 90-х, когда языки с нормальными системами типов делать не умели
- Haskell, 1990 год.
- Python, 1991 год.
Как эти три вещи могут одновременно укладываться в голове? Видимо ваш знакомый не знает одной из них.
Не получится убедить, что Haskell — это подходящий язык для разработки, а Python — не подходящий.
Лучшее, что может быть — это типизация по требованию. Когда нужно, беру и использую. Когда не нужно — избегаю кучи бойлерплейта.
Все таки Haskell это полигон для экспериментов, который тем не менее дорос до прода, а активно вывод типов начал проникать в индустрию только в 10ых годах.
Ну так хаскель 90-го года и хаскель совеременный — это очень разные языки.
Лучшее, что может быть — это типизация по требованию. Когда нужно, беру и использую. Когда не нужно — избегаю кучи бойлерплейта.
Если бы она ещё работала… Потому что когда тебе нужно, а в апстриме не нужно — вылезай, приехали.
Swift
Не очень из-за дурацкого деления типов на структуры и классы.
Структуры и классы никак не делят типы и не мешают. Это лишь определяет reference type/value type и системе типов до этого нет никакого дела.
Есть дело мне при написании программ, потому что мне надо думать, где будет глубокое копирование, а где — поверхностное, где меняется аргумент, а где — его копия. И в дженериках подобное разделение обычно аукается.
Ну скорее всего придётся об этом думать, язык все-таки позиционируется как более менее быстрый и нежручий.
За мутабельные структуры компилятор всегда подскажет. Если один раз понять как работают reference type/value type в свифте и использовать их где нужно и как нужно, то никаких проблем не будет возникать, а компилятор в случае чего все-равно заботливо предостережет. Все четко и явно в этом плане. И не придется переживать за глубокое/поверхностное копирование.
А что не так с дженериками?
В самом простом варианте все по-умолчанию imutable, потому что компилятор не будет знать что именно туда придет, а для мутабельности можно и inout
или var
в нужном месте указать.
В случаях посложнее (generic constraints) у вас в протоколе все ограничения описываются, вплоть до указания что этот протокол только для классов.
Не знаю с какими проблемами вы сталкивались, но по этому поводу у меня голова ни разу не болела.
К сожалению он существует только в яблочной экосистеме.
К счастью, его можно поставить и использовать практически на все, кроме винды. На малинку вот поставил недавно.
6 лет назад было 50/50, как сейчас — не знаю, но думаю не в пользу винды.
87% windows на 2019 год.
87% это в целом по миру или в сфере разработки? Я видел винду только у тех разработчиков, которым по каким-то причинам было лень ставить линукс. Возможно страх перед неизведанным.
Страх перед паршивыми гуями тогда уж.
На самом деле почти у всех знакомых мне разработчиков в экосистеме .NET и 1С винда — основная ось для этой разработки. Линуксы — только для кроссплатформенных задач.
https://swift.org/blog/5-3-release-process/
Теперь и на винде будет.
Так исторически сложилось, что на свифт перешли все кто писал на ObjC, а он существовал в рамках эппловских операционок, поэтому большинство пишущих на нем — маководы. А так как язык молодой, то пока еще не успел выбиться из нативной разработки под MacOS/iOS (в плане популярности), хоть эппл и делает многое, чтобы он мог быть универсальным. Бекенды эти ваши давно уже можно писать, с ардуинками играться, TensorFlow переходит на него как на основной язык. Дайте малышу время)
хоть эппл и делает многое, чтобы он мог быть универсальным.А что именно он делает? Мне просто интересно. Компилятор предоставил? Так Objective C всегда был под разные платформы (стараниями Столлмана, правда, вопреке желанию Джобса… но был).
Каких-либо попыток сделать разумную среду, которую можно использовать вне экосистемы Apple я не наблюдаю… да неясно какой в ней мог бы быть смысл: Apple же нужно сделать так, всё-таки, чтобы «хомячки» не разбежались с его платформы, а не чтобы кто-то вне её творил…
TensorFlow переходит на него как на основной языкКто сказал? Откуда уверенность, что из этого не получится очередная стелла на известном сайте?
Про 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 вполне неплохая альтернатива в данной ситуации.
Динамическая типизация переносит ряд возможных ошибок на время исполнения программы вместо времени компиляции.
Как по мне оптимальна гибридная типизация, ибо иногда просто хочется расслабиться и что-то наклепать на коленке, не задумываясь о типах, но в серьезных проектах на том же PHP строгая типизация просто необходима по причинам, которые я описал выше. Причем я понял что словами это не объяснить, с этим нужно сталкиваться чтобы оценить все преимущества.
P. S. Это еще ладно, я еще и после этого с MySQL на PostgreSQL перешел (который тоже строготипизирован), теперь он меня обругивает каждый раз если по какой-то причине в строку суется число (а это может быть следствием какой-то очень серьезной проблемы, ибо почему возвращается число там, где должна возвратиться строка, например, array_search не нашел какое-то значение в массиве, хотя должно, что означает что этот массив сформирован неверно). Очень сильно выручало уже, хотя я не так давно пользуюсь всеми ее преимуществами.
писал на PHP, пару лет назад понадобилось прочно влезть в яву (более строго-типизированного языка я в жизни не видел)Это не та ли система типов, которая считает null объектом любого типа?
В РНР эту «особенность» умудрились не повторить, кстати.
Наверное, просто потому что null в PHP появился чуть ли не раньше чем сама Java появилась (шутка, она старше на пару месяцев) и изначально был отдельным скалярным типом, когда объектов ещё даже в проекте не было
заругается если аргумент имеет другой тип данных
Нуда, только его ругание попробуй еще перехвати, приходится статический анализатор гонять
ЗЫ на самом деле Php начинает нервировать, ятоже много лет на нем пишу, и у меня все более отчетливое желание писать на jsp или на чистой Java
TypeError обычное исключение. Обычно его и особо перехватывать не нужно, так же как любое необработанное.
Хороший пример: когда тон чего-то сказанного в начале убивает желание вообще продолжать смотреть на дальнейшие какие-то рассуждения или аргументы, не важно правильные или неправильные.
Приблизительно как начать общение в таком духе: "слыш, ты, послушай что я тебе сейчас скажу об этом говне...",
что там дальше уже не особо важно.
-А холивар то где???
P.S. После фразы «адское говнище» не читал.
В PHP добавляют строгую. А про джс можно подробнее?
Тот, кому первому пришла в голову идея назвать рантаймовый контроль типов «типизацией» — будет вечно гореть в аду за обман джуниоров.
Типизация — не контроль типов?
Не согласен. Типы — информация о том, как интерпретировать то или иное значение. А где она хранится и как и когда проверяется — детали реализации.
Лучше поздно, чем никогда, нет?
Как по мне, то если контроль типов есть, то это типизация.
Ваша программа станет типизированной.
Большинство источников используют "динамическая типизация" без подобных огооврок.
Строго говоря можно даже говорить о том, что все языки с динамической типизацией — суть языки со статической типизацией, в которых есть ровно один тип (и других создать невозможно). Ну или (как в JavaScript) — их несколько, но их фиксированное число и они все описаны в документации.
Однако в виду полной абсурдности такого подхода обычно от языков со строгой типизацией требуется, чтобы свои типы в них, всё-таки, можно было создавать.
Но нет, позднее связывание не делает язык нетипизированным. Даже если в каким-то месте про тип и нельзя ничего сказать (как в Java, когда вы получаете
Object
), но в других-то можно!назвать типизацией наличие проверок на корректный доступ к элементу массива
Тем не менее в Паскале длина массива именно что входила в определение типа.
(ещё до программирования)
Если вы имеете в виду математические типы в стиле введенных Расселом, то он ведь тоже не уточнял, в какое время их надо проверять.
Поэтому ваше утверждение
которое на программирование отображается как статические проверки
достаточно спорно.
Если уж на то пошло, то и статическая, и динамическая проверка типов вообще не относятся к типам, как таковым — типы просто существуют, а является скорее помощью человеку, который не может не делать ошибок и не путать данные разные типов в процессе программирования или выведения логических формул.
Не только конструктивное, но даже конструктивистское. Т.е. вполне пригодное для практического построения системы типов и ее использования.
Типы в ЯП до формализации примерно так и строились.
Должна ли операция «удалить первые N символов» быть в определении строки?
Может быть, но не обязательно. Она не слишком аксиоматическая, что ли.
Если у вас питон с типа строгой динамической типизацией, то, получается, «abcde» и "" — разные типы?
Непонятно, почему вы пришли к такому выводу. Операция эта будет определена как функция отображения строки в строку, т.е. тип объекта не изменится.
Может быть, но не обязательно. Она не слишком аксиоматическая, что ли.
То есть вместо строгого определения имеем: "Вроде как нет, но если надо, почему бы и не да".
И это положительно сказывается на популярности?
некоторые выражения не имеют смысла, не «вычисляя»
Вы все равно вычисляете — ведь это знание не дано свыше, а требует тех же символьных манипуляций. Просто в данном случае есть более короткий способ вычисления — как некоторые интегралы можно посчитать в символьной форме, а не численно. Но в общем случае вычисления все равно придется проводить полностью.
выделить массив ровно такой длины
Насколько я помню исходный виртовский Паскаль — нет. Массивы там были вообще не динамические, а в их тип входили тип элементов, тип индексов и диапазон индексов.
А для передачи массива в процедуру приходилось определять формальный аргумент, прибегая к чему-то вроде any: ARRAY OF INTEGER, например, вместо полного типа ARRAY[1..10] OF INTEGER.
Хотя бывают разные ассемблеры. Почитайте документацию на TASM. У них там объекты были.
Целочисленный add, применённый к float значению, выдаст хурму на выходе.
елочисленный add, применённый к float значению, выдаст хурму на выходе.Недоумённо смотрит на свой код из релизнутого продукта. А вы точно в этом уверены?
А вот эту статью вы когда-нибудь видели?
В моём случае речь шла об округлении мантиссы — это делается как раз использованием целочисленных операций с
float
.Разумеется, какие-то целочисленные операции можно применять к float зная формат и ожидаемый результат.
Я же говорил, что сложив 1+1 вы получите не 2, а 1.7014118346e+38
Точно так же, перепутав знаковое и беззнаковое деление результат может быть неверным.
Я же говорил что сложив 1+1 вы получите не 2А почему вы, собственно, должны получить 2? Вы и без всяких
float
ов можете получить чушь, если в одной переменной у вас 1 и в другой 1, только в одной — это метр, а в другой дюйм.Проверено экспериментально.
Процессор не сделает преобразование типов за вас. К чему вот было это ваше «а можно плавать и со штангой»?
>> А почему вы, собственно, должны получить 2?
Потому что я хочу получить 2, наверное?
Ещё, слышал, бывали процессоры, у которых переменные содержали поле с типом.
У типа есть очень формально определённое значение
Много определений типа в программировании. Некоторые ещё тянут в программировании определения типов из математики.
"У типа есть очень формально определённое значение".
Я знаю про несколько определений типа из нескольких разных теорий типов. Не считая определений из прикладных языков программирования, который возникли раньше тапла и из других предпосылок. Какое же из них верное?
Понятие типа в контексте STLC
1. Система типов из «лямбда-исчисления с типами» не единственная система типов, а только одна из.
2. Системы типов в современных мейнстримных языках (как со статической типизацией, так и с динамической) — это очень далеко не STLC и я подозреваю, что их авторы строили их на несколько других основаниях (и не только формальных).
3. Да, можно натянуть сову на глобус (что и делает тапл) и вывести одно из другого, но это вообще не означает, что определение типа из STCL единственно верное или валидное для языков программирования.
4. То что система типов красиво формализуема еще не означает, что она хорошо подходит для промышленной разработки людьми, которым важно получить результат здесь и сейчас, а не формально верифицировать корректность программы.
А в каких других теориях типов это не статическая классификация?
Ну есть, например, такая «Gradual Type Theory». Правда я с ней недостаточно знаком, чтобы внятно ее обсуждать.
По остальным пунктам — а о чём мы спорим-то?
Я спорю с утверждением, что «типы — это не рантайм-метки рядом с другими ячейками в памяти, а что-то, что проверяется компилятором статически», и утверждаю, что если «статическая типизация = типы проверяются компилятором статически», то так же правомерно говорить «типы проверяются рантаймом динамически = динамическая типизация».
automath какой-нибудь возник сильно до любого из ныне существующих языков программирования.
Я думал, что тут разговор о языках программирования, а не доказателях теорем.
А как называются рантайм метки более коротко? И какое название у описания того, что можно делать с некоторой штукой вне зависимости от того, рантайм это или дизайн тайм?
Мне кажется, такой подход к терминологии менее ортогонален.
Ну так и называются, метки.
А кем они так называются? Есть ли какая-то реализация которая называет их не типом?
Например, в вашей любимой IDE при отладке тип переменной и тип значения переменной называются по разному? Один тип, другой метка?
Ээ, не знаю, это какой-то слишком общий термин для меня.
Ну вы в обычной речи слово тип не употребляете?
С моей точки зрения в книжке терминология интересна но неудобна, все говорят "тип" для общего, никто не использует выражения "рантайм метка" а статика тесно связана с динамикой.
С моей точки зрения в книжке терминология интересна но неудобна, все говорят «тип» для общего, никто не использует выражения «рантайм метка»
А зря. На мой взгляд, создаёт неправильные ожидания.
Зря или не зря — это уже больше философский вопрос. Факт в том, что «динамическая типизация» по отношению к языкам программирования используется именно в таком смысле, и причины, по которым так сложилось, здесь не важны.
лишний раз указать на принципиальное различие между типизацией и рантайм-проверками
То, что вы называете типизацией, — всего лишь проверки до рантайма.
Это лишь ваше убеждение :)
От задач зависит. Популярность языка, стэка обеспечивает масштабируемость разработки для бизнеса и наличие рабочих мест для программистов.
Извините, но вы соответствие Карри-Говарда проигнорировали. Избирательное зрение?
Надеюсь теперь всем ясно, что это — тролль?
Они, впрочем, обычно обладают крайне развитым навыком «переноса ворот» (как вы это уже тут видите), потому важно им всячески помогать, но ни в коем случае не брать на себя никаких обязательсв, если они не скрплены «подписями и печатями».
Даже если вам за выполнение чего-то сказанного мимоходом и нигде не зафиксированного обещают кучу плюшек и всяких благ. Лучше прослыть «ничего не понимающим в бизнесе», чем оказаться крайним, когда очередной такой персонаж будет на вас пытаться повесить свои косяки.
А если мне сказали закодить биржевого бота, который будет торговать на какой-нибудь азиатской бирже только в рабочие дни, то, например, если я неправильно скопирую список праздников (или нагуглю список не для той страны), то типы едва ли это помогут отловить, конечно. Но как это отлавливать — вообще непонятно.
Хуже. Список рабочих дней может как в России определяться в предыдущем году по решению Правительства. Или как с "нерабочими" днями. По ходу дела.
Вообще удивительно, что только 0xd34df00d реально вернулся к истокам. Все это программирование — это не код ради кода, а код обработки данных. А все данные типизируются. А код — это просто функции превращения одного в другое.
у него большая проблема: многое из того что он говорит базируется не на научном подходе, а на религиозных предпочтениях/взглядахНу хоть с тем, что ЯП со статической типизацией убирают множество проблем с ошибками типов вы согласны?
однако надо помнить (и это исследовал ещё Ларри Уолл), что большинство проблем с ошибками типов связаны с тем, что в языках некорректно сдизайнены операторы сравнения и математические операции.А ещё нужно помнить, что когда эта «глыба», эта «гора», этот «гений» решил создаить что-то на основе своих идей… то получился высер такого микроскопического размера, что о нём даже как о мыши-то говорить смешно.
и чем крута динамическая типизация: что программист больше думает об алгоритме, нежели занимается обрядами вокруг его реализацииСерьёзно? И потому как только вам требуются реально серьёзные алгоритмы (распределённые базы данных или хотя бы SQL-базы, компиляторы, операционные системы и всё такое прочее) — так прям все на динимических языках начинают программировать? Вы это сейчас серьёзно?
Знаете — весь этот ваш пафос был бы слегка более уместен если бы подверждался опытом. И вы могли назвать хотя бы одну систему, где динамически типизированный язык — это не «пенка» на базисе из модулей на статически типизированных языках, а что-то, что сущесвует само по себе. Хотя бы.
Уж не говоря о том, что если бы динамически типизированные языки были бы так круты, как вы описываете, то именно они должны были бы формировать базис, а на статически типизированных языках люди бы писали что-то, ошибки в чём были бы не так опасны.
и это путь решения тех же проблем но на дороге динамической типизацииЭто махание руками. Давайте ближе к практике:
1. Реализация динамически типизиванного языка на динамически типизованном языке же: ___
2. Операционная система на этом самом динамически типизованном языке: ___
3. База данных на таком же языке: ___
4. Процент рынка, который вот всё это заняло в ___ году: ___
Вот как заполните пропуски — так сможете лить в уши сказки про преимущество динамической типизации в деле реализации алгоритмов. А до тех пор — это всё рассказы условного «таджика» умеющего неплохо строть туалеты и двухтажные домишки дендрофекальным метордом о том, что у оного метода есть масса преимуществ перед сталью и бетоном, а что какие-то идиоты из говна и палок даже не пытаются строить мосты и небоскрёбы — так это потому что у архитекторов и инжинеров-строителей умишко слабенький и нет того опыта строительства туалетов, что «таджика»…
назовите три полезных программы на Расте/Хацкеле стоящие на большинстве компьютеровНазовите хоть одну такую на Raku для начала. Или вам можно выбирать языки, а мне нельзя? Вы же сами тут поёте песни про крутизну Ларри — ну вот покажите… на практике.
динамически типизированные языки — это скриптовые языки, прежде всего.Внезапно как, а. А почему так, не расскажите? Почему языки, в которых «программист больше думает об алгоритме, нежели занимается обрядами вокруг его реализации» не применяются там, где алгоритмы сложны и о них действительно приходится думать — но всё больше там, где алгоритмы тривиальны и думать о них не нужно?
затем попробуйте удалить Perl и Bash. и посмотрите на результатИ много вы алгоримов на Bash написали? Я как-то писал топологическую сортировку банальную — то ещё равлечение было. В Android, кстатати, нет ни Perl, ни Bash. И ничего — работает как-то.
А вот попробуйте оттуда удалить модули, написанные на C…
Вы хотите сказать что языки со строгой/статической типизацией все находятся в стадии «бета» (== «ещё не доделан»)?Я хочу сказать, что с идиотами, записывающими в языки с динамической типизацией C и Java разговаривать бессмысленно. Хотя вас я идиотом не считал, но… теперь вижу._
Статически типизированный язык, между прочим
Да, предствьте себе — даже такая слабая типизация, как в C, и даже при такой ужасной культуре кода, как в openSSL (поговорите с теми, кто внутрь смотрел) всё равно снижает количество уязвимостей. В каком-нибудь NGINX — их меньше на порядок. В Chrome — да, побольше будет… но вы когда-нибудь сраванивали по объёму Drupal и Chrome? Сравните как-нибудь на досуге.
поэтому языки вроде C, C++, Java (и прочие языки традиционно ориентированные) — это языки, которые я противопоставляю высказываниям сектантов.У… как всё запущено. Что такое вообще «традиционно ориентированный язык»?
именно строгую типизацию сектанты вроде 0xd34df00d противопоставляют тестам.Серьёзно? У вас всё с логикой настолько плохо?
Извините, но я нигде и никогда не слышал, чтобы 0xd34df00d говорил о том, что типами нужно заменять тесты. Он всегда говорит о том, что можно — и да в Idris это попроще, а в C++… ну на спор, наверное, тоже можно, но в реальной программе — не получится.
Вопрос того, что нужно выражать ограничениями на типах, а что лучше оставить в виде тестов — он совершенно отдельный от вопросов принципиальной реализуемости того или иного подхода.
Давайте теперь Вы назовите пару монополистов, имеющих аудиторию в миллиард людей, чтобы их основной язык был со строгой/статической типизациейВы издеваетесь или как? Ну пусть будет Google и Microsoft, если уж так хотите. Только не рассказывайте сказок про то, что Microsoft меньшая монополия, чем какой-нибудь Facebook: в китае без Facebook отлично живут, а без Window — таки не обходятся. Ну или Apple возьмите — да, это не монополия… но денег она зарабатывают больше, чем Facebook и Mail.Ru вместе взятые.
то FaceBook — это PHP.Нет. PHP такую махину не потянет. Facebook — это Hack. И да — он статически типизирован.
(распределённые базы данных или хотя бы SQL-базы, компиляторы, операционные системы и всё такое прочее) — так прям все на динимических языках начинают программировать?
Однако же поверх всех этих замечательных программ тут же возникают динамические языки — шеллы или тот же SQL. SQL сильно типизирован?
Совпадение? Не думаю.
Так никто вроде бы и не спорит, что в качестве glue code для одноразовых задач динамические языки вполне себе работают.
Совпадение? Не думаю.Нет, конечно. Как только вы решаете, что вам не нужен качественный код, но нужны дешёвые программисты — так динамические языки становятся, вдруг, резко осмысленными.
Программисты на PHP получают меньше, чем программисты на C++, а администраторы («программисты на bash») — ещё меньше.
В некоторых случаях возможна и обратная ситуация (финансовый аналитик, пишущий только программы на каком-то простеньком язычке, но никак не на C++ — может получать и больше программиста на C++), но в этом случае они получают столько не за то, что умеют лихо писать программы на Python, а за что-то совсем другое.
Где-то тут уже приводил: в Киеве разница между PHP и Javaсеньорами порядка 5% всего. Это во столько бизнес оценивает надежность статической типизации (забудем про то, что часто Java и быстрее)?
к чему тогда пассажи про "нужны дешёвые программисты — так динамические языки становятся, вдруг, резко осмысленными. Программисты на PHP получают меньше, чем программисты на C++"
У меня есть цифры, что эти "дешевые" лишь на 5% дешевле, а разница в качестве, вроде как, качественная, если верить адептам статики.
У меня есть цифры, что эти «дешевые» лишь на 5% дешевлеНет у вас таких цифр, извините. У вас есть информация про кое-что другое.
Разница между дешёвыми и дорогими программистами лишь слегка кореллирует с зарплатой.
Более того — в некоторых случаях программист, получающий более высокую зарплату может оказаться дешевле.
Подумайте над этим.
а разница в качестве, вроде как, качественная, если верить адептам статики.Разница качественная — но не между динамикой и статикой.
А между продукцией «дешёвых» и «дорогих» программистов.
Я это уже показывал на примере CVE.
И да, разница между зарплатами — гораздо меньше, тут вы, что забавно, тоже правы.
> В языке «ться» и «тся» не различаются, они различаются лишь на письме, которое представляет собой условность. Потому, собственно, их и путают на письме.
В языке у них разная роль, что можно увидеть, например, по тому, что для некоторых глаголов вместо "-ться" получается "-тись": нестись, пастись…
(это как раз о типизации;))
В фонетике, да, они сливаются — но уже после этого.
И если мы обсуждаем преимущества разных видов типизации, то, ИМХО, лишний раз указать на принципиальное различие между типизацией и рантайм-проверками, которое по-хорошему должно быть определено даже в терминологии, вполне себе стоит.
Так никто не против указывать на различия статической и динамической типизации. Более того, никто вроде не отрицает, что с некоторой точки зрения правильнее эти две альтернативы называть по-другому. Но для того, чтобы как можно больше людей, связанных с программированием, вас сразу без дополнительных пояснений правильно понимало, нужно использовать именно «статическая типизация» и «динамической типизация» — это устоявиеся названия классов языков. Можно для себя их называть как угодно, но все (?) официальные документы по динамически типизированным языкам программирования используют слова «тип» и «динамическая типизация»/«динамическая проверка типов» — например python, js. То же верно и для обсуждений этих языков на практике. Поэтому смена терминологии привнесёт только путаницу на этом этапе.
В моей IDE для хаскеля вообще нет рантайм-меток (да, я за всю практику пользовался Typeable в своём коде ровно один раз). Да и дебаггером я там не пользуюсь.
Если вы им не пользуетесь это не значит что его нет. Я посмотрел — оно умеет как-то определять тип в рантайме.
Кстати, определите до конца термин "рантайм метка" он не отражает метка чего именно.
В моей IDE для плюсов их тоже не особо много для рантайм-поведения.
А что у вас за IDE для плюсов? У вас там нет cимволов и RTTI? в окне watch нет колонки type для переменных? Или там написано что-то типа "рантайм метка относящаяся к набору операций которое можно совершать со значением"?
А зря. На мой взгляд, создаёт неправильные ожидания.
Какие и у кого?
Не обязательно. В том же хаскеле в общем случае после того, как вы проверили типы, вы можете их стереть и не иметь вообще ни намёка на них в рантайме.
Я хаскель знаю очень поверхностно. Мне трудно с этим поспорить.
С моей точки зрения, терминология, которую вы предлагаете требует введения разных слов для одного и того же и необщепринята, т.е. никакой выгоды от нее нет.
прекрасный термин, и никого не обманывает
Скорее не линтерами, а статанализаторами. Да, если использовать все возможности языка на полную, не помогая анализатору тайпхинтами и аннотациями, то много ошибок типов будет как ложно положительных, так и ложно отрицательных, но тем не менее как современные IDE, так и отдельные статанализаторы широко используют информацию о типах из исходников.
Можно писать на Idris и эммитить код на PHP
Тот, кому первому пришла в голову идея назвать рантаймовый контроль типов «типизацией» — будет вечно гореть в аду за обман джуниоров.
А как по вашему это нужно называть?
Типизация в PHP как была динамической и слабой, так и осталась. И нет никаких предпосылок к изменению этого положения.
Контролем типовВроде это по определению делается во всех системах с проверками типов. Ну там Rust, Haskell. На другом этапе, конечно.
Я не понимаю отчаянного сопротивления применению определенного уважаемого термина к РНР и попыток его замены на какой-нибудь другой, не такой уважаемый.
Типизация в PHP как была динамической и слабой, так и осталасьКстати, вы будете гореть в аду
Тот, кому первому пришла в голову идея назвать рантаймовый контроль типов «типизацией» — будет вечно гореть в аду за обман джуниоров.
Если это не typing (типизация), то как сообщить другому человеку «Я придумал ЯП с динамическим blabla» и остаться понятым?
«Можно ли на этой переменной дёрнуть эту функцию?»Но если мы хотим донести, что эта переменная ведёт себя как string ибо помечена таковой средой выполнения, то нам придётся долго перечислять список функций (и всё равно можем не попасть, потому что у другого типа может быть такой же, но он к примеру несовместим со string). Нам же нужны обобщения.
вы придумали язык без статической типизации.Это можно, да. Термин взаимоисключающий.
Проблема в том, что всё это противоречит естественному языку как средству коммуникации. Лучше было бы придумать для формальных понятий другие слова, например «типоид» и «типоизация». Тогда можно было бы смело поправлять других «Вот это ни в коем случае нельзя называть типоидом по определению», «в этом ЯП не может быть никакой типоизации» и никто бы и слова против не сказал.
Я не знаю, как это было с исторической перспективы, но сейчас частичное пересечение узкоспециального термина с широким общим играет отрицательную роль для первого.
Но да, это не про питон.
Можно просто сказать, что вы придумали язык без статической типизации.
Это может быть и безтиповый язык типа популярных ассемблеров.
А джунам тем стоит взять JSP если уж на то пошло)
В "компайл-тайме" в клиентской коде мы не можем знать что загрузит автолоалер или какая имплементации интерфейса придёт. Вообще проверки не будет?
Компайл тайма нет. Проверка будет только при статическом анализе и канеш в рантайме. Поэтому индустрия пыха требует монструозного техпроцесса на нескольких стадиях.
Ну какой-то компайл тайм есть: преобразование в опкоды. В рамках одного класса можно было бы в нём что-то по минимум проверить, но вот весь проект проверить нереально, по крайней мере с доминирующей моделью автолоадинг классов.
С Java или С# о компиляции в байт-код говорить можем, а с PHP не можем?
А 8 с JIT уже есть https://github.com/php/php-src/blob/master/UPGRADING :)
Java на JIT, насчёт C# не могу сказать ничего. А 8 с JIT ещё только в альфе, первый релиз-кандидат вроде как только осенью будет, а сам релиз в декабре.
В пыхе компиляция пока что относится только к сборке самого бинарника руками) А наш с вами код интерпретируется, это сильно другой процесс.
В альфе, но есть :)
Тут о терминах можно спорить долго. javac запускает компиляцию в байт-код, который отдаётся виртуальной машине. Раньше она его просто интерпретировала, сейчас JIT везде или почти везде. php запускает компиляцию в байт-код, который отдаётся вирткальной машине. раньше она его просто интерпретировала, сейчас JIT в мастере. В чём качественная разница? В отсутствии файла с байт-кодом?
Вопрос ведь не в терминах, ну и не спорю, если грубо — то можно свести к фразе компилится.
Для меня лично компиляция — строго вне рантайма. Если код попадает в кучу когда пришли данные на обработку — интерпретация. Отсутствие файлика — огромная разница в процессе.
Ну и ещё у меня стойкое чувство, что вы меня стебете)
/ пошто пыхоиндуса обижаете? :( /
Ну вот JIT тогда не компиляция? Файлика нет же. :)
А если серьёзно, то в современной разработке грань между компиляторами и интерпретаторами размылась — слишком многое под капотом, на что программист никак повлиять не может обычно.
У вас слишком узкое представление.
PS На всякий случай подчеркну, это вопрос, а не утверждение.
Проверка типов происходит точно на рантайме, когда данные переданы в поток (то есть код уже в куче)
Если развернуто:
1. В зависимости от версии пыха и правил типизации (strict_types) проекта на этапе разработки (локально) доступны:
1.1. Анализ самого IDE в режиме реального времени
1.2 Встраиваемые пакеты для статического анализа codestyle
1.3 Встраиваемые пакеты для стат анализа codequality
2. Дальше в крупных проектах CI/CD, со стендами для предварительных тестов регрессии, интеграции, фича тестов и вероятнее всего 1.2 и 1.3 повторные.
3. Дальше, в зависимости от критичности проекта, может быть ряд canary продакшн серверов, на которых крутятся «свои» юзеры, которые выступают в роли кроликов-тестировщиков.
4. Ну и сам прод собственно. Тут вызывается код, интерпретируется в псевдокод для виртуальной машины (например нгинкс), выполняется до определенного адреса, там происходит ошибка и бросается исключение (от нотиса до фатала) — вот последнее это рантайм.
А так, по топику могу сказать одно.
Типизация нисколько не спасает от багов на проде.
Чаще всего прод на пыхе страдает от кривой логики реализации бизнес-процесса или не до конца протестированных юзкейсов.
Орут о величии строгой типизации над динамически типизированными языками в основном фронтендеры, которые пересели с js на ts и решили, что они не верстальщики, а программисты =)
Не так плоха динамическая типизация, как ее сочетание со слабой, js, php привет вам.
Вот это уже взрывная смесь по производству багов.
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. Он ещё парочку странностей от него унаследовал…В моих книжках написано, что not (not x) = x для всех допустимых x, значит, None эквивалентно not (not None).
Ещё раз. У вас не получится сложить None и 1. Оператор not это логический оператор отрицания, который возвращает строго True/False. Двойное инвертирование True вернёт True и наоборот, эта цепочка из not not not [...] может быть бесконечной. Не понимаю, что мы обсуждаем?
Да, это всего лишь ещё один способ указать на unsoundness языка.
Ну, назовите это консистентностью языка. В целом проблемы нет, согласен.
Уже давно это не так.
Да, есть unsound-элементы, но они связаны с изначальными ошибками (или компромиссами) в дизайне системы типов, и о них думают, как бы их устранить.Лучше бы они подумали как «людям снаружи» дать доступ ко всему этому.
Либо объявите GHC «единственной правильной версией» (и тогда версии языка будут соответствовать резлизам GHC), либо сделайте уж, как в C++, регулярные релизы. А то официальной версии 10 лет, а что из бесконечного количества расширений и дополнений, доступных после этого, считать «официальной частью языка» — «снаружи» понять невозможно.
Далеко не у всех есть возможность следить за всей «движухой», если они хотят попробовать Haskell на примере задачи генерации какого-нибудь отчёта.
А с устранением косяков вопрос сложный, на самом деле: в Python считается идеоматичным не писать в
if
всякие "== 0" или "== []" (хотя лично я это считают некрасивым как раз) из чего, как бы, очевидно следует, что и not
должен работать со всеми типами — иначе будет нелогично.Де-факто это уже давно так.А как до этого догадаться? Захожу я на 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-сайте не найти…1 + "hello" => TypeError (String can't be coerced into Integer)
А я говорю, что описание типов — и есть описание процессаЭ? Вообще-то описание _процессов_ — это функции/процедуры.
Код на динамических языках не только пишется легче, но и легче читается. Поэтому многие ошибки видны невооруженным глазом.
Но с определенного размера кодовой базы все связи уследить уже просто не возможно, и вот тут на помощь приходит статическая типизация.
В общем, для каждой задачи — свой инструмент.
Не совсем так. Динамически-типизированный код может вообще не отличаться от статически-типизированного, просто автоматический вывод.
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
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'.
Вот я и говорю, что это не работает, любую строку можно просто привести к типу UserName без доказательства последнегоconst nameOf = (name: string) => name as UserName;
Я могу ошибаться, но вы именно о таком поведении писали в комментарии выше.
А как доказать, что строка, которая пришла с сервера, это действительно UserName, а не что-то иное?Проверить, что она соответствует всем ограничениям на тип UserName, если проверка успешна — я получу тип UserName, иначе получу ошибку. Другого способа получить тип UserName в программе нет, поэтому ему можно доверять. А вот типу, в который можно просто кастануть любую строку я доверять не могу, он для меня бесполезен.
Но я согласен с автором что «в продакшене» всё-таки лучше использовать языки со статической типизацией.
В плюсах же как раз есть пользовательские суффиксы.
Ну и, кроме того, всё уже сделано до нас: Boost.Unit
Писать много много оберток над тривиальными математическими операциями и сравнениями. Фактически копипаст. Нельзя просто сказать что вот этот int будет метры, этот секунды, а этот тугрики. Плюс взаимодействие сложных типов вышеупомянутое.
Там ограничения есть, например, для целого это всегда long long int, а зачем мне это, если я метры хочу только int32.
Другое дело, что можно все в классы обернуть… тогда точно, одно с другим не сложишь. Но это конечно дополнительно писать придется кода...
В C++ как раз сложишь, если оператор + переопределишь :)
И как так просто метры с миллиметрами сложить? Переопределить то можно… придется делать столько этих операторов, сколько типов собираетесь складывать.
Для такого есть std::ratio
Хорошо, Фаренгейты с Цельсиями.
температуру с температурой складывать нельзяВот у меня литр воды 20 градусов и 5 литров 50 градусов, как мне посчитать температуру смеси (пренебрегая теплопередачей посуде и воздуху)? Всегда думал что для этого нужно средневзвешенное значение находить (в кельвинах), а для этого множить на скаляры и складывать.
Фаренгейты и Цельсии изоморфны, можно перевести одно в другое и сложить.В том-то и дело, что они нифига не изомрфны. Сколько будет 1°C + 1°F? А фиг его знает: может быть 15⁄9°C, может быть -304⁄9°C. И без дополнительной информации вы это не узнаете.
Да, тут есть неоднозначность, каким должен быть тип результата, но это вполне может зависеть от вызывающего кода, и какой тип он там ожидает.Если бы речь шла только о типе результата — беды бы не было. К сожалению меняется ещё и значение этого самого результата.
Результаты, как несложно заметить, будут сильно разными.
Потому — только перевод в Кельвины (ну или, если очень приспичит, в Ранкины), потом что-то там можно считать…
Просто группа градусов как дельт действует (ну как в алгебре) на множестве градусов как температур с привязкой к абсолютному нулю или ещё чему-нибудь.Не совсем так. В отличие от времени для температуры ноль имеет чёткий физический смысл: это средняя квадратичная скорость поступательного движения молекул (вернее пересчитывается в неё через постоянную Больцмана. Потому для неё не нужны все эти сложности.
Но это только в Келвинах или Ранкиных.
Если же вы хотите что-то считать в Цельсиях или Фаренгейтах… то да, можно развести весь этот дуализм… но обычно не нужно. Ибо всё равно запутаетесь.
Вы как-будто в школе физику не учили. Первым делом в любой задаче было привести все параметры к СИ. С другой стороны это очень странная система, если вам приходится складывать такого рода значения. Но в целом проблема 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);
}
Haskell же!
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
newtype Seconds = Seconds { getSeconds :: Int }
deriving Num
Rust же!
use derive_more::Add;
#[derive(Add)]
struct Seconds(u32);
В F# есть такая встроенная фича, называется units of measure. Очень удобная, в моём физическом коде пару ошибок помогла поймать.
Во многих других функциональных языках, в которых есть конструкции вида newtype
, это также делается достаточно изящно.
(забавный факт: автор обсуждаемой статьи как раз тоже топит за F#)
В F# есть такая встроенная фича
Там степени только целые, а хотелось бы рациональные иметь.
Вроде в какой-то версии это допилили. У меня работает, например, такое:
[<Measure>] type cm
[<Measure>] type xx = cm ^ (1/3)
let a = 10<cm>
let b = 10<xx>
(извините, хорошего примера я не придумал, и даже помню, как во времена введения этой фичи ломал голову — где она может понадобиться; ни одной физической величины, использующей такие единицы, мне в голову ни тогда, ни сейчас не пришло)
Охотно верю, что фича появилась не случайно. Но где такие единицы используются, не могли бы вы привести пример?
чем же js чист?
Несите нового!
Динамическая типизация — адское говнище
Погодите это про отсутствие типов а ля питон или разрешения типов компилятором в F# перед компиляцией?
Может все-же в некоторых ситуациях оно таки надо, м?
Да и те-же темплейты в 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 без ключей никаких ворнинга не дают. Это же не запрещено стандартом. Просто неявно тип катится к другому.
А так конечно со статическим анализатором можно все узкие места находить на этапе компиляции.
Для GCC есть -Wconversion
Естественно, что он не включён по умолчанию, так как обычно это ненужно.
Опции компилятора для того и есть, чтобы настроить под конкретные нужды. Компилировать без настроенных флагов, значит полагаться на дефолтные значения. Далеко не факт, что это те настройки, что требуются.
А каким образом темплейты — шаг в сторону динамики, непонятно.
Ну как-же. Вы ведь можете подставить в темплейт любой тип, или переменную, т.е. строгого типизирования нет. Понятно что с точки зрения компилятора все будет все равно типизировано строго, но с точки зрения программиста чем не «динамический» тип?
Собственно концепты и ввели чтобы изобразить что-то вроде типизирования для темплейтов.
any почти наверное означает, что где-то сделана ошибка
Либо что оно прилетело оттуда, где у вас нет власти
В играх ECS без std::any довольно сложно представить, особенно когда это дело еще из сети откуда-нибудь качается.
Динамическая типизация — это не инструмент для разработки. Это чепуха (паршивая)